Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 14 additions & 25 deletions libclamav/others.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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
77 changes: 51 additions & 26 deletions libclamav/regex_suffix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;
}

Expand All @@ -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 '?':
Expand All @@ -265,34 +270,42 @@ 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;
case ')':
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;
Expand All @@ -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 '\\':
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -453,19 +475,22 @@ 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;

rc = build_suffixtree_descend(n, &buf, cb, cbdata, &regex);

done:

FREE(regex.pattern);
FREE(buf.data);
destroy_tree(n);
Expand Down