X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Fos_regex%2Fos_regex_execute.c;h=682ae483f4163d97f596a1c2dbc6bc6f6ab264aa;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hp=5fef327150ad2d0c1000c35de996ea132ed92152;hpb=6ef2f786c6c8ead94841b5f93baf9f43421f08c8;p=ossec-hids.git diff --git a/src/os_regex/os_regex_execute.c b/src/os_regex/os_regex_execute.c old mode 100755 new mode 100644 index 5fef327..682ae48 --- a/src/os_regex/os_regex_execute.c +++ b/src/os_regex/os_regex_execute.c @@ -1,5 +1,3 @@ -/* $OSSEC, os_regex.c, v0.3, 2005/04/05, Daniel B. Cid$ */ - /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * @@ -9,490 +7,111 @@ * Foundation */ - #include #include #include #include "os_regex.h" -#include "os_regex_internal.h" - - -/** Internal prototypes **/ -char *_OS_Regex(char *pattern, char *str, char **prts_closure, - char **prts_str, int flags); - - -/** char *OSRegex_Execute(char *str, OSRegex *reg) v0.1 - * Compare an already compiled regular expression with +/* Compare an already compiled regular expression with * a not NULL string. * Returns the end of the string on success or NULL on error. * The error code is set on reg->error. */ -char *OSRegex_Execute(char *str, OSRegex *reg) +const char *OSRegex_Execute(const char *str, OSRegex *reg) { - char *ret; - int i = 0; - /* The string can't be NULL */ - if(str == NULL) - { + if (str == NULL) { reg->error = OS_REGEX_STR_NULL; - return(0); + return (NULL); } + return reg->exec_function(str, reg); +} +const char *OSRegex_Execute_pcre2_match(const char *str, OSRegex *reg) +{ + int rc = 0, nbs = 0, i = 0; + PCRE2_SIZE *ov = NULL; + + /* Execute the reg */ +#ifdef USE_PCRE2_JIT + rc = pcre2_jit_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL); +#else + rc = pcre2_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL); +#endif + + /* Check execution result */ + if (rc <= 0) { + return NULL; + } - /* If we need the sub strings */ - if(reg->prts_closure) - { - int j = 0, k = 0, str_char = 0; - - /* Looping on all sub patterns */ - while(reg->patterns[i]) - { - /* Cleaning the prts_str */ - j = 0; - while(reg->prts_closure[i][j]) - { - reg->prts_str[i][j] = NULL; - j++; - } - - if((ret = _OS_Regex(reg->patterns[i], str, reg->prts_closure[i], - reg->prts_str[i], reg->flags[i]))) - { - j = 0; - - /* We must always have the open and the close */ - while(reg->prts_str[i][j] && reg->prts_str[i][j+1]) - { - str_char = reg->prts_str[i][j+1][0]; - - reg->prts_str[i][j+1][0] = '\0'; - - reg->sub_strings[k] = strdup(reg->prts_str[i][j]); - if(!reg->sub_strings[k]) - { - OSRegex_FreeSubStrings(reg); - return(NULL); - } - - /* Set the next one to null */ - reg->prts_str[i][j+1][0] = str_char; - k++; - reg->sub_strings[k] = NULL; - - /* Go two by two */ - j+=2; - } - - return(ret); + /* get the offsets informations for the match */ + ov = pcre2_get_ovector_pointer(reg->match_data); + + if (reg->sub_strings) { + /* get the substrings if required */ + for (i = 1; i < rc; i++) { + PCRE2_SIZE sub_string_start = ov[2 * i]; + PCRE2_SIZE sub_string_end = ov[2 * i + 1]; + PCRE2_SIZE sub_string_len = sub_string_end - sub_string_start; + if (sub_string_end > sub_string_start) { + reg->sub_strings[nbs] = (char *)calloc(sub_string_len + 1, sizeof(char)); + strncpy(reg->sub_strings[nbs], &str[sub_string_start], sub_string_len); + nbs++; } - i++; } - - return(0); - + reg->sub_strings[nbs] = NULL; } - /* If we don't need the sub strings */ + return &str[ov[1]]; +} - /* Looping on all sub patterns */ - while(reg->patterns[i]) - { - if((ret = _OS_Regex(reg->patterns[i], str, NULL, NULL, reg->flags[i]))) - { - return(ret); - } - i++; +const char *OSRegex_Execute_strcmp(const char *subject, OSRegex *reg) +{ + if (!strcmp(reg->pattern, subject)) { + return &subject[reg->pattern_len]; } - - return(NULL); + return NULL; } -#define PRTS(x) ((prts(*x) && x++) || 1) -#define ENDOFFILE(x) ( PRTS(x) && (*x == '\0')) - -/** int _OS_Regex(char *pattern, char *str, char **prts_closure, - char **prts_str, int flags) v0.1 - * Perform the pattern matching on the pattern/string provided. - * Returns 1 on success and 0 on failure. - * If prts_closure is set, the parenthesis locations will be - * written on prts_str (which must not be NULL) - */ -char *_OS_Regex(char *pattern, char *str, char **prts_closure, - char **prts_str, int flags) +const char *OSRegex_Execute_strncmp(const char *subject, OSRegex *reg) { - char *r_code = NULL; - - int ok_here; - int _regex_matched = 0; - - int prts_int; - - char *st = str; - char *st_error = NULL; - - char *pt = pattern; - char *next_pt; - - char *pt_error[4] = {NULL, NULL, NULL, NULL}; - char *pt_error_str[4]; - - - /* Will loop the whole string, trying to find a match */ - do - { - switch(*pt) - { - case '\0': - if(!(flags & END_SET) || (flags & END_SET && (*st == '\0'))) - return(r_code); - break; - - /* If it is a parenthesis do not match against the character */ - case '(': - /* Find the closure for the parenthesis */ - if(prts_closure) - { - prts_int = 0; - while(prts_closure[prts_int]) - { - if(prts_closure[prts_int] == pt) - { - prts_str[prts_int] = st; - break; - } - prts_int++; - } - } - - pt++; - if(*pt == '\0') - { - if(!(flags & END_SET) || (flags & END_SET && (*st == '\0'))) - return(r_code); - } - break; - } - - /* If it starts on Backslash (future regex) */ - if(*pt == BACKSLASH) - { - if(Regex((uchar)*(pt+1), (uchar)*st)) - { - next_pt = pt+2; - - /* If we don't have a '+' or '*', we should skip - * searching using this pattern. - */ - if(!isPlus(*next_pt)) - { - pt = next_pt; - if(!st_error) - { - /* If st_error is not set, we need to set it here. - * In case of error in the matching later, we need - * to continue from here (it will be incremented in - * the while loop) - */ - st_error = st; - } - r_code = st; - continue; - } - - /* If it is a '*', we need to set the _regex_matched - * for the first pattern even. - */ - if(*next_pt == '*') - { - _regex_matched = 1; - } - - - /* If our regex matches and we have a "+" set, we will - * try the next one to see if it matches. If yes, we - * can jump to it, but saving our currently location - * in case of error. - * _regex_matched will set set to true after the first - * round of matches - */ - if(_regex_matched) - { - next_pt++; - ok_here = -1; - - /* If it is a parenthesis, jump to the next and write - * the location down if 'ok_here >= 0' - */ - if(prts(*next_pt)) - { - next_pt++; - } - - if(*next_pt == '\0') - { - ok_here = 1; - } - else if(*next_pt == BACKSLASH) - { - if(Regex((uchar)*(next_pt+1), (uchar)*st)) - { - /* If the next one does not have - * a '+' or '*', we can set it as - * being read and continue. - */ - if(!isPlus(*(next_pt+2))) - { - ok_here = 2; - } - else - { - ok_here = 0; - } - } - } - else if(*next_pt == charmap[(uchar)*st]) - { - _regex_matched = 0; - ok_here = 1; - } - - /* If the next character matches in here */ - if(ok_here >= 0) - { - if(prts_closure && prts(*(next_pt - 1))) - { - prts_int = 0; - while(prts_closure[prts_int]) - { - if(prts_closure[prts_int] == (next_pt -1)) - { - if(*(st+1) == '\0') - prts_str[prts_int] = st+1; - else - prts_str[prts_int] = st; - break; - } - prts_int++; - } - } - - - /* If next_pt == \0, return the r_code */ - if(*next_pt == '\0') - { - continue; - } - - - /* Each "if" will increment the amount - * necessary for the next pattern in ok_here - */ - if(ok_here) - next_pt+=ok_here; - - - if(!pt_error[0]) - { - pt_error[0] = pt; - pt_error_str[0] = st; - } - else if(!pt_error[1]) - { - pt_error[1] = pt; - pt_error_str[1] = st; - } - else if(!pt_error[2]) - { - pt_error[2] = pt; - pt_error_str[2] = st; - - } - else if(!pt_error[3]) - { - pt_error[3] = pt; - pt_error_str[3] = st; - } - - pt = next_pt; - } - } - else - { - next_pt++; - - /* If it is a parenthesis, mark the location */ - if(prts_closure && prts(*next_pt)) - { - prts_int = 0; - while(prts_closure[prts_int]) - { - if(prts_closure[prts_int] == next_pt) - { - if(*(st+1) == '\0') - prts_str[prts_int] = st +1; - else - prts_str[prts_int] = st; - break; - } - prts_int++; - } - next_pt++; - } - - _regex_matched = 1; - } - - r_code = st; - continue; - } - - else if((*(pt+3) == '\0') && (_regex_matched == 1)&&(r_code)) - { - r_code = st; - if(!(flags & END_SET) || (flags & END_SET && (*st == '\0'))) - return(r_code); - } - - /* If we didn't match regex, but _regex_matched == 1, jump - * to the next available pattern - */ - else if((*(pt+2) == '+') && (_regex_matched == 1)) - { - pt+=3; - st--; - _regex_matched = 0; - continue; - } - /* We may not match with '*' */ - else if(*(pt+2) == '*') - { - pt+=3; - st--; - r_code = st; - _regex_matched = 0; - continue; - } - - _regex_matched = 0; - } - else if(*pt == charmap[(uchar)*st]) - { - pt++; - if(!st_error) - { - /* If st_error is not set, we need to set it here. - * In case of error in the matching later, we need - * to continue from here (it will be incremented in - * the while loop) - */ - st_error = st; - } - r_code = st; - continue; - } - - /* Error Handling */ - if(pt_error[3]) - { - pt = pt_error[3]; - st = pt_error_str[3]; - pt_error[3] = NULL; - continue; - } - else if(pt_error[2]) - { - pt = pt_error[2]; - st = pt_error_str[2]; - pt_error[2] = NULL; - continue; - } - else if(pt_error[1]) - { - pt = pt_error[1]; - st = pt_error_str[1]; - pt_error[1] = NULL; - continue; - } - else if(pt_error[0]) - { - pt = pt_error[0]; - st = pt_error_str[0]; - pt_error[0] = NULL; - continue; - } - else if(flags & BEGIN_SET) - { - /* If we get an error and the "^" option is - * set, we can return "not matched" in here. - */ - return(NULL); - } - else if(st_error) - { - st = st_error; - st_error = NULL; - } - pt = pattern; - r_code = NULL; - - }while(*(++st) != '\0'); - - - /* Matching for a possible last parenthesis */ - if(prts_closure) - { - while(!prts(*pt) && *pt != '\0') - { - if(*pt == BACKSLASH && *(pt+2) == '*') - pt+=3; - else - break; - } - - if(prts(*pt)) - { - prts_int = 0; - while(prts_closure[prts_int]) - { - if(prts_closure[prts_int] == pt) - { - prts_str[prts_int] = st; - break; - } - prts_int++; - } - } + if (!strncmp(reg->pattern, subject, reg->pattern_len)) { + return &subject[reg->pattern_len]; } + return NULL; +} - /* Cleaning up */ - if(ENDOFFILE(pt) || - (*pt == BACKSLASH && - _regex_matched && - (pt+=2) && - isPlus(*pt) && - (pt++) && - ((ENDOFFILE(pt)) || - ((*pt == BACKSLASH) && - (pt+=2) && - (*pt == '*') && - (pt++) && - (ENDOFFILE(pt)) ))) || - (*pt == BACKSLASH && - (pt+=2) && - (*pt == '*') && - (pt++) && - ENDOFFILE(pt)) - ) - { - return(r_code); +const char *OSRegex_Execute_strrcmp(const char *subject, OSRegex *reg) +{ + size_t len = strlen(subject); + if (len >= reg->pattern_len && !strcmp(reg->pattern, &subject[len - reg->pattern_len])) { + return &subject[len]; } + return NULL; +} - return(NULL); +const char *OSRegex_Execute_strcasecmp(const char *subject, OSRegex *reg) +{ + if (!strcasecmp(reg->pattern, subject)) { + return &subject[reg->pattern_len]; + } + return NULL; } +const char *OSRegex_Execute_strncasecmp(const char *subject, OSRegex *reg) +{ + if (!strncasecmp(reg->pattern, subject, reg->pattern_len)) { + return &subject[reg->pattern_len]; + } + return NULL; +} -/* EOF */ +const char *OSRegex_Execute_strrcasecmp(const char *subject, OSRegex *reg) +{ + size_t len = strlen(subject); + if (len >= reg->pattern_len && !strcasecmp(reg->pattern, &subject[len - reg->pattern_len])) { + return &subject[len]; + } + return NULL; +}