1 /* $OSSEC, os_regex_compile.c, v0.1, 2006/01/02, Daniel B. Cid$ */
3 /* Copyright (C) 2009 Trend Micro Inc.
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
19 #include "os_regex_internal.h"
22 /** int OSRegex_Compile(char *pattern, OSRegex *reg, int flags) v0.1
23 * Compile a regular expression to be used later.
26 * - OS_RETURN_SUBSTRING
27 * Returns 1 on success or 0 on error.
28 * The error code is set on reg->error.
30 int OSRegex_Compile(char *pattern, OSRegex *reg, int flags)
34 int end_of_string = 0;
37 int max_prts_size = 0;
41 char *new_str_free = NULL;
44 /* Checking for references not initialized */
51 /* Initializing OSRegex structure */
55 reg->prts_closure = NULL;
57 reg->sub_strings = NULL;
61 /* The pattern can't be null */
64 reg->error = OS_REGEX_PATTERN_NULL;
68 /* Maximum size of the pattern */
69 if(strlen(pattern) > OS_PATTERN_MAXSIZE)
71 reg->error = OS_REGEX_MAXSIZE;
76 /* Duping the pattern for our internal work */
77 new_str = strdup(pattern);
80 reg->error = OS_REGEX_OUTOFMEMORY;
83 new_str_free = new_str;
87 /* Getting the number of sub patterns */
109 reg->error = OS_REGEX_BADREGEX;
113 /* Giving the new values for each regex */
116 case 'd': *pt = 1;break;
117 case 'w': *pt = 2;break;
118 case 's': *pt = 3;break;
119 case 'p': *pt = 4;break;
120 case '(': *pt = 5;break;
121 case ')': *pt = 6;break;
122 case '\\':*pt = 7;break;
123 case 'D': *pt = 8;break;
124 case 'W': *pt = 9;break;
125 case 'S': *pt = 10;break;
126 case '.': *pt = 11;break;
127 case 't': *pt = 12;break;
128 case '$': *pt = 13;break;
129 case '|': *pt = 14;break;
130 case '<': *pt = 15;break;
142 /* Internally, open and closed are the same */
148 /* We only allow one level of parenthesis */
149 if(parenthesis != 0 && parenthesis != 1)
151 reg->error = OS_REGEX_BADPARENTHESIS;
155 /* The pattern must be always lower case if
156 * case sensitive is set
158 if(!(flags & OS_CASE_SENSITIVE))
160 *pt = charmap[(uchar)*pt];
165 /* Each sub pattern must be closed on parenthesis */
168 reg->error = OS_REGEX_BADPARENTHESIS;
177 /* After the whole pattern is read, the parenthesis must all be closed */
180 reg->error = OS_REGEX_BADPARENTHESIS;
185 /* Allocating the memory for the sub patterns */
187 reg->patterns = calloc(count +1, sizeof(char *));
188 reg->flags = calloc(count +1, sizeof(int));
191 /* For the substrings */
192 if((prts_size > 0) && (flags & OS_RETURN_SUBSTRING))
194 reg->prts_closure = calloc(count +1, sizeof(char **));
195 reg->prts_str = calloc(count +1, sizeof(char **));
196 if(!reg->prts_closure || !reg->prts_str)
198 reg->error = OS_REGEX_OUTOFMEMORY;
204 /* Memory allocation error check */
205 if(!reg->patterns || !reg->flags)
207 reg->error = OS_REGEX_OUTOFMEMORY;
211 /* Initializing each sub pattern */
212 for(i = 0; i<=count; i++)
214 reg->patterns[i] = NULL;
217 /* The parenthesis closure if set */
218 if(reg->prts_closure)
220 reg->prts_closure[i] = NULL;
221 reg->prts_str[i] = NULL;
227 /* Reassigning pt to the beginning of the string */
231 /* Getting the sub patterns */
234 if((*pt == OR) || (*pt == '\0'))
243 /* If string starts with ^, set the BEGIN SET flag */
244 if(*new_str == BEGINREGEX)
247 reg->flags[i]|=BEGIN_SET;
250 /* If string ends with $, set the END_SET flag */
251 if(*(pt-1) == ENDREGEX)
254 reg->flags[i]|=END_SET;
257 reg->patterns[i] = strdup(new_str);
259 if(!reg->patterns[i])
261 reg->error = OS_REGEX_OUTOFMEMORY;
267 /* Setting the parenthesis closures */
268 /* The parenthesis closure if set */
269 if(reg->prts_closure)
275 /* search the whole pattern for parenthesis */
278 /* First loop we get the number of parenthesis.
279 * We allocate the memory and loop again setting
280 * the parenthesis closures.
282 tmp_str = reg->patterns[i];
283 while(*tmp_str != '\0')
292 /* Getting the maximum number of parenthesis for
293 * all sub strings. We need that to set up the maximum
294 * number of substrings to be returned.
296 if(max_prts_size < prts_size)
298 max_prts_size = prts_size;
301 /* Allocating the memory */
302 reg->prts_closure[i] = calloc(prts_size + 1, sizeof(char *));
303 reg->prts_str[i] = calloc(prts_size + 1, sizeof(char *));
304 if((reg->prts_closure[i] == NULL)||(reg->prts_str[i] == NULL))
306 reg->error = OS_REGEX_OUTOFMEMORY;
310 /* Next loop to set the closures */
311 tmp_str = reg->patterns[i];
312 while(*tmp_str != '\0')
316 if(tmp_int >= prts_size)
318 reg->error = OS_REGEX_BADPARENTHESIS;
322 /* Setting to the pointer to the string */
323 reg->prts_closure[i][tmp_int] = tmp_str;
324 reg->prts_str[i][tmp_int] = NULL;
345 }while(!end_of_string);
347 /* Allocating sub string for the maximum number of parenthesis */
348 reg->sub_strings = calloc(max_prts_size + 1, sizeof(char *));
349 if(reg->sub_strings == NULL)
351 reg->error = OS_REGEX_OUTOFMEMORY;
368 OSRegex_FreePattern(reg);