Fix compiling regular expressions that contain both compile- and run-time compiled code blocks
This commit is contained in:
parent
45b1f54fc1
commit
bfd9d6a2ae
118
perl-5.29.5-handle-code-mixed-compile-and-runtime.patch
Normal file
118
perl-5.29.5-handle-code-mixed-compile-and-runtime.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From 278d8c58e85c646b61e60fe48207e090278bb61c Mon Sep 17 00:00:00 2001
|
||||
From: David Mitchell <davem@iabyn.com>
|
||||
Date: Tue, 27 Nov 2018 13:26:39 +0000
|
||||
Subject: [PATCH] handle /(?(?{code}))/ mixed compile-and runtime
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Where a runtime pattern contains both compile-time and run-time code
|
||||
blocks, e.g.:
|
||||
|
||||
$re = '(?{ RRR })';
|
||||
/ $re X(?{ CCC })Y/
|
||||
|
||||
The compile-time code-block CCC is parsed at the same time as the
|
||||
surrounding text. The runtime code RRR is parsed at runtime by
|
||||
constructing a fake pattern and re-parsing it, but with any compile-time
|
||||
code-blocks blanked out (so they don't get compiled twice). The compiled
|
||||
regex is then thrown away, but any optrees just created for the runtime
|
||||
code blocks are kept.
|
||||
|
||||
For example at runtime, the re-parsed pattern looks like:
|
||||
|
||||
/ (?{ RRR }) X__________Y/
|
||||
|
||||
Unfortunately this was failing for the conditional pattern, e.g.
|
||||
|
||||
/ $re X(?(?{ CCC }))Y/
|
||||
|
||||
which was getting blanked as
|
||||
|
||||
/ (?{ RRR }) X(?_______)Y/
|
||||
|
||||
which isn't valid syntax.
|
||||
|
||||
This commit blanks (?{...}) into (?=====) instead which is always legal.
|
||||
|
||||
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||||
---
|
||||
regcomp.c | 24 +++++++++++++++++++-----
|
||||
t/re/pat_re_eval.t | 17 ++++++++++++++++-
|
||||
2 files changed, 35 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/regcomp.c b/regcomp.c
|
||||
index bf987f6e28..ff26f2242f 100644
|
||||
--- a/regcomp.c
|
||||
+++ b/regcomp.c
|
||||
@@ -6756,13 +6756,27 @@ S_compile_runtime_code(pTHX_ RExC_state_t * const pRExC_state,
|
||||
&& n < pRExC_state->code_blocks->count
|
||||
&& s == pRExC_state->code_blocks->cb[n].start)
|
||||
{
|
||||
- /* blank out literal code block */
|
||||
- assert(pat[s] == '(');
|
||||
- while (s <= pRExC_state->code_blocks->cb[n].end) {
|
||||
- *p++ = '_';
|
||||
+ /* blank out literal code block so that they aren't
|
||||
+ * recompiled: eg change from/to:
|
||||
+ * /(?{xyz})/
|
||||
+ * /(?=====)/
|
||||
+ * and
|
||||
+ * /(??{xyz})/
|
||||
+ * /(?======)/
|
||||
+ * and
|
||||
+ * /(?(?{xyz}))/
|
||||
+ * /(?(?=====))/
|
||||
+ */
|
||||
+ assert(pat[s] == '(');
|
||||
+ assert(pat[s+1] == '?');
|
||||
+ *p++ = '(';
|
||||
+ *p++ = '?';
|
||||
+ s += 2;
|
||||
+ while (s < pRExC_state->code_blocks->cb[n].end) {
|
||||
+ *p++ = '=';
|
||||
s++;
|
||||
}
|
||||
- s--;
|
||||
+ *p++ = ')';
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
diff --git a/t/re/pat_re_eval.t b/t/re/pat_re_eval.t
|
||||
index f88a8651a1..8325451377 100644
|
||||
--- a/t/re/pat_re_eval.t
|
||||
+++ b/t/re/pat_re_eval.t
|
||||
@@ -23,7 +23,7 @@ BEGIN {
|
||||
|
||||
our @global;
|
||||
|
||||
-plan tests => 502; # Update this when adding/deleting tests.
|
||||
+plan tests => 504; # Update this when adding/deleting tests.
|
||||
|
||||
run_tests() unless caller;
|
||||
|
||||
@@ -1301,6 +1301,21 @@ sub run_tests {
|
||||
ok /^$qr$/, "RT #132772 - run time time qr//";
|
||||
}
|
||||
|
||||
+ # RT #133687
|
||||
+ # mixing compile-time (?(?{code})) with run-time code blocks
|
||||
+ # was failing, because the second pass through the parser
|
||||
+ # (which compiles the runtime code blocks) was failing to adequately
|
||||
+ # mask the compile-time code blocks to shield them from a second
|
||||
+ # compile: /X(?{...})Y/ was being correctly masked as /X________Y/
|
||||
+ # but /X(?(?{...}))Y/ was being incorrectly masked as
|
||||
+ # /X(?________)Y/
|
||||
+
|
||||
+ {
|
||||
+ use re 'eval';
|
||||
+ my $runtime_re = '(??{ "A"; })';
|
||||
+ ok "ABC" =~ /^ $runtime_re (?(?{ 1; })BC) $/x, 'RT #133687 yes';
|
||||
+ ok "ABC" =~ /^ $runtime_re (?(?{ 0; })xy|BC) $/x, 'RT #133687 yes|no';
|
||||
+ }
|
||||
|
||||
} # End of sub run_tests
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -211,6 +211,10 @@ Patch35: perl-5.29.5-perl-133659-move-argvout-cleanup-to-a-new-function.p
|
||||
Patch36: perl-5.29.5-perl-133659-tests-for-global-destruction-handling-of.patch
|
||||
Patch37: perl-5.29.5-perl-133659-make-an-in-place-edit-successful-if-the-.patch
|
||||
|
||||
# Fix compiling regular expressions that contain both compile- and run-time
|
||||
# compiled code blocks, RT#133687, in upstream after 5.29.5
|
||||
Patch38: perl-5.29.5-handle-code-mixed-compile-and-runtime.patch
|
||||
|
||||
# Link XS modules to libperl.so with EU::CBuilder on Linux, bug #960048
|
||||
Patch200: perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch
|
||||
|
||||
@ -2799,6 +2803,7 @@ Perl extension for Version Objects
|
||||
%patch35 -p1
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
%patch38 -p1
|
||||
%patch200 -p1
|
||||
%patch201 -p1
|
||||
|
||||
@ -2835,6 +2840,7 @@ perl -x patchlevel.h \
|
||||
'Fedora Patch33: Fix PathTools tests to cope with ESTALE error (RT#133534)' \
|
||||
'Fedora Patch34: Fix an undefined behaviour in S_hv_delete_common()' \
|
||||
'Fedora Patch35: Fix in-place edit to replace files on a successful perl exit status (bug #1650041)' \
|
||||
'Fedora Patch38: Fix compiling regular expressions that contain both compile- and run-time compiled code blocks (RT#133687)' \
|
||||
'Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux' \
|
||||
'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \
|
||||
%{nil}
|
||||
@ -5130,6 +5136,8 @@ popd
|
||||
- Fix an undefined behaviour in S_hv_delete_common()
|
||||
- Fix in-place edit to replace files on a successful perl exit status
|
||||
(bug #1650041)
|
||||
- Fix compiling regular expressions that contain both compile- and run-time
|
||||
compiled code blocks (RT#133687)
|
||||
|
||||
* Fri Nov 30 2018 Jitka Plesnikova <jplesnik@redhat.com> - 4:5.28.1-426
|
||||
- 5.28.1 bump
|
||||
|
Loading…
Reference in New Issue
Block a user