summaryrefslogtreecommitdiff
path: root/t/op/array.t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-01-06 13:50:35 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-01-06 13:50:35 -0800
commit9f71cfe6ef2a57e26394d4caf1bf2894802f4777 (patch)
tree55b4e2aa0dc91477963674d95f1aa6f9ab1f5236 /t/op/array.t
parentbd4675851936488a7b28a813c5b60248be3e733b (diff)
downloadperl-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.t14
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";