Imported Upstream version 2.3
[ossec-hids.git] / src / os_regex / os_match_compile.c
1 /*   $OSSEC, os_match_compile.c, v0.1, 2006/04/17, Daniel B. Cid$   */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All right reserved.
5  *
6  * This program is a free software; you can redistribute it
7  * and/or modify it under the terms of the GNU General Public
8  * License (version 3) as published by the FSF - Free Software
9  * Foundation
10  */
11
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <ctype.h>
17
18 #include "os_regex.h"
19 #include "os_regex_internal.h"
20
21 /* Prototype fo the _OsMatch */
22 int _OS_Match(char *pattern, char *str, int str_len, int size);
23 int _os_strncmp(char *pattern, char *str, int str_len, int size);
24 int _os_strcmp_last(char *pattern, char *str, int str_len, int size);
25 int _os_strcmp(char *pattern, char *str, int str_len, int size);
26 int _os_strmatch(char *pattern, char *str, int str_len, int size);
27
28
29 /** int OSMatch_Compile(char *pattern, OSMatch *reg, int flags) v0.1
30  * Compile a pattern to be used later.
31  * Allowed flags are:
32  *      - OS_CASE_SENSITIVE
33  * Returns 1 on success or 0 on error.
34  * The error code is set on reg->error.
35  */
36 int OSMatch_Compile(char *pattern, OSMatch *reg, int flags)
37 {
38     int i = 0;
39     int count = 0;
40     int end_of_string = 0;
41     
42     char *pt;
43     char *new_str;
44     char *new_str_free = NULL;
45
46     
47     /* Checking for references not initialized */
48     if(reg == NULL)
49     {
50         return(0);
51     }
52     
53
54     /* Initializing OSRegex structure */
55     reg->error = 0;
56     reg->patterns = NULL;
57     reg->size = NULL;
58
59
60     /* The pattern can't be null */
61     if(pattern == NULL)
62     {
63         reg->error = OS_REGEX_PATTERN_NULL;
64         goto compile_error;
65     }
66
67
68     /* Maximum size of the pattern */
69     if(strlen(pattern) > OS_PATTERN_MAXSIZE)
70     {
71         reg->error = OS_REGEX_MAXSIZE;
72         goto compile_error;
73     }
74     
75     
76     /* Duping the pattern for our internal work */
77     new_str = strdup(pattern);
78     if(!new_str)
79     {
80         reg->error = OS_REGEX_OUTOFMEMORY;
81         goto compile_error;
82     }
83     new_str_free = new_str;
84     pt = new_str;
85     
86     
87     /* Getting the number of sub patterns */
88     while(*pt != '\0')
89     {
90         /* The pattern must be always lower case if 
91          * case sensitive is set
92          */
93         if(!(flags & OS_CASE_SENSITIVE))
94         {
95             *pt = charmap[(uchar)*pt];
96         }
97        
98         /* Number of sub patterns */ 
99         if(*pt == OR)
100         {
101             count++;
102         }
103         pt++;    
104     }
105     
106     
107     /* For the last pattern */
108     count++;
109     reg->patterns = calloc(count +1, sizeof(char *));
110     reg->size = calloc(count +1, sizeof(int));
111     reg->match_fp = calloc(count +1, sizeof(void *));
112     
113     
114     /* Memory allocation error check */
115     if(!reg->patterns || !reg->size || !reg->match_fp)
116     {
117         reg->error = OS_REGEX_OUTOFMEMORY;
118         goto compile_error;
119     }
120
121
122     /* Initializing each sub pattern */
123     for(i = 0; i<=count; i++)
124     {
125         reg->patterns[i] = NULL;
126         reg->match_fp[i] = NULL;
127         reg->size[i] = 0;
128     }
129     i = 0;
130     
131     
132     /* Reassigning pt to the beginning of the string */
133     pt = new_str;
134
135     
136     /* Getting the sub patterns */
137     do
138     {
139         if((*pt == OR) || (*pt == '\0'))
140         {
141             if(*pt == '\0')
142             {
143                 end_of_string = 1;
144             }
145
146             *pt = '\0';
147
148             /* Dupping the string */
149             if(*new_str == BEGINREGEX)
150                 reg->patterns[i] = strdup(new_str +1);
151             else     
152                 reg->patterns[i] = strdup(new_str);
153
154             /* Memory error */
155             if(!reg->patterns[i])
156             {
157                 reg->error = OS_REGEX_OUTOFMEMORY;
158                 goto compile_error;
159             }
160
161
162             /* If the string has ^ and $ */
163             if((*new_str == BEGINREGEX) && (*(pt -1) == ENDREGEX))
164             {
165                 reg->match_fp[i] = _os_strcmp;
166                 reg->size[i] = strlen(reg->patterns[i]) -1;
167                 reg->patterns[i][reg->size[i]] = '\0';
168             }
169             else if(strlen(new_str) == 0)
170             {
171                 reg->match_fp[i] = _os_strmatch;
172                 reg->size[i] = 0;
173             }
174
175             /* String only has $ */
176             else if(*(pt -1) == ENDREGEX)
177             {
178                 reg->match_fp[i] = _os_strcmp_last;
179                 reg->size[i] = strlen(reg->patterns[i]) -1;
180                 reg->patterns[i][reg->size[i]] = '\0';
181             }
182             
183             /* If string starts with ^, use strncmp */
184             else if(*new_str == BEGINREGEX)
185             {
186                 reg->match_fp[i] = _os_strncmp;
187                 reg->size[i] = strlen(reg->patterns[i]);
188             }
189             else
190             {
191                 reg->match_fp[i] = _OS_Match;
192                 reg->size[i] = strlen(reg->patterns[i]);
193             }
194
195             if(end_of_string)
196             {
197                 break;
198             }
199
200             new_str = ++pt;
201             i++;
202             continue;
203         }
204         pt++;
205
206     }while(!end_of_string);
207
208
209     /* Success return */
210     free(new_str_free);
211     return(1);
212     
213     
214     /* Error handling */
215     compile_error:
216     
217     if(new_str_free)
218     {
219         free(new_str_free);
220     }
221     
222     OSMatch_FreePattern(reg);
223
224     return(0);
225 }
226
227
228 /* EOF */