From f5df269c5cef57294662d0b1f80a468b91f13643 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Fri, 5 Jul 2013 23:59:46 -0700 Subject: [PATCH] [perl #117917] /(?{ m|...| }) (?{ $1 })/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 1 + t/re/re_tests | 2 ++ 2 files changed, 3 insertions(+) diff --git a/regexec.c b/regexec.c index 12548d5..6367e2e 100644 --- a/regexec.c +++ b/regexec.c @@ -4991,6 +4991,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog) PL_curcop = ocurcop; PL_regeol = saved_regeol; S_regcp_restore(aTHX_ rex, runops_cp, &maxopenparen); + PL_curpm = PL_reg_curpm; if (logical != 2) break; diff --git a/t/re/re_tests b/t/re/re_tests index 9a24360..3921bb7 100644 --- a/t/re/re_tests +++ b/t/re/re_tests @@ -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 :[ -- 1.8.3.1