642235098577a7a89bba618b945dc335c7409538
[ossec-hids.git] / src / tests / test_os_regex.c
1 /* Copyright (C) 2014 Trend Micro Inc.
2  * All rights reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include <check.h>
11 #include <stdlib.h>
12
13 #include "../os_regex/os_regex.h"
14 #include "../os_regex/os_regex_internal.h"
15
16 Suite *test_suite(void);
17
18
19 START_TEST(test_success_match1)
20 {
21
22     int i;
23     const char *tests[][3] = {
24         {"abc", "abcd", ""},
25         {"abcd", "abcd", ""},
26         {"a", "a", ""},
27         {"a", "aa", ""},
28         {"^a", "ab", ""},
29         {"test", "testa", ""},
30         {"test", "testest", ""},
31         {"lalaila", "lalalalaila", ""},
32         {"abc|cde", "cde", ""},
33         {"^aa|ee|ii|oo|uu", "dfgdsii", ""},
34         {"Abc", "abc", ""},
35         {"ZBE", "zbe", ""},
36         {"ABC", "ABc", ""},
37         {"^A", "a", ""},
38         {"a|E", "abcdef", ""},
39         {"daniel", "daniel", ""},
40         {"DANIeL", "daNIel", ""},
41         {"^abc ", "abc ", ""},
42         {"ddd|eee|fff|ggg|ggg|hhh|iii", "iii", ""},
43         {"kwo|fe|fw|wfW|edW|dwDF|WdW|dw|d|^la", "la", ""},
44         {"^a", "a", ""},
45         {"^ab$", "ab", ""},
46         {"c$", "c", ""},
47         {"c$", "lalalalac", ""},
48         {"^bin$|^shell$", "bin", ""},
49         {"^bin$|^shell$", "shell", ""},
50         {"^bin$|^shell$|^ftp$", "shell", ""},
51         {"^bin$|^shell$|^ftp$", "ftp", ""},
52         {NULL, NULL, NULL}
53     };
54
55     for (i = 0; tests[i][0] != NULL ; i++) {
56         ck_assert_msg(OS_Match2(tests[i][0], tests[i][1]),
57                       "%s should have OS_Match2 true with %s: Ref: %s",
58                       tests[i][0], tests[i][1], tests[i][1]);
59     }
60 }
61 END_TEST
62
63 START_TEST(test_fail_match1)
64 {
65
66     int i;
67     const char *tests[][3] = {
68         {"abc", "abb", ""},
69         {"^ab", " ab", ""},
70         {"test", "tes", ""},
71         {"abcd", "abc", ""},
72         {"abbb", "abb", ""},
73         {"abbbbbbbb", "abbbbbbb", ""},
74         {"a|b|c| ", "def", ""},
75         {"lala$", "lalalalalal", ""},
76         {"^ab$", "abc", ""},
77         {"zzzz$", "zzzzzzzzzzzz ", ""},
78         {"^bin$|^shell$", "bina", ""},
79         {"^bin$|^shell$", "shella", ""},
80         {"^bin$|^shell$", "ashell", ""},
81         {NULL, NULL, NULL}
82     };
83
84     for (i = 0; tests[i][0] != NULL ; i++) {
85         ck_assert_msg(!OS_Match2(tests[i][0], tests[i][1]),
86                       "%s should have OS_Match2 false with %s: Ref: %s",
87                       tests[i][0], tests[i][1], tests[i][2]);
88     }
89 }
90 END_TEST
91
92 START_TEST(test_success_regex1)
93 {
94
95     int i;
96     /*
97      * Please note that all strings are \ escaped
98      */
99     const char *tests[][3] = {
100         {"abc", "abcd", ""},
101         {"abcd", "abcd", ""},
102         {"a", "a", ""},
103         {"a", "aa", ""},
104         {"^a", "ab", ""},
105         {"test", "testa", ""},
106         {"test", "testest", ""},
107         {"lalaila", "lalalalaila", ""},
108         {"abc|cde", "cde", ""},
109         {"^aa|ee|ii|oo|uu", "dfgdsii", ""},
110         {"Abc", "abc", ""},
111         {"ZBE", "zbe", ""},
112         {"ABC", "ABc", ""},
113         {"^A", "a", ""},
114         {"a|E", "abcdef", ""},
115         {"daniel", "daniel", ""},
116         {"DANIeL", "daNIel", ""},
117         {"^abc ", "abc ", ""},
118         {"ddd|eee|fff|ggg|ggg|hhh|iii", "iii", ""},
119         {"kwo|fe|fw|wfW|edW|dwDF|WdW|dw|d|^la", "la", ""},
120         {"^a", "a", ""},
121         {"^ab$", "ab", ""},
122         {"c$", "c", ""},
123         {"c$", "lalalalac", ""},
124         {"^bin$|^shell$", "bin", ""},
125         {"^bin$|^shell$", "shell", ""},
126         {"^bin$|^shell$|^ftp$", "shell", ""},
127         {"^bin$|^shell$|^ftp$", "ftp", ""},
128         {"\\s+123", "  123", ""},
129         {"\\s*123", "123", ""},
130         {"\\s123", " 123", ""},
131         {"\\w+\\s+\\w+", "a 1", ""},
132         {"\\w+\\d+\\w+\\s+", "ab12fb12fd12 ", ""},
133         {"^\\s*\\w\\s*\\w+", "a   l a  a", ""},
134         {"\\w+\\s+\\w+\\d+\\s$", "a aa11 ", ""},
135         {"^su\\S*: BAD su", "su: BAD SU dcid to root on /dev/ttyp0", ""},
136         {"^su\\s*: BAD su", "su: BAD SU dcid to root on /dev/ttyp0", ""},
137         {"^abc\\sabc", "abc abcd", ""},
138         {"^abc\\s\\s*abc", "abc abcd", ""},
139         {"^\\s+\\sl", "     lala", ""},
140         {"^\\s*\\sl", "     lala", ""},
141         {"^\\s\\s+l", "     lala", ""},
142         {"^\\s+\\s l", "     lala", ""},
143         {"^\\s*\\s lal\\w$", "  lala", ""},
144         {"test123test\\d+$", "test123test123", ""},
145         {"^kernel: \\S+ \\.+ SRC=\\S+ DST=\\S+ \\.+ PROTO=\\w+ SPT=\\d+ DPT=\\d+ ", "kernel: IPTABLE IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:03:93:db:2e:b4:08:00 SRC=10.4.11.40 DST=255.255.255.255 LEN=180 TOS=0x00 PREC=0x00 TTL=64 ID=4753 PROTO=UDP SPT=49320 DPT=2222 LEN=160", ""},
146         {"test (\\w+)la", "test abclala", ""},
147         {"(\\w+) (\\w+)", "wofl wofl", ""},
148         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:469:3] ICMP PING NMAP [Classification: Attempted Information Leak] [Priority: 2]: {ICMP} 10.4.12.26 -> 10.4.10.231", ""},
149         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:408:5] ICMP Echo Reply [Classification: Misc Activity] [Priority: 3]: {ICMP} 10.4.10.231 -> 10.4.12.26", ""},
150         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:162", ""},
151         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37021 -> 10.4.10.231:162", ""},
152         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:669 -> 10.4.3.20:111", ""},
153         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:670 -> 10.4.3.20:111", ""},
154         {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1421:11] SNMP AgentX/tcp request [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:705", ""},
155         {NULL, NULL, NULL}
156     };
157
158     for (i = 0; tests[i][0] != NULL ; i++) {
159         ck_assert_msg(OS_Regex(tests[i][0], tests[i][1]),
160                       "%s should have OS_Regex true with %s: Ref: %s",
161                       tests[i][0], tests[i][1], tests[i][2]);
162     }
163 }
164 END_TEST
165
166 START_TEST(test_fail_regex1)
167 {
168
169     int i;
170     /*
171      * Please note that all strings are \ escaped
172      */
173     const char *tests[][3] = {
174         {"abc", "abb", ""},
175         {"^ab", " ab", ""},
176         {"test", "tes", ""},
177         {"abcd", "abc", ""},
178         {"abbb", "abb", ""},
179         {"abbbbbbbb", "abbbbbbb", ""},
180         {"a|b|c| ", "def", ""},
181         {"lala$", "lalalalalal", ""},
182         {"^ab$", "abc", ""},
183         {"zzzz$", "zzzzzzzzzzzz ", ""},
184         {"^bin$|^shell$", "bina", ""},
185         {"^bin$|^shell$", "shella", ""},
186         {"^bin$|^shell$", "ashell", ""},
187         {"\\w+\\s+\\w+\\d+\\s$", "a aa11  ", ""},
188         {"^\\s+\\s     l", "     lala", ""},
189         {"test123test\\d+", "test123test", ""},
190         {"test123test\\d+$", "test123test", ""},
191         {"(lalala", "lalala", ""},
192         {"test123(\\d)", "test123a", ""},
193         {"\\(test)", "test", ""},
194         {"(\\w+)(\\d+)", "1 1", ""},
195         {NULL, NULL, NULL},
196     };
197
198     for (i = 0; tests[i][0] != NULL ; i++) {
199         ck_assert_msg(!OS_Regex(tests[i][0], tests[i][1]),
200                       "%s should have OS_Regex false with %s: Ref: %s",
201                       tests[i][0], tests[i][1], tests[i][2]);
202     }
203 }
204 END_TEST
205
206 START_TEST(test_success_wordmatch)
207 {
208     int i;
209
210     /*
211      * Please note that all strings are \ escaped
212      */
213     const char *tests[][2] = {
214         { "test", "this is a test" },
215         { "test", "thistestiswithoutspaces" },
216         { "test|not", "test" },
217         { "test|not", "not" },
218         { "^test", "test on start" },
219         {NULL, NULL},
220     };
221
222     for (i = 0; tests[i][0] != NULL ; i++) {
223         ck_assert_msg(OS_WordMatch(tests[i][0], tests[i][1]),
224                       "%s should match positive with %s by OS_WordMatch",
225                       tests[i][0], tests[i][1]);
226     }
227
228 }
229 END_TEST
230
231 START_TEST(test_fail_wordmatch)
232 {
233     int i;
234
235     /*
236      * Please note that all strings are \ escaped
237      */
238     const char *tests[][2] = {
239         { "-test", "this is a test" },
240         { "", "test" },
241         { "test|not", "negative" },
242         { "test", "" },
243         { "^test", "starttest" },
244         {NULL, NULL},
245     };
246
247     for (i = 0; tests[i][0] != NULL ; i++) {
248         ck_assert_msg(!OS_WordMatch(tests[i][0], tests[i][1]),
249                       "%s should not match positive with %s by OS_WordMatch",
250                       tests[i][0], tests[i][1]);
251     }
252
253 }
254 END_TEST
255
256 START_TEST(test_success_strisnum)
257 {
258     int i;
259
260     /*
261      * Please note that all strings are \ escaped
262      */
263     const char *tests[] = {
264         "1",
265         "0123",
266         NULL,
267     };
268
269     for (i = 0; tests[i] != NULL ; i++) {
270         ck_assert_msg(OS_StrIsNum(tests[i]),
271                       "%s should match positive by OS_StrIsNum",
272                       tests[i]);
273     }
274
275 }
276 END_TEST
277
278 START_TEST(test_fail_strisnum)
279 {
280     int i;
281
282     /*
283      * Please note that all strings are \ escaped
284      */
285     const char *tests[] = {
286         "test",
287         "1234e",
288         "-1",
289         "+1",
290         NULL,
291     };
292
293     for (i = 0; tests[i] != NULL ; i++) {
294         ck_assert_msg(!OS_StrIsNum(tests[i]),
295                       "%s should not match positive by OS_StrIsNum",
296                       tests[i]);
297     }
298
299 }
300 END_TEST
301
302 START_TEST(test_strhowclosedmatch)
303 {
304     int i;
305
306     /*
307      * Please note that all strings are \ escaped
308      */
309     const char *tests[][3] = {
310         { "test", "test1234", "4" },
311         { "test1234", "test", "4" },
312         { "test", "test", "4" },
313         { "test", "", "0" },
314         { "", "test", "0" },
315         {NULL, NULL, NULL},
316     };
317
318     for (i = 0; tests[i][0] != NULL ; i++) {
319         ck_assert_uint_eq(OS_StrHowClosedMatch(tests[i][0], tests[i][1])
320                           , (unsigned) atoi(tests[i][2]));
321     }
322
323 }
324 END_TEST
325
326 START_TEST(test_strbreak)
327 {
328     int i;
329
330     /*
331      * Please note that all strings are \ escaped
332      */
333     const char *tests[][15] = {
334         { "X", "testX1234", "4", "test", "1234", NULL},
335         { "X", "XtestX1234X", "4", "", "test", "1234", "", NULL},
336         { "Y", "testX1234", "4", "testX1234", NULL},
337         { "X", "testXX1234", "4", "test", "", "1234", NULL},
338         { "X", "testX1234", "1", "testX1234", NULL},
339         { "X", "testX1234X5678", "2", "test", "1234X5678", NULL},
340         { "X", "testX1234", "0", NULL},
341         {NULL},
342     };
343
344     for (i = 0; tests[i][0] != NULL; i++) {
345         char **result = OS_StrBreak(tests[i][0][0], tests[i][1], (unsigned) atoi(tests[i][2]));
346
347         int j = 3;
348         if (tests[i][j] == NULL) {
349             ck_assert_ptr_eq(result, NULL);
350             continue;
351         }
352
353         int k;
354         for (k = 0; tests[i][j] != NULL; j++, k++) {
355             ck_assert_ptr_ne(result[k], NULL);
356             ck_assert_str_eq(result[k], tests[i][j]);
357         }
358         ck_assert_ptr_eq(result[k], NULL);
359
360         k = 0;
361         while (result[k]) {
362             free(result[k++]);
363         }
364         free(result);
365     }
366
367 }
368 END_TEST
369
370 START_TEST(test_regexextraction)
371 {
372
373     int i;
374     /*
375      * Please note that all strings are \ escaped
376      */
377     const char *tests[][15] = {
378         { "123(\\w+\\s+)abc", "123sdf    abc", "sdf    ", NULL},
379         { "123(\\w+\\s+)abc", "abc123sdf    abc", "sdf    ", NULL},
380         { "123 (\\d+.\\d.\\d.\\d\\d*\\d*)", "123 45.6.5.567", "45.6.5.567", NULL},
381         { "from (\\S*\\d+.\\d+.\\d+.\\d\\d*\\d*)", "sshd[21576]: Illegal user web14 from ::ffff:212.227.60.55", "::ffff:212.227.60.55", NULL},
382         { "^sshd[\\d+]: Accepted \\S+ for (\\S+) from (\\S+) port ", "sshd[21405]: Accepted password for root from 192.1.1.1 port 6023", "root", "192.1.1.1", NULL},
383         { ": \\((\\S+)@(\\S+)\\) [", "pure-ftpd: (?@enigma.lab.ossec.net) [INFO] New connection from enigma.lab.ossec.net", "?", "enigma.lab.ossec.net", NULL},
384         {NULL, NULL, NULL}
385     };
386
387     for (i = 0; tests[i][0] != NULL; i++) {
388         OSRegex reg;
389         ck_assert_int_eq(OSRegex_Compile(tests[i][0], &reg, OS_RETURN_SUBSTRING), 1);
390         ck_assert_ptr_ne((void *)OSRegex_Execute(tests[i][1], &reg), NULL);
391
392
393
394         char **result = reg.sub_strings;
395
396         int j;
397         int k;
398         for (j = 2, k = 0; tests[i][j] != NULL; j++, k++) {
399             ck_assert_ptr_ne(result[k], NULL);
400             ck_assert_str_eq(result[k], tests[i][j]);
401         }
402         ck_assert_ptr_eq(result[k], NULL);
403
404         OSRegex_FreePattern(&reg);
405     }
406 }
407 END_TEST
408
409 START_TEST(test_hostnamemap)
410 {
411     unsigned char test = 0;
412
413     while (1) {
414         if ((test >= 48 && test <= 57) // 0-9
415                 || (test >= 65 && test <= 90) // A-Z
416                 || (test >= 97 && test <= 122) // a-z
417                 || test == '(' || test == ')' || test == '-'
418                 || test == '.' || test == '@' || test == '/'
419                 || test == '_') {
420             ck_assert_msg(isValidChar(test) == 1, "char %d should be a valid hostname char", test);
421         } else {
422             ck_assert_msg(isValidChar(test) != 1, "char %d should not be a valid hostname char", test);
423         }
424
425
426
427         if (test == 255) {
428             break;
429         }
430         test++;
431     }
432
433 }
434 END_TEST
435
436 START_TEST(test_caseinsensitivecharmap)
437 {
438     unsigned char test = 0;
439
440     while (1) {
441         if (test >= 65 && test <= 90) { // A-Z
442             ck_assert_msg(charmap[test] == test + 32, "char %d should resolve to lowercase version %d and not to %d", test, test + 32, charmap[test]);
443         } else {
444             ck_assert_msg(charmap[test] == test, "char %d should resolve to itself and not to %d", test, charmap[test]);
445         }
446
447
448
449         if (test == 255) {
450             break;
451         }
452         test++;
453     }
454
455 }
456 END_TEST
457
458 START_TEST(test_regexmap_digit)
459 {
460     unsigned char test = 0;
461
462     while (1) {
463         if (test >= '0' && test <= '9') {
464             ck_assert_msg(regexmap[1][test] == 1, "char %d should match", test);
465         } else {
466             ck_assert_msg(regexmap[1][test] != 1, "char %d should not match", test);
467         }
468
469
470         if (test == 255) {
471             break;
472         }
473         test++;
474     }
475
476 }
477 END_TEST
478
479 START_TEST(test_regexmap_word)
480 {
481     unsigned char test = 0;
482
483     while (1) {
484         if ((test >= 'a' && test <= 'z')
485                 || (test >= 'A' && test <= 'Z')
486                 || (test >= '0' && test <= '9')
487                 || test == '-' || test == '@'
488                 || test == '_') {
489             ck_assert_msg(regexmap[2][test] == 1, "char %d should match", test);
490         } else {
491             ck_assert_msg(regexmap[2][test] != 1, "char %d should not match", test);
492         }
493
494
495         if (test == 255) {
496             break;
497         }
498         test++;
499     }
500
501 }
502 END_TEST
503
504 START_TEST(test_regexmap_space)
505 {
506     unsigned char test = 0;
507
508     while (1) {
509         if (test == ' ') {
510             ck_assert_msg(regexmap[3][test] == 1, "char %d should match", test);
511         } else {
512             ck_assert_msg(regexmap[3][test] != 1, "char %d should not match", test);
513         }
514
515
516         if (test == 255) {
517             break;
518         }
519         test++;
520     }
521
522 }
523 END_TEST
524
525 START_TEST(test_regexmap_punctuation)
526 {
527     unsigned char test = 0;
528
529     while (1) {
530         if (test == '<' || test == '>' || test == '!' || test == '?'
531                 || test == '"' || test == '\'' || test == '#'
532                 || test == '$' || test == '%' || test == '&'
533                 || test == '(' || test == ')' || test == '+'
534                 || test == '*' || test == ',' || test == '-'
535                 || test == '-' || test == ':' || test == '|'
536                 || test == '.' || test == ';' || test == '='
537                 || test == '[' || test == ']' || test == '{'
538                 || test == '}') {
539             ck_assert_msg(regexmap[4][test] == 1, "char %d should match", test);
540         } else {
541             ck_assert_msg(regexmap[4][test] != 1, "char %d should not match", test);
542         }
543
544
545         if (test == 255) {
546             break;
547         }
548         test++;
549     }
550
551 }
552 END_TEST
553
554 START_TEST(test_regexmap_lparenthesis)
555 {
556     unsigned char test = 0;
557
558     while (1) {
559         if (test == '(') {
560             ck_assert_msg(regexmap[5][test] == 1, "char %d should match", test);
561         } else {
562             ck_assert_msg(regexmap[5][test] != 1, "char %d should not match", test);
563         }
564
565
566         if (test == 255) {
567             break;
568         }
569         test++;
570     }
571
572 }
573 END_TEST
574
575 START_TEST(test_regexmap_rparenthesis)
576 {
577     unsigned char test = 0;
578
579     while (1) {
580         if (test == ')') {
581             ck_assert_msg(regexmap[6][test] == 1, "char %d should match", test);
582         } else {
583             ck_assert_msg(regexmap[6][test] != 1, "char %d should not match", test);
584         }
585
586
587         if (test == 255) {
588             break;
589         }
590         test++;
591     }
592
593 }
594 END_TEST
595
596 START_TEST(test_regexmap_backslash)
597 {
598     unsigned char test = 0;
599
600     while (1) {
601         if (test == '\\') {
602             ck_assert_msg(regexmap[7][test] == 1, "char %d should match", test);
603         } else {
604             ck_assert_msg(regexmap[7][test] != 1, "char %d should not match", test);
605         }
606
607
608         if (test == 255) {
609             break;
610         }
611         test++;
612     }
613
614 }
615 END_TEST
616
617
618 START_TEST(test_regexmap_nondigit)
619 {
620     unsigned char test = 0;
621
622     while (1) {
623         if (!(test >= '0' && test <= '9')) {
624             ck_assert_msg(regexmap[8][test] == 1, "char %d should match", test);
625         } else {
626             ck_assert_msg(regexmap[8][test] != 1, "char %d should not match", test);
627         }
628
629
630         if (test == 255) {
631             break;
632         }
633         test++;
634     }
635
636 }
637 END_TEST
638
639 START_TEST(test_regexmap_nonword)
640 {
641     unsigned char test = 0;
642
643     while (1) {
644         if (!((test >= 'a' && test <= 'z')
645                 || (test >= 'A' && test <= 'Z')
646                 || (test >= '0' && test <= '9')
647                 || test == '-' || test == '@'
648                 || test == '_')) {
649             ck_assert_msg(regexmap[9][test] == 1, "char %d should match", test);
650         } else {
651             ck_assert_msg(regexmap[9][test] != 1, "char %d should not match", test);
652         }
653
654
655         if (test == 255) {
656             break;
657         }
658         test++;
659     }
660
661 }
662 END_TEST
663
664 START_TEST(test_regexmap_nonspace)
665 {
666     unsigned char test = 0;
667
668     while (1) {
669         if (test != ' ') {
670             ck_assert_msg(regexmap[10][test] == 1, "char %d should match", test);
671         } else {
672             ck_assert_msg(regexmap[10][test] != 1, "char %d should not match", test);
673         }
674
675
676         if (test == 255) {
677             break;
678         }
679         test++;
680     }
681
682 }
683 END_TEST
684
685 START_TEST(test_regexmap_all)
686 {
687     unsigned char test = 0;
688
689     while (1) {
690         ck_assert_msg(regexmap[11][test] == 1, "char %d should match", test);
691
692
693         if (test == 255) {
694             break;
695         }
696         test++;
697     }
698
699 }
700 END_TEST
701
702 START_TEST(test_regexmap_tab)
703 {
704     unsigned char test = 0;
705
706     while (1) {
707         if (test == '\t') {
708             ck_assert_msg(regexmap[12][test] == 1, "char %d should match", test);
709         } else {
710             ck_assert_msg(regexmap[12][test] != 1, "char %d should not match", test);
711         }
712
713
714         if (test == 255) {
715             break;
716         }
717         test++;
718     }
719
720 }
721 END_TEST
722
723 START_TEST(test_regexmap_dollar)
724 {
725     unsigned char test = 0;
726
727     while (1) {
728         if (test == '$') {
729             ck_assert_msg(regexmap[13][test] == 1, "char %d should match", test);
730         } else {
731             ck_assert_msg(regexmap[13][test] != 1, "char %d should not match", test);
732         }
733
734
735         if (test == 255) {
736             break;
737         }
738         test++;
739     }
740
741 }
742 END_TEST
743
744 START_TEST(test_regexmap_or)
745 {
746     unsigned char test = 0;
747
748     while (1) {
749         if (test == '|') {
750             ck_assert_msg(regexmap[14][test] == 1, "char %d should match", test);
751         } else {
752             ck_assert_msg(regexmap[14][test] != 1, "char %d should not match", test);
753         }
754
755
756         if (test == 255) {
757             break;
758         }
759         test++;
760     }
761
762 }
763 END_TEST
764
765 START_TEST(test_regexmap_lt)
766 {
767     unsigned char test = 0;
768
769     while (1) {
770         if (test == '<') {
771             ck_assert_msg(regexmap[15][test] == 1, "char %d should match", test);
772         } else {
773             ck_assert_msg(regexmap[15][test] != 1, "char %d should not match", test);
774         }
775
776
777         if (test == 255) {
778             break;
779         }
780         test++;
781     }
782
783 }
784 END_TEST
785
786 START_TEST(test_success_strstartswith)
787 {
788     int i;
789
790     /*
791      * Please note that all strings are \ escaped
792      */
793     const char *tests[][2] = {
794         { "test1234", "test" },
795         { "test", "test" },
796         { "test", "" },
797         { "", "" },
798         {NULL, NULL},
799     };
800
801     for (i = 0; tests[i][0] != NULL ; i++) {
802         ck_assert_msg(OS_StrStartsWith(tests[i][0], tests[i][1]),
803                       "%s should match positive with %s by OS_StrStartsWith",
804                       tests[i][0], tests[i][1]);
805     }
806
807 }
808 END_TEST
809
810 START_TEST(test_fail_strstartswith)
811 {
812     int i;
813
814     /*
815      * Please note that all strings are \ escaped
816      */
817     const char *tests[][2] = {
818         { "test", "test1234" },
819         { "", "test" },
820         {NULL, NULL},
821     };
822
823     for (i = 0; tests[i][0] != NULL ; i++) {
824         ck_assert_msg(!OS_StrStartsWith(tests[i][0], tests[i][1]),
825                       "%s should not match positive with %s by OS_StrStartsWith",
826                       tests[i][0], tests[i][1]);
827     }
828
829 }
830 END_TEST
831
832 Suite *test_suite(void)
833 {
834     Suite *s = suite_create("os_regex");
835
836     /* Core test case */
837     TCase *tc_match = tcase_create("Match");
838     TCase *tc_regex = tcase_create("Regex");
839     TCase *tc_wordmatch = tcase_create("WordMatch");
840     TCase *tc_strisnum = tcase_create("StrIsNum");
841     TCase *tc_strhowclosedmatch = tcase_create("StrHowClosedMatch");
842     TCase *tc_strbreak = tcase_create("StrBreak");
843     TCase *tc_regexextraction = tcase_create("RegexExtraction");
844     TCase *tc_hostnamemap = tcase_create("HostnameMap");
845     TCase *tc_caseinsensitivecharmap = tcase_create("CaseInsensitiveCharmap");
846     TCase *tc_regexmap = tcase_create("RegexMap");
847     TCase *tc_strstartswith = tcase_create("StrStartsWith");
848
849     tcase_add_test(tc_match, test_success_match1);
850     tcase_add_test(tc_match, test_fail_match1);
851
852     tcase_add_test(tc_regex, test_success_regex1);
853     tcase_add_test(tc_regex, test_fail_regex1);
854
855     tcase_add_test(tc_wordmatch, test_success_wordmatch);
856     tcase_add_test(tc_wordmatch, test_fail_wordmatch);
857
858     tcase_add_test(tc_strisnum, test_success_strisnum);
859     tcase_add_test(tc_strisnum, test_fail_strisnum);
860
861     tcase_add_test(tc_strhowclosedmatch, test_strhowclosedmatch);
862
863     tcase_add_test(tc_strbreak, test_strbreak);
864
865     tcase_add_test(tc_regexextraction, test_regexextraction);
866
867     tcase_add_test(tc_hostnamemap, test_hostnamemap);
868
869     tcase_add_test(tc_caseinsensitivecharmap, test_caseinsensitivecharmap);
870
871     tcase_add_test(tc_regexmap, test_regexmap_digit);
872     tcase_add_test(tc_regexmap, test_regexmap_word);
873     tcase_add_test(tc_regexmap, test_regexmap_space);
874     tcase_add_test(tc_regexmap, test_regexmap_punctuation);
875     tcase_add_test(tc_regexmap, test_regexmap_lparenthesis);
876     tcase_add_test(tc_regexmap, test_regexmap_rparenthesis);
877     tcase_add_test(tc_regexmap, test_regexmap_backslash);
878     tcase_add_test(tc_regexmap, test_regexmap_nondigit);
879     tcase_add_test(tc_regexmap, test_regexmap_nonword);
880     tcase_add_test(tc_regexmap, test_regexmap_nonspace);
881     tcase_add_test(tc_regexmap, test_regexmap_all);
882     tcase_add_test(tc_regexmap, test_regexmap_tab);
883     tcase_add_test(tc_regexmap, test_regexmap_dollar);
884     tcase_add_test(tc_regexmap, test_regexmap_or);
885     tcase_add_test(tc_regexmap, test_regexmap_lt);
886
887     tcase_add_test(tc_strstartswith, test_success_strstartswith);
888     tcase_add_test(tc_strstartswith, test_fail_strstartswith);
889
890     suite_add_tcase(s, tc_match);
891     suite_add_tcase(s, tc_regex);
892     suite_add_tcase(s, tc_wordmatch);
893     suite_add_tcase(s, tc_strisnum);
894     suite_add_tcase(s, tc_strhowclosedmatch);
895     suite_add_tcase(s, tc_strbreak);
896     suite_add_tcase(s, tc_regexextraction);
897     suite_add_tcase(s, tc_hostnamemap);
898     suite_add_tcase(s, tc_caseinsensitivecharmap);
899     suite_add_tcase(s, tc_regexmap);
900     suite_add_tcase(s, tc_strstartswith);
901
902     return (s);
903 }
904
905 int main(void)
906 {
907     Suite *s = test_suite();
908     SRunner *sr = srunner_create(s);
909     srunner_run_all(sr, CK_NORMAL);
910     int number_failed = srunner_ntests_failed(sr);
911     srunner_free(sr);
912
913     return ((number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
914 }