summaryrefslogtreecommitdiff
path: root/regexec.c
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2011-03-12 17:21:54 +0100
committerYves Orton <demerphq@gmail.com>2011-03-12 17:44:33 +0100
commit92e82afa16f5f1aa1b3e163f6d4656d14c44a4d2 (patch)
treedfa390236bc22ee6e20dc9cb22912bf6b645b83e /regexec.c
parentd774cd11ba563c66e3199abfc3061bdc88e980e0 (diff)
downloadperl-92e82afa16f5f1aa1b3e163f6d4656d14c44a4d2.tar.gz
Fix RT #84294 /((\w+)(?{print $2})){2,2}/ problem
When we are doing a CURLYX/WHILEM loop and the min iterations is larger than zero we were not saving the buffer state before each iteration. This mean that partial matches would end up with strange buffer pointers, with the start *after* the end point. In more detail WHILEM has four exits, three of which as far as I could tell would do a regcppush/regcppop in their state transitions, only one, WHILEM_A_pre which is entered when (n < min) would not. And it is this state that we repeatedly enter when performing A the min number of times. When I made the logic similar to the handling of ( n < max ), the bug went away, and as far as I can tell nothing else broke. Review by Dave Mitchell required before release.
Diffstat (limited to 'regexec.c')
-rw-r--r--regexec.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/regexec.c b/regexec.c
index 8486646854..eb5e346d74 100644
--- a/regexec.c
+++ b/regexec.c
@@ -4648,7 +4648,10 @@ NULL
/* First just match a string of min A's. */
if (n < min) {
+ ST.cp = regcppush(cur_curlyx->u.curlyx.parenfloor);
cur_curlyx->u.curlyx.lastloc = locinput;
+ REGCP_SET(ST.lastcp);
+
PUSH_STATE_GOTO(WHILEM_A_pre, A);
/* NOTREACHED */
}
@@ -4754,10 +4757,10 @@ NULL
/* NOTREACHED */
case WHILEM_A_min_fail: /* just failed to match A in a minimal match */
- REGCP_UNWIND(ST.lastcp);
- regcppop(rex);
/* FALL THROUGH */
case WHILEM_A_pre_fail: /* just failed to match even minimal A */
+ REGCP_UNWIND(ST.lastcp);
+ regcppop(rex);
cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
cur_curlyx->u.curlyx.count--;
CACHEsayNO;