summaryrefslogtreecommitdiff
path: root/pcre_exec.c
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2015-02-11 16:48:35 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2015-02-11 16:48:35 +0000
commite8b2eeee0cd812405f60cb27ccb43e5e085b0f93 (patch)
treeb33b5c32237772c1f30309ad99dcfd805bee9376 /pcre_exec.c
parentce9b59fc85f65e65ea6858874571b33fc7cad1dd (diff)
downloadpcre-e8b2eeee0cd812405f60cb27ccb43e5e085b0f93.tar.gz
Fix bug that did not allow zero case for (a)*+ when ovector was too small to
capture. git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1525 2f5784b3-3f2a-0410-8824-cb99058d5e15
Diffstat (limited to 'pcre_exec.c')
-rw-r--r--pcre_exec.c140
1 files changed, 64 insertions, 76 deletions
diff --git a/pcre_exec.c b/pcre_exec.c
index 607aad8..788cc76 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -1136,93 +1136,81 @@ for (;;)
printf("\n");
#endif
- if (offset < md->offset_max)
- {
- matched_once = FALSE;
- code_offset = (int)(ecode - md->start_code);
+ if (offset >= md->offset_max) goto POSSESSIVE_NON_CAPTURE;
- save_offset1 = md->offset_vector[offset];
- save_offset2 = md->offset_vector[offset+1];
- save_offset3 = md->offset_vector[md->offset_end - number];
- save_capture_last = md->capture_last;
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
- DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+ save_offset1 = md->offset_vector[offset];
+ save_offset2 = md->offset_vector[offset+1];
+ save_offset3 = md->offset_vector[md->offset_end - number];
+ save_capture_last = md->capture_last;
- /* Each time round the loop, save the current subject position for use
- when the group matches. For MATCH_MATCH, the group has matched, so we
- restart it with a new subject starting position, remembering that we had
- at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
- usual. If we haven't matched any alternatives in any iteration, check to
- see if a previous iteration matched. If so, the group has matched;
- continue from afterwards. Otherwise it has failed; restore the previous
- capture values before returning NOMATCH. */
+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
- for (;;)
- {
- md->offset_vector[md->offset_end - number] =
- (int)(eptr - md->start_subject);
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM63);
- if (rrc == MATCH_KETRPOS)
- {
- offset_top = md->end_offset_top;
- ecode = md->start_code + code_offset;
- save_capture_last = md->capture_last;
- matched_once = TRUE;
- mstart = md->start_match_ptr; /* In case \K changed it */
- if (eptr == md->end_match_ptr) /* Matched an empty string */
- {
- do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
- break;
- }
- eptr = md->end_match_ptr;
- continue;
- }
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
+ /* Each time round the loop, save the current subject position for use
+ when the group matches. For MATCH_MATCH, the group has matched, so we
+ restart it with a new subject starting position, remembering that we had
+ at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
+ usual. If we haven't matched any alternatives in any iteration, check to
+ see if a previous iteration matched. If so, the group has matched;
+ continue from afterwards. Otherwise it has failed; restore the previous
+ capture values before returning NOMATCH. */
- if (rrc == MATCH_THEN)
+ for (;;)
+ {
+ md->offset_vector[md->offset_end - number] =
+ (int)(eptr - md->start_subject);
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM63);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ ecode = md->start_code + code_offset;
+ save_capture_last = md->capture_last;
+ matched_once = TRUE;
+ mstart = md->start_match_ptr; /* In case \K changed it */
+ if (eptr == md->end_match_ptr) /* Matched an empty string */
{
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+ break;
}
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->capture_last = save_capture_last;
- ecode += GET(ecode, 1);
- if (*ecode != OP_ALT) break;
+ eptr = md->end_match_ptr;
+ continue;
}
- if (!matched_once)
- {
- md->offset_vector[offset] = save_offset1;
- md->offset_vector[offset+1] = save_offset2;
- md->offset_vector[md->offset_end - number] = save_offset3;
- }
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
- if (allow_zero || matched_once)
+ if (rrc == MATCH_THEN)
{
- ecode += 1 + LINK_SIZE;
- break;
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
}
- RRETURN(MATCH_NOMATCH);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
}
- /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
- as a non-capturing bracket. */
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ if (!matched_once)
+ {
+ md->offset_vector[offset] = save_offset1;
+ md->offset_vector[offset+1] = save_offset2;
+ md->offset_vector[md->offset_end - number] = save_offset3;
+ }
- DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+ if (allow_zero || matched_once)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ RRETURN(MATCH_NOMATCH);
/* Non-capturing possessive bracket with unlimited repeat. We come here
from BRAZERO with allow_zero = TRUE. The code is similar to the above,
@@ -1404,11 +1392,11 @@ for (;;)
condition = TRUE;
/* Advance ecode past the assertion to the start of the first branch,
- but adjust it so that the general choosing code below works. If the
- assertion has a quantifier that allows zero repeats we must skip over
+ but adjust it so that the general choosing code below works. If the
+ assertion has a quantifier that allows zero repeats we must skip over
the BRAZERO. This is a lunatic thing to do, but somebody did! */
-
- if (*ecode == OP_BRAZERO) ecode++;
+
+ if (*ecode == OP_BRAZERO) ecode++;
ecode += GET(ecode, 1);
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
@@ -1840,11 +1828,11 @@ for (;;)
are defined in a range that can be tested for. */
if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
- {
+ {
if (new_recursive.offset_save != stacksave)
(PUBL(free))(new_recursive.offset_save);
RRETURN(MATCH_NOMATCH);
- }
+ }
/* Any return code other than NOMATCH is an error. */