diff --git a/libclamav/others.h b/libclamav/others.h index a8dfa7c631..59f594be31 100644 --- a/libclamav/others.h +++ b/libclamav/others.h @@ -1314,31 +1314,6 @@ uint8_t cli_set_debug_flag(uint8_t debug_flag); } while (0) #endif -/** - * @brief Wrapper around realloc that limits how much may be allocated to CLI_MAX_ALLOCATION. - * - * IMPORTANT: This differs from realloc() in that if size==0, it will NOT free the ptr. - * - * NOTE: cli_realloc() will NOT free var if size==0. It is safe to free var after `done:`. - * - * @param ptr - * @param size - * @return void* - */ -#ifndef CLI_REALLOC -#define CLI_REALLOC(var, size, ...) \ - do { \ - void *vTmp = cli_realloc(var, size); \ - if (NULL == vTmp) { \ - do { \ - __VA_ARGS__; \ - } while (0); \ - goto done; \ - } \ - var = vTmp; \ - } while (0) -#endif - /** * @brief Wrapper around realloc that limits how much may be allocated to CLI_MAX_ALLOCATION. * @@ -1364,4 +1339,18 @@ uint8_t cli_set_debug_flag(uint8_t debug_flag); } while (0) #endif +/*This is a duplicate from other PR's.*/ +#ifndef CLI_STRDUP +#define CLI_STRDUP(buf, var, ...) \ + do { \ + var = cli_strdup(buf); \ + if (NULL == var) { \ + do { \ + __VA_ARGS__; \ + } while (0); \ + goto done; \ + } \ + } while (0) +#endif + #endif diff --git a/libclamav/regex_suffix.c b/libclamav/regex_suffix.c index 863a862e52..2eeb3cc919 100644 --- a/libclamav/regex_suffix.c +++ b/libclamav/regex_suffix.c @@ -170,24 +170,24 @@ static void destroy_tree(struct node *n) break; case leaf_class: if (n->u.leaf_class_bitmap != dot_bitmap) - free(n->u.leaf_class_bitmap); + FREE(n->u.leaf_class_bitmap); break; case root: case leaf: break; } - free(n); + FREE(n); } static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos) { unsigned char range_start = 0; int hasprev = 0; - uint8_t *bitmap = cli_malloc(32); - if (!bitmap) { - cli_errmsg("parse_char_class: Unable to allocate memory for bitmap\n"); - return NULL; - } + uint8_t *bitmap = NULL; + + CLI_MALLOC(bitmap, 32, + cli_errmsg("parse_char_class: Unable to allocate memory for bitmap\n")); + if (pat[*pos] == '^') { memset(bitmap, 0xFF, 32); /*match chars not in brackets*/ ++*pos; @@ -200,14 +200,15 @@ static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos) unsigned char range_end; unsigned int c; if (0 == range_start) { + FREE(bitmap); cli_errmsg("parse_char_class: range_start not initialized"); - return NULL; + goto done; } ++*pos; if (pat[*pos] == '[') if (pat[*pos + 1] == '.') { /* collating sequence not handled */ - free(bitmap); + FREE(bitmap); /* we are parsing the regex for a * filter, be conservative and * tell the filter that anything could @@ -225,7 +226,7 @@ static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos) hasprev = 0; } else if (pat[*pos] == '[' && pat[*pos] == ':') { /* char class */ - free(bitmap); + FREE(bitmap); while (pat[*pos] != ']') ++*pos; ++*pos; while (pat[*pos] != ']') ++*pos; @@ -237,6 +238,8 @@ static uint8_t *parse_char_class(const uint8_t *pat, size_t *pos) hasprev = 1; } } while (pat[*pos] != ']'); + +done: return bitmap; } @@ -252,8 +255,10 @@ static struct node *parse_regex(const uint8_t *p, size_t *last) ++*last; right = parse_regex(p, last); v = make_node(alternate, v, right); - if (!v) + if (!v) { + destroy_tree(right); return NULL; + } break; case '*': case '?': @@ -265,25 +270,31 @@ static struct node *parse_regex(const uint8_t *p, size_t *last) case '+': /* (x)* */ tmp = make_node(optional, v, NULL); - if (!tmp) + if (!tmp) { + destroy_tree(v); return NULL; + } /* (x) */ right = dup_node(v); if (!right) { - free(tmp); + destroy_tree(tmp); return NULL; } /* (x)*(x) => (x)+ */ v = make_node(concat, tmp, right); - if (!v) + if (!v) { + destroy_tree(right); return NULL; + } ++*last; break; case '(': ++*last; right = parse_regex(p, last); - if (!right) + if (!right) { + destroy_tree(v); return NULL; + } ++*last; v = make_node(concat, v, right); break; @@ -291,8 +302,10 @@ static struct node *parse_regex(const uint8_t *p, size_t *last) return v; case '.': right = make_charclass(dot_bitmap); - if (!right) + if (!right) { + destroy_tree(v); return NULL; + } v = make_node(concat, v, right); if (!v) return NULL; @@ -301,11 +314,15 @@ static struct node *parse_regex(const uint8_t *p, size_t *last) case '[': ++*last; right = make_charclass(parse_char_class(p, last)); - if (!right) + if (!right) { + destroy_tree(v); return NULL; + } v = make_node(concat, v, right); - if (!v) + if (!v) { + destroy_tree(right); return NULL; + } ++*last; break; case '\\': @@ -315,8 +332,10 @@ static struct node *parse_regex(const uint8_t *p, size_t *last) default: right = make_leaf(p[*last]); v = make_node(concat, v, right); - if (!v) + if (!v) { + destroy_tree(right); return NULL; + } ++*last; break; } @@ -435,8 +454,11 @@ cl_error_t cli_regex2suffix(const char *pattern, regex_t *preg, suffix_callback size_t last = 0; int rc; - VERIFY_POINTER(pattern, cli_errmsg("cli_regex2suffix: pattern must be initialized"); rc = CL_ENULLARG); - VERIFY_POINTER(preg, cli_errmsg("cli_regex2suffix: preg must be initialized"); rc = CL_ENULLARG); + if (NULL == pattern) { + cli_errmsg("cli_regex2suffix: pattern can't be NULL"); + rc = REG_INVARG; + goto done; + } regex.preg = preg; rc = cli_regcomp(regex.preg, pattern, REG_EXTENDED); @@ -453,11 +475,15 @@ cl_error_t cli_regex2suffix(const char *pattern, regex_t *preg, suffix_callback return rc; } regex.nxt = NULL; - CLI_STRDUP(pattern, regex.pattern, cli_errmsg("cli_regex2suffix: Unable to duplicate pattern"); rc = CL_EMEM); + CLI_STRDUP(pattern, regex.pattern, + cli_errmsg("cli_regex2suffix: unable to strdup regex.pattern"); + rc = REG_ESPACE); - n = parse_regex(((const uint8_t *)pattern), &last); - if (!n) - return REG_ESPACE; + n = parse_regex(pattern, &last); + if (!n) { + rc = REG_ESPACE; + goto done; + } memset(&buf, 0, sizeof(buf)); memset(&root_node, 0, sizeof(buf)); n->parent = &root_node; @@ -465,7 +491,6 @@ cl_error_t cli_regex2suffix(const char *pattern, regex_t *preg, suffix_callback rc = build_suffixtree_descend(n, &buf, cb, cbdata, ®ex); done: - FREE(regex.pattern); FREE(buf.data); destroy_tree(n);