aboutsummaryrefslogtreecommitdiff
path: root/posix/regexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'posix/regexec.c')
-rw-r--r--posix/regexec.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/posix/regexec.c b/posix/regexec.c
index 3cc9288a67..fa4f218df3 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -2551,7 +2551,6 @@ get_subexp (mctx, bkref_node, bkref_str_idx)
re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
re_sub_match_last_t *sub_last;
int sub_last_idx, sl_str, bkref_str_off;
- const char *bkref_str;
if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
continue; /* It isn't related. */
@@ -2567,9 +2566,24 @@ get_subexp (mctx, bkref_node, bkref_str_idx)
sl_str_diff = sub_last->str_idx - sl_str;
/* The matched string by the sub expression match with the substring
at the back reference? */
- if (sl_str_diff > 0
- && memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
- break; /* We don't need to search this sub expression any more. */
+ if (sl_str_diff > 0)
+ {
+ if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
+ {
+ /* Not enough chars for a successful match. */
+ if (bkref_str_off + sl_str_diff > mctx->input.len)
+ break;
+
+ err = clean_state_log_if_needed (mctx,
+ bkref_str_off
+ + sl_str_diff);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+ buf = (const char *) re_string_get_buffer (&mctx->input);
+ }
+ if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
+ break; /* We don't need to search this sub expression any more. */
+ }
bkref_str_off += sl_str_diff;
sl_str += sl_str_diff;
err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
@@ -2584,7 +2598,6 @@ get_subexp (mctx, bkref_node, bkref_str_idx)
if (BE (err != REG_NOERROR, 0))
return err;
}
- bkref_str = buf + bkref_str_off;
if (sub_last_idx < sub_top->nlasts)
continue;
@@ -2598,8 +2611,24 @@ get_subexp (mctx, bkref_node, bkref_str_idx)
sl_str_off = sl_str - sub_top->str_idx;
/* The matched string by the sub expression match with the substring
at the back reference? */
- if (sl_str_off > 0 && *bkref_str++ != buf[sl_str - 1])
- break; /* We don't need to search this sub expression any more. */
+ if (sl_str_off > 0)
+ {
+ if (BE (bkref_str_off >= mctx->input.valid_len, 0))
+ {
+ /* If we are at the end of the input, we cannot match. */
+ if (bkref_str_off >= mctx->input.len)
+ break;
+
+ err = extend_buffers (mctx);
+ if (BE (err != REG_NOERROR, 0))
+ return err;
+
+ buf = (const char *) re_string_get_buffer (&mctx->input);
+ }
+ if (buf [bkref_str_off++] != buf[sl_str - 1])
+ break; /* We don't need to search this sub expression
+ any more. */
+ }
if (mctx->state_log[sl_str] == NULL)
continue;
/* Does this state have a ')' of the sub expression? */
@@ -2659,8 +2688,7 @@ get_subexp_sub (mctx, sub_top, sub_last, bkref_node, bkref_str)
if (BE (err != REG_NOERROR, 0))
return err;
to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
- clean_state_log_if_needed (mctx, to_idx);
- return REG_NOERROR;
+ return clean_state_log_if_needed (mctx, to_idx);
}
/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.