19
19
#include < iostream>
20
20
#include < ctime>
21
21
#include < string>
22
+ #include < cassert>
22
23
23
24
#include " modsecurity/rules_set.h"
24
25
#include " modsecurity/modsecurity.h"
25
26
#include " src/operators/operator.h"
26
27
#include " src/actions/transformations/transformation.h"
28
+ #include " src/actions/capture.h"
27
29
#include " modsecurity/transaction.h"
28
30
#include " modsecurity/actions/action.h"
29
31
40
42
using modsecurity_test::UnitTest;
41
43
using modsecurity_test::ModSecurityTest;
42
44
using modsecurity_test::ModSecurityTestResults;
45
+ using modsecurity::ModSecurity;
46
+ using modsecurity::RuleWithActions;
47
+ using modsecurity::Transaction;
43
48
using modsecurity::actions::transformations::Transformation;
44
49
using modsecurity::operators::Operator;
45
50
@@ -52,8 +57,30 @@ void print_help() {
52
57
std::cout << std::endl;
53
58
}
54
59
60
+ static std::vector<std::string> get_capturing_groups (Transaction &transaction) {
61
+ // capturing groups are stored in the TX collection as "0", "1", and so on
62
+ std::vector<std::string> res;
63
+ for (int i = 0 ;; i++) {
64
+ const std::string key = std::to_string (i);
65
+ auto s = transaction.m_collections .m_tx_collection ->resolveFirst (key);
66
+ if (s == NULL ) break ;
67
+ res.push_back (*s);
68
+ }
69
+ return res;
70
+ }
71
+
72
+ static std::unique_ptr<RuleWithActions> create_fake_capture_rule () {
73
+ auto actions = new modsecurity::Actions;
74
+ actions->push_back (new modsecurity::actions::Capture (" " ));
75
+ auto rule = std::unique_ptr<RuleWithActions>(new RuleWithActions{actions, nullptr , std::unique_ptr<std::string>(new std::string (" " )), 1 });
76
+
77
+ assert (rule->hasCaptureAction ());
55
78
56
- void perform_unit_test (ModSecurityTest<UnitTest> *test, UnitTest *t,
79
+ return rule;
80
+ }
81
+
82
+ static void perform_unit_test (ModSecurity *modsec,
83
+ ModSecurityTest<UnitTest> *test, UnitTest *t,
57
84
ModSecurityTestResults<UnitTest>* res) {
58
85
std::string error;
59
86
bool found = true ;
@@ -76,11 +103,26 @@ void perform_unit_test(ModSecurityTest<UnitTest> *test, UnitTest *t,
76
103
}
77
104
78
105
if (t->type == " op" ) {
106
+ modsecurity::RulesSet rules{};
107
+ Transaction transaction{modsec, &rules, NULL };
79
108
Operator *op = Operator::instantiate (t->name , t->param );
109
+
110
+ // Rx operator won't capture groups otherwise
111
+ auto rule = create_fake_capture_rule ();
112
+
80
113
op->init (t->filename , &error);
81
- int ret = op->evaluate (NULL , NULL , t->input , NULL );
114
+ int ret = op->evaluate (&transaction, rule. get () , t->input , NULL );
82
115
t->obtained = ret;
83
- if (ret != t->ret ) {
116
+
117
+ bool pass = (ret == t->ret );
118
+ if (t->re_groups .size () > 0 ) {
119
+ t->obtained_re_groups = get_capturing_groups (transaction);
120
+ if (t->re_groups != t->obtained_re_groups ) {
121
+ pass = false ;
122
+ }
123
+ }
124
+
125
+ if (!pass) {
84
126
res->push_back (t);
85
127
if (test->m_automake_output ) {
86
128
std::cout << " FAIL " ;
@@ -151,6 +193,8 @@ int main(int argc, char **argv) {
151
193
test.load_tests (" test-cases/secrules-language-tests/transformations" );
152
194
}
153
195
196
+ ModSecurity modsec{};
197
+
154
198
for (std::pair<std::string, std::vector<UnitTest *> *> a : test) {
155
199
std::vector<UnitTest *> *tests = a.second ;
156
200
@@ -161,7 +205,7 @@ int main(int argc, char **argv) {
161
205
if (!test.m_automake_output ) {
162
206
std::cout << " " << a.first << " ...\t " ;
163
207
}
164
- perform_unit_test (&test, t, &r);
208
+ perform_unit_test (&modsec, & test, t, &r);
165
209
166
210
if (!test.m_automake_output ) {
167
211
int skp = 0 ;
0 commit comments