69 lines
2.3 KiB
Diff
69 lines
2.3 KiB
Diff
|
From f5df269c5cef57294662d0b1f80a468b91f13643 Mon Sep 17 00:00:00 2001
|
|||
|
From: Father Chrysostomos <sprout@cpan.org>
|
|||
|
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
|
|||
|
|