This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #117917] /(?{ m|...| }) (?{ $1 })/
authorFather Chrysostomos <sprout@cpan.org>
Sat, 6 Jul 2013 06:59:46 +0000 (23:59 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 6 Jul 2013 13:47:24 +0000 (06:47 -0700)
A regular expression invoked inside a regular expression code block
can cause other code blocks in the same outer regular expression to
see the wrong values in $1.

PL_curpm holds a pointer to the match operator from which $1, $2, etc.
get their values.

Normally PL_curpm is set at the end of a match.

When code blocks are embedded inside a regular expression, PL_curpm
is set during a match to point to PL_reg_curpm, which is a dummy op
pointing to the current regular expression.

S_setup_eval_state is called at the beginning of regexp execution.
It is responsible for setting up PL_regcurpm and making PL_curpm
point to it.

Code blocks are executed using the multicall API.  PUSH_MULTICALL
records the value of PL_curpm and POP_MULTICALL makes sure that the
previous value of PL_curpm is restored.

Executing a code block can cause PL_curpm to point to something else.
Since we don’t necessarily do POP_MULTICALL between code block calls
within a single regular expression (sometimes we do, depending on
backtracking), PL_curpm may not have been restored when a second code
block fires.  So we have to restore it to point to PL_reg_curpm manu-
ally after calling a code block.

regexec.c
t/re/re_tests

index 12548d5..6367e2e 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -4991,6 +4991,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                PL_op = oop;
                PL_curcop = ocurcop;
                S_regcp_restore(aTHX_ rex, runops_cp, &maxopenparen);
+               PL_curpm = PL_reg_curpm;
 
                if (logical != 2)
                    break;
index 9a24360..3921bb7 100644 (file)
@@ -613,6 +613,8 @@ $(?<=^(a))  a       y       $1      a
 ^[^bcd]*(c+)   aexycd  y       $1      c
 (?{$a=2})a*aa(?{local$a=$a+1})k*c(?{$b=$a})    yaaxxaaaacd     y       $b      3
 (?{$a=2})(a(?{local$a=$a+1}))*aak*c(?{$b=$a})  yaaxxaaaacd     y       $b      4
+# [perl #117917]
+^(a(?{ "x" =~ m{x}})b)(??{ $1 })       abab    y       $&      abab
 (>a+)ab        aaab    n       -       -
 (?>a+)b        aaab    y       -       -
 ([[:]+)        a:[b]:  y       $1      :[