diff options
author | Yves Orton <demerphq@gmail.com> | 2011-03-12 17:21:54 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2011-03-12 17:44:33 +0100 |
commit | 92e82afa16f5f1aa1b3e163f6d4656d14c44a4d2 (patch) | |
tree | dfa390236bc22ee6e20dc9cb22912bf6b645b83e /regexec.c | |
parent | d774cd11ba563c66e3199abfc3061bdc88e980e0 (diff) | |
download | perl-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.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -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; |