From 8fe3c67a9d33417c317107b8f5a56ca88d4153a9 Mon Sep 17 00:00:00 2001 From: Yves Orton Date: Sun, 16 Sep 2012 14:25:02 +0200 Subject: [PATCH] fix 114884 positive GPOS lookbehind regex substitution failure This also corrects a test added in 2c2969659ae1c534e7f3fac9e7a7d186defd9943 which was arguably wrong. The details of \G are a bit fuzzy, and IMO its a little hard to say exactly what is right, although it generally is clear what is wrong. --- pp_ctl.c | 9 +++++---- t/re/subst.t | 10 +++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/pp_ctl.c b/pp_ctl.c index 17121be..5c6999b 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -226,12 +226,13 @@ PP(pp_substcont) if (SvTAINTED(TOPs)) cx->sb_rxtainted |= SUBST_TAINT_REPL; sv_catsv_nomg(dstr, POPs); - /* XXX: adjust for positive offsets of \G for instance s/(.)\G//g with positive pos() */ - s -= RX_GOFS(rx); - + /* XXX: the RX_GOFS stuff is to adjust for positive offsets of + * \G for instance s/(.)\G//g with positive pos(). See #69056 and #114884 + * This whole \G thing makes a *lot* of things more difficult than they + * should be. - Yves */ /* Are we done */ if (CxONCE(cx) || s < orig || - !CALLREGEXEC(rx, s, cx->sb_strend, orig, + !CALLREGEXEC(rx, s - RX_GOFS(rx), cx->sb_strend, orig, (s == m) + RX_GOFS(rx), cx->sb_targ, NULL, (REXEC_IGNOREPOS|REXEC_NOT_FIRST))) { diff --git a/t/re/subst.t b/t/re/subst.t index c1e0d03..bbc3a83 100644 --- a/t/re/subst.t +++ b/t/re/subst.t @@ -7,7 +7,7 @@ BEGIN { require './test.pl'; } -plan( tests => 206 ); +plan( tests => 207 ); $_ = 'david'; $a = s/david/rules/r; @@ -668,8 +668,12 @@ is($name, "cis", q[#22351 bug with 'e' substitution modifier]); } } -fresh_perl_is( '$_=q(foo);s/(.)\G//g;print' => 'foo', '[perl #69056] positive GPOS regex segfault' ); -fresh_perl_is( '$_="abcef"; s/bc|(.)\G(.)/$1 ? "[$1-$2]" : "XX"/ge; print' => 'aXX[c-e][e-f]f', 'positive GPOS regex substitution failure' ); +fresh_perl_is( '$_=q(foo);s/(.)\G//g;print' => 'foo', + '[perl #69056] positive GPOS regex segfault' ); +fresh_perl_is( '$_="abcdef"; s/bc|(.)\G(.)/$1 ? "[$1-$2]" : "XX"/ge; print' => 'aXX[c-d][d-e][e-f]', + 'positive GPOS regex substitution failure (#69056, #114884)' ); +fresh_perl_is( '$_="abcdefg123456"; s/(?<=...\G)?(\d)/($1)/; print' => 'abcdefg(1)23456', + 'positive GPOS lookbehind regex substitution failure #114884' ); # [perl #71470] $var =~ s/$qr//e calling get-magic on $_ as well as $var { -- 2.7.4