This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #27638] scope exit could expose freed local() value
authorDave Mitchell <davem@fdisolutions.com>
Sun, 14 Mar 2004 20:13:47 +0000 (20:13 +0000)
committerDave Mitchell <davem@fdisolutions.com>
Sun, 14 Mar 2004 20:13:47 +0000 (20:13 +0000)
p4raw-id: //depot/perl@22500

scope.c
t/op/localref.t

diff --git a/scope.c b/scope.c
index 2c2ce36..2491150 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -782,8 +782,8 @@ Perl_leave_scope(pTHX_ I32 base)
                 * mg_get() in save_scalar_at() croaked */
                SvMAGIC(value) = 0;
            }
-           SvREFCNT_dec(sv);
            *(SV**)ptr = value;
+           SvREFCNT_dec(sv);
            PL_localizing = 2;
            SvSETMAGIC(value);
            PL_localizing = 0;
index 9379575..3f49344 100644 (file)
@@ -3,7 +3,7 @@
 chdir 't' if -d 't';
 @INC = qw(. ../lib);
 require "test.pl";
-plan( tests => 63 );
+plan( tests => 64 );
 
 $aa = 1;
 { local $aa;     $aa = 2; is($aa,2); }
@@ -83,3 +83,17 @@ eval { local %$y; };      test_err_localref;
 eval { local %{$y}; };    test_err_localref;
 eval { local %{\%aa}; };  test_err_localref;
 eval { local %{{a=>1}}; };test_err_localref;
+
+
+{
+    # [perl #27638] when restoring a localized variable, the thing being
+    # freed shouldn't be visible
+    my $ok;
+    $x = 0;
+    sub X::DESTROY { $ok = !ref($x); }
+    {
+       local $x = \ bless {}, 'X';
+       1;
+    }
+ok($ok,'old value not visible during restore');
+}