diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-01-06 13:50:35 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-01-06 13:50:35 -0800 |
commit | 9f71cfe6ef2a57e26394d4caf1bf2894802f4777 (patch) | |
tree | 55b4e2aa0dc91477963674d95f1aa6f9ab1f5236 /t/op/array.t | |
parent | bd4675851936488a7b28a813c5b60248be3e733b (diff) | |
download | perl-9f71cfe6ef2a57e26394d4caf1bf2894802f4777.tar.gz |
[perl #107440] Save av/hv on mortals stack when clearing
In pp_undef and pp_aassign, we should put the av or hv that is being
cleared on the mortals stack (with an increased refcount), so that
destructors fired during the clearing do not free the av or hv.
I was going to put this in av_undef, etc., but pp_aassign also needs
to access the aggregate after clearing it. We still get a crash with
that approach.
Putting the aggregate on the mortals stack in av_undef, av_clear and
h_freeentries would work, too, but might cause the aggregate to leak
too far. That may cause problems, e.g., if it is %^H, because it may
last until the end of the current compilation unit.
Directly inside a runloop (in a pp function), it should be OK to use
the mortals stack, as it *will* be cleared ‘soon’. This seems the
least intrusive approach.
Diffstat (limited to 't/op/array.t')
-rw-r--r-- | t/op/array.t | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/t/op/array.t b/t/op/array.t index b53da80424..233af19097 100644 --- a/t/op/array.t +++ b/t/op/array.t @@ -3,11 +3,10 @@ BEGIN { chdir 't' if -d 't'; @INC = ('.', '../lib'); + require 'test.pl'; } -require 'test.pl'; - -plan (123); +plan (125); # # @foo, @bar, and @ary are also used from tie-stdarray after tie-ing them @@ -441,4 +440,13 @@ sub test_arylen { *trit = *scile; $trit[0]; ok(1, 'aelem_fast on a nonexistent array does not crash'); +# [perl #107440] +sub A::DESTROY { $::ra = 0 } +$::ra = [ bless [], 'A' ]; +undef @$::ra; +pass 'no crash when freeing array that is being undeffed'; +$::ra = [ bless [], 'A' ]; +@$::ra = ('a'..'z'); +pass 'no crash when freeing array that is being cleared'; + "We're included by lib/Tie/Array/std.t so we need to return something true"; |