This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Copy RE capture buf on overload as well as TEMP
authorDavid Mitchell <davem@iabyn.com>
Wed, 1 Sep 2010 15:59:03 +0000 (16:59 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 1 Sep 2010 16:08:46 +0000 (17:08 +0100)
Partial fix for [perl #77084]. Sometimes pp_match makes a copy of the
original SV's string for the later use of $1 et al; in particular if the
SV is TEMP (so will soon go away).

Make it do the same if the SV is overloaded, as the string return is most
certainly temporary!

(Also tweak the tests to make them more likely to fail on badness by
creating new stings that will likely reallocate freed buffer).

pp_hot.c
t/re/overload.t

index 02f425a..25a804a 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1336,7 +1336,7 @@ PP(pp_match)
        appears to be quite tricky.
        Test for the unsafe vars are TODO for now. */
     if ((  !global && RX_NPARENS(rx)) 
-           || SvTEMP(TARG) || PL_sawampersand ||
+           || SvTEMP(TARG) || SvAMAGIC(TARG) || PL_sawampersand ||
            (RX_EXTFLAGS(rx) & (RXf_EVAL_SEEN|RXf_PMf_KEEPCOPY)))
        r_flags |= REXEC_COPY_STR;
     if (SvSCREAM(TARG))
index 46407ae..d16aec1 100644 (file)
@@ -19,19 +19,24 @@ plan tests => 3;
     # Bug #77084 points out a corruption problem when scalar //g is used
     # on overloaded objects.
 
+    my @realloc;
     my $TAG = "foo:bar";
     use overload '""' => sub {$TAG};
 
     my $o = bless [];
     my ($one) = $o =~ /(.*)/g;
+    push @realloc, "xxxxxx"; # encourage realloc of SV and PVX
     is $one, $TAG, "list context //g against overloaded object";
 
-    local our $TODO = "Bug #77084";
 
     my $r = $o =~ /(.*)/g;
+    push @realloc, "yyyyyy"; # encourage realloc of SV and PVX
     is $1, $TAG, "scalar context //g against overloaded object";
 
+    local our $TODO = "Bug #77084";
+
     $o =~ /(.*)/g;
+    push @realloc, "zzzzzz"; # encourage realloc of SV and PVX
     is $1, $TAG, "void context //g against overloaded object";
 }