Skip to content

Commit

Permalink
filterx: performance and safe code fix for regex_subst match groups
Browse files Browse the repository at this point in the history
+ additional unit test for enabled but unused 'group' feature

Signed-off-by: shifter <shifter@axoflow.com>
  • Loading branch information
bshifter committed Dec 2, 2024
1 parent 5535115 commit a805102
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
26 changes: 17 additions & 9 deletions lib/filterx/expr-regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ typedef struct FilterXReMatchState_
FilterXObject *lhs_obj;
const gchar *lhs_str;
gsize lhs_str_len;
gint rc;
} FilterXReMatchState;

static void
Expand Down Expand Up @@ -113,6 +114,7 @@ _match_inner(FilterXReMatchState *state, pcre2_code_8 *pattern, gint start_offse
gint rc = pcre2_match(pattern, (PCRE2_SPTR) state->lhs_str, (PCRE2_SIZE) state->lhs_str_len, (PCRE2_SIZE) start_offset,
0,
state->match_data, NULL);
state->rc = rc;
if (rc < 0)
{
switch (rc)
Expand Down Expand Up @@ -551,6 +553,8 @@ _build_replacement_stirng_with_match_groups(const FilterXFuncRegexpSubst *self,
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(state->match_data);
g_string_set_size(replacement_string, 0);
const gchar *rep_ptr = self->replacement;
const gchar *last_ptr = rep_ptr;
gint num_grps = state->rc;

while (*rep_ptr)
{
Expand All @@ -559,22 +563,26 @@ _build_replacement_stirng_with_match_groups(const FilterXFuncRegexpSubst *self,
rep_ptr++;
if (*rep_ptr >= '1' && *rep_ptr <= '9')
{
gint grp_num = *rep_ptr - '0';
PCRE2_SIZE start = ovector[2 * grp_num];
PCRE2_SIZE end = ovector[2 * grp_num + 1];
if (start != PCRE2_UNSET)
gint grp_idx = *rep_ptr - '0';
if (grp_idx < num_grps)
{
size_t group_len = end - start;
g_string_append_len_inline(replacement_string, state->lhs_str + start, group_len);
PCRE2_SIZE start = ovector[2 * grp_idx];
PCRE2_SIZE end = ovector[2 * grp_idx + 1];
if (start != PCRE2_UNSET)
{
g_string_append_len(replacement_string, last_ptr, rep_ptr - last_ptr - 1);
last_ptr = rep_ptr + 1;
size_t group_len = end - start;
g_string_append_len(replacement_string, state->lhs_str + start, group_len);
}
}
}
rep_ptr++;
}
else
{
g_string_append_c_inline(replacement_string, *rep_ptr++);
}
rep_ptr++;
}
g_string_append_len(replacement_string, last_ptr, rep_ptr - last_ptr);
return TRUE;
}

Expand Down
10 changes: 10 additions & 0 deletions lib/filterx/tests/test_expr_regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,16 @@ Test(filterx_expr_regexp, regexp_subst_group_subst)
filterx_object_unref(result_alt);
}

Test(filterx_expr_regexp, regexp_subst_group_subst_without_ref)
{
FilterXFuncRegexpSubstOpts opts = {.groups = TRUE};
FilterXObject *result = _sub("(\\d{2})-(\\d{2})-(\\d{4})", "group without ref", "25-02-2022", opts);
cr_assert(filterx_object_is_type(result, &FILTERX_TYPE_NAME(string)));
const gchar *res = filterx_string_get_value_ref(result, NULL);
cr_assert_str_eq(res, "group without ref");
filterx_object_unref(result);
}

static void
setup(void)
{
Expand Down

0 comments on commit a805102

Please sign in to comment.