new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_regex / os_regex_match.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right 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 <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "os_regex.h"
16 #include "os_regex_internal.h"
17
18 /* Algorithm:
19  *       Go as fast as you can :)
20  *
21  * Supports:
22  *      '|' to separate multiple OR patterns
23  *      '^' to match the beginning of a string
24  */
25
26 /* Prototypes */
27 static int _InternalMatch(const char *pattern, const char *str, size_t count) __attribute__((nonnull));
28
29
30 /* Search for pattern in the string */
31 int OS_WordMatch(const char *pattern, const char *str)
32 {
33     size_t count = 0;
34
35     if (*pattern == '\0') {
36         return (FALSE);
37     }
38
39     do {
40         if (pattern[count] == '|') {
41             /* If we match '|' , search with
42              * we have so far.
43              */
44             if (_InternalMatch(pattern, str, count)) {
45                 return (TRUE);
46             } else {
47                 pattern += count + 1;
48                 count = 0;
49                 continue;
50             }
51         }
52
53         count++;
54
55     } while (pattern[count] != '\0');
56
57     /* Last check until end of string */
58     return (_InternalMatch(pattern, str, count));
59 }
60
61 static int _InternalMatch(const char *pattern, const char *str, size_t pattern_size)
62 {
63     const uchar *pt = (const uchar *)pattern;
64     const uchar *st = (const uchar *)str;
65     const uchar last_char = (const uchar) pattern[pattern_size];
66
67     if (*pattern == '\0') {
68         return (TRUE);
69     }
70
71     /* If '^' specified, just do a strncasecmp */
72     else if (*pattern == '^') {
73         pattern++;
74         pattern_size --;
75
76         /* Compare two strings */
77         if (strncasecmp(pattern, str, pattern_size) == 0) {
78             return (TRUE);
79         }
80         return (FALSE);
81     }
82
83     /* Null line */
84     else if (*st == '\0') {
85         return (FALSE);
86     }
87
88     /* Look to match the first pattern */
89     do {
90         /* Match */
91         if (charmap[*st] == charmap[*pt]) {
92             str = (const char *)st++;
93             pt++;
94
95             while (*pt != last_char) {
96                 if (*st == '\0') {
97                     return (FALSE);
98                 }
99
100                 else if (charmap[*pt] != charmap[*st]) {
101                     goto error;
102                 }
103
104                 st++;
105                 pt++;
106             }
107
108             /* Return here if pt == last_char */
109             return (TRUE);
110
111 error:
112             st = (const uchar *)str;
113             pt = (const uchar *)pattern;
114         }
115
116         st++;
117     } while (*st != '\0');
118
119     return (FALSE);
120 }
121