Fix non-passing of mark values out of recursions.
This commit is contained in:
parent
fcd0c39b26
commit
0757041114
|
@ -34,6 +34,8 @@ bugs were never in fully released code, but are noted here for the record.
|
||||||
(d) Captures in negative assertions that were used as conditions were not
|
(d) Captures in negative assertions that were used as conditions were not
|
||||||
happening if the assertion matched via (*ACCEPT).
|
happening if the assertion matched via (*ACCEPT).
|
||||||
|
|
||||||
|
(e) Mark values were not being passed out of recursions.
|
||||||
|
|
||||||
2. Now that pcre2_match() no longer uses recursive function calls (see above),
|
2. Now that pcre2_match() no longer uses recursive function calls (see above),
|
||||||
the "match limit recursion" value seems misnamed. It still exists, and limits
|
the "match limit recursion" value seems misnamed. It still exists, and limits
|
||||||
the depth of tree that is searched. To avoid future confusion, it has been
|
the depth of tree that is searched. To avoid future confusion, it has been
|
||||||
|
|
|
@ -725,7 +725,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||||
where we know the starting frame is at the top of the chained frames, in
|
where we know the starting frame is at the top of the chained frames, in
|
||||||
this case we have to search back for the relevant frame in case other types
|
this case we have to search back for the relevant frame in case other types
|
||||||
of group that use chained frames have intervened. Multiple OP_CLOSEs always
|
of group that use chained frames have intervened. Multiple OP_CLOSEs always
|
||||||
come innermost first, which matches the chain order. */
|
come innermost first, which matches the chain order. We can ignore this in
|
||||||
|
a recursion, because captures are not passed out of recursions. */
|
||||||
|
|
||||||
case OP_CLOSE:
|
case OP_CLOSE:
|
||||||
if (Fcurrent_recurse == RECURSE_UNSET)
|
if (Fcurrent_recurse == RECURSE_UNSET)
|
||||||
|
@ -746,23 +747,21 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||||
Fovector[offset+1] = Feptr - mb->start_subject;
|
Fovector[offset+1] = Feptr - mb->start_subject;
|
||||||
if (offset >= Foffset_top) Foffset_top = offset + 2;
|
if (offset >= Foffset_top) Foffset_top = offset + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fecode += PRIV(OP_lengths)[*Fecode];
|
Fecode += PRIV(OP_lengths)[*Fecode];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
/* ===================================================================== */
|
/* ===================================================================== */
|
||||||
/* End of the pattern, either real or forced. In an assertion ACCEPT,
|
/* Real or forced end of the pattern, assertion, or recursion. In an
|
||||||
update the last used pointer and remember the current frame so that the
|
assertion ACCEPT, update the last used pointer and remember the current
|
||||||
captures can be fished out of it. */
|
frame so that the captures can be fished out of it. */
|
||||||
|
|
||||||
case OP_ASSERT_ACCEPT:
|
case OP_ASSERT_ACCEPT:
|
||||||
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
|
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
|
||||||
assert_accept_frame = F;
|
assert_accept_frame = F;
|
||||||
RRETURN(MATCH_ACCEPT);
|
RRETURN(MATCH_ACCEPT);
|
||||||
|
|
||||||
/* The real end, or top-level (*ACCEPT). If recursing, we have to find the
|
/* If recursing, we have to find the most recent recursion. */
|
||||||
most recent recursion. */
|
|
||||||
|
|
||||||
case OP_ACCEPT:
|
case OP_ACCEPT:
|
||||||
case OP_END:
|
case OP_END:
|
||||||
|
@ -782,10 +781,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* N is now the frame of the recursion; the previous frame is at the
|
/* N is now the frame of the recursion; the previous frame is at the
|
||||||
OP_RECURSE position. Go back there, copying the current subject position,
|
OP_RECURSE position. Go back there, copying the current subject position
|
||||||
and move on past the OP_RECURSE. */
|
and mark, and move on past the OP_RECURSE. */
|
||||||
|
|
||||||
P->eptr = Feptr;
|
P->eptr = Feptr;
|
||||||
|
P->mark = Fmark;
|
||||||
F = P;
|
F = P;
|
||||||
Fecode += 1 + LINK_SIZE;
|
Fecode += 1 + LINK_SIZE;
|
||||||
continue;
|
continue;
|
||||||
|
@ -5078,10 +5078,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now run the recursion. If it successfully completes, it re-instates the
|
/* Now run the recursion, branch by branch. */
|
||||||
previous values of the captures and continues, just like a non-capturing
|
|
||||||
bracket. We must leave Fecode unchanged so that the ending code can find
|
|
||||||
out where to continue. */
|
|
||||||
|
|
||||||
Lstart_branch = bracode;
|
Lstart_branch = bracode;
|
||||||
Lframe_type = GF_RECURSE | number;
|
Lframe_type = GF_RECURSE | number;
|
||||||
|
|
|
@ -5005,5 +5005,10 @@ a)"xI
|
||||||
/^ (?(DEFINE) (..(*ACCEPT)|...) ) (?1)$/x
|
/^ (?(DEFINE) (..(*ACCEPT)|...) ) (?1)$/x
|
||||||
\= Expect no match
|
\= Expect no match
|
||||||
abc
|
abc
|
||||||
|
|
||||||
|
# Perl gives no match for this one
|
||||||
|
|
||||||
|
/(a(*MARK:m)(*ACCEPT)){0}(?1)/mark
|
||||||
|
abc
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
|
@ -15529,6 +15529,13 @@ Callout 1: last capture = 1
|
||||||
\= Expect no match
|
\= Expect no match
|
||||||
abc
|
abc
|
||||||
No match
|
No match
|
||||||
|
|
||||||
|
# Perl gives no match for this one
|
||||||
|
|
||||||
|
/(a(*MARK:m)(*ACCEPT)){0}(?1)/mark
|
||||||
|
abc
|
||||||
|
0: a
|
||||||
|
MK: m
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
Error -63: PCRE2_ERROR_BADDATA (unknown error number)
|
Error -63: PCRE2_ERROR_BADDATA (unknown error number)
|
||||||
|
|
Loading…
Reference in New Issue