41
41
using modsecurity_test::UnitTest;
42
42
using modsecurity_test::ModSecurityTest;
43
43
using modsecurity_test::ModSecurityTestResults;
44
+ using modsecurity::ModSecurity;
45
+ using modsecurity::Rule;
46
+ using modsecurity::Rules;
47
+ using modsecurity::Transaction;
44
48
using modsecurity::actions::transformations::Transformation;
45
49
using modsecurity::operators::Operator;
46
50
@@ -53,8 +57,20 @@ void print_help() {
53
57
std::cout << std::endl;
54
58
}
55
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
+ }
56
71
57
- void perform_unit_test (ModSecurityTest<UnitTest> *test, UnitTest *t,
72
+ static void perform_unit_test (ModSecurity *modsec,
73
+ ModSecurityTest<UnitTest> *test, UnitTest *t,
58
74
ModSecurityTestResults<UnitTest>* res) {
59
75
std::string error;
60
76
bool found = true ;
@@ -77,11 +93,27 @@ void perform_unit_test(ModSecurityTest<UnitTest> *test, UnitTest *t,
77
93
}
78
94
79
95
if (t->type == " op" ) {
96
+ Rules rules{};
97
+ Transaction transaction{modsec, &rules, NULL };
80
98
Operator *op = Operator::instantiate (t->name , t->param );
99
+ Rule rule{NULL , NULL , NULL , " " , 1 };
100
+
101
+ // Rx operator won't capture groups otherwise
102
+ rule.m_containsCaptureAction = true ;
103
+
81
104
op->init (t->filename , &error);
82
- int ret = op->evaluate (NULL , NULL , t->input , NULL );
105
+ int ret = op->evaluate (&transaction, &rule , t->input , NULL );
83
106
t->obtained = ret;
84
- if (ret != t->ret ) {
107
+
108
+ bool pass = (ret == t->ret );
109
+ if (t->re_groups .size () > 0 ) {
110
+ t->obtained_re_groups = get_capturing_groups (transaction);
111
+ if (t->re_groups != t->obtained_re_groups ) {
112
+ pass = false ;
113
+ }
114
+ }
115
+
116
+ if (!pass) {
85
117
res->push_back (t);
86
118
if (test->m_automake_output ) {
87
119
std::cout << " FAIL " ;
@@ -152,6 +184,8 @@ int main(int argc, char **argv) {
152
184
test.load_tests (" test-cases/secrules-language-tests/transformations" );
153
185
}
154
186
187
+ ModSecurity modsec{};
188
+
155
189
for (std::pair<std::string, std::vector<UnitTest *> *> a : test) {
156
190
std::vector<UnitTest *> *tests = a.second ;
157
191
@@ -162,7 +196,7 @@ int main(int argc, char **argv) {
162
196
if (!test.m_automake_output ) {
163
197
std::cout << " " << a.first << " ...\t " ;
164
198
}
165
- perform_unit_test (&test, t, &r);
199
+ perform_unit_test (&modsec, & test, t, &r);
166
200
167
201
if (!test.m_automake_output ) {
168
202
int skp = 0 ;
0 commit comments