Resolve
Yves Orton [Sat, 23 Jun 2007 19:04:04 +0000 (19:04 +0000)]
http://www.nntp.perl.org/group/perl.perl5.porters/2007/06/msg125667.html
by reverting part of change #29354.

Unfortunately match vars after a /g match in scalar context will be
unsafe (again) after this, but such matches on long strings won't be
as diabolically slow.

Question: why does the new test in t/op/pat.t pass, but the same test
in t/op/reg_unsafe.t fail? (Latter is TODO for now)
p4raw-link: @29354 on //depot/perl: 58e23c8d7d24dd08c87b5d56819ad45527176c15

p4raw-id: //depot/perl@31451

MANIFEST
pp_hot.c
t/op/pat.t
t/op/reg_unsafe.t [new file with mode: 0644]

index dafce23..f922144 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -3761,6 +3761,7 @@ t/op/regexp_qr.t          See if regular expressions work as qr//
 t/op/regexp.t                  See if regular expressions work
 t/op/regexp_trielist.t         See if regular expressions work with trie optimisation
 t/op/regmesg.t                 See if one can get regular expression errors
+t/op/reg_unsafe.t              Check for unsafe match vars
 t/op/repeat.t                  See if x operator works
 t/op/reset.t                   See if reset operator works
 t/op/re_tests                  Regular expressions for regexp.t
index 27e863d..1535e4c 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1266,9 +1266,12 @@ PP(pp_match)
            }
        }
     }
-    /* remove comment to get faster /g but possibly unsafe $1 vars after a
-       match. Test for the unsafe vars will fail as well*/
-    if (( /* !global &&  */ rx->nparens) 
+    /* XXX: comment out !global get safe $1 vars after a
+       match, BUT be aware that this leads to drammatic slowdowns on
+       /g matches against large strings.  So far a solution to this problem
+       appears to be quite tricky.
+       Test for the unsafe vars are TODO for now. */
+    if ((  !global &&  rx->nparens) 
            || SvTEMP(TARG) || PL_sawampersand ||
            (rx->extflags & (RXf_EVAL_SEEN|RXf_PMf_KEEPCOPY)))
        r_flags |= REXEC_COPY_STR;
index 856d3ac..f40154e 100755 (executable)
@@ -4453,7 +4453,12 @@ sub kt
         if 'foo'=~/(?<x>foo)|bar/;
     iseq($ok,1,'$+{x} exists after "foo"=~/(?<x>foo)|bar/');
 }
-
+{
+    local $_;
+    ($_ = 'abc')=~/(abc)/g;
+    $_ = '123'; 
+    iseq("$1",'abc',"/g leads to unsafe match vars: $1");
+}
 
 # Test counter is at bottom of file. Put new tests above here.
 #-------------------------------------------------------------------
@@ -4504,6 +4509,6 @@ ok($@=~/\QSequence \k... not terminated in regex;\E/);
 iseq(0+$::test,$::TestCount,"Got the right number of tests!");
 # Don't forget to update this!
 BEGIN {
-    $::TestCount = 1960;
+    $::TestCount = 1961;
     print "1..$::TestCount\n";
 }
diff --git a/t/op/reg_unsafe.t b/t/op/reg_unsafe.t
new file mode 100644 (file)
index 0000000..6b19108
--- /dev/null
@@ -0,0 +1,19 @@
+#!./perl
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = '../lib';
+    
+}
+print "1..1\n";
+
+# there is an equivelent test in t/op/pat.t which does NOT fail
+# its not clear why it doesnt fail, so this todo gets its own test
+# file until we can work it out.
+
+my $x; 
+($x='abc')=~/(abc)/g; 
+$x='123'; 
+
+print "not " if $1 ne 'abc';
+print "ok 1 # TODO safe match vars make /g slow\n";