diff options
-rw-r--r-- | pp.c | 4 | ||||
-rw-r--r-- | pp_hot.c | 4 | ||||
-rw-r--r-- | t/op/array.t | 14 | ||||
-rw-r--r-- | t/op/hash.t | 11 |
4 files changed, 25 insertions, 8 deletions
@@ -970,10 +970,10 @@ PP(pp_undef) case SVt_NULL: break; case SVt_PVAV: - av_undef(MUTABLE_AV(sv)); + av_undef(MUTABLE_AV(sv_2mortal(SvREFCNT_inc_simple_NN(sv)))); break; case SVt_PVHV: - hv_undef(MUTABLE_HV(sv)); + hv_undef(MUTABLE_HV(sv_2mortal(SvREFCNT_inc_simple_NN(sv)))); break; case SVt_PVCV: if (cv_const_sv((const CV *)sv)) @@ -993,7 +993,7 @@ PP(pp_aassign) sv = *lelem++; switch (SvTYPE(sv)) { case SVt_PVAV: - ary = MUTABLE_AV(sv); + ary = MUTABLE_AV(sv_2mortal(SvREFCNT_inc_simple_NN(sv))); magic = SvMAGICAL(ary) != 0; av_clear(ary); av_extend(ary, lastrelem - relem); @@ -1020,7 +1020,7 @@ PP(pp_aassign) SV *tmpstr; SV** topelem = relem; - hash = MUTABLE_HV(sv); + hash = MUTABLE_HV(sv_2mortal(SvREFCNT_inc_simple_NN(sv))); magic = SvMAGICAL(hash) != 0; hv_clear(hash); firsthashrelem = relem; 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"; diff --git a/t/op/hash.t b/t/op/hash.t index 1e8c6b296c..ef757a3bc1 100644 --- a/t/op/hash.t +++ b/t/op/hash.t @@ -8,7 +8,7 @@ BEGIN { use strict; -plan tests => 13; +plan tests => 15; my %h; @@ -208,3 +208,12 @@ SKIP: { } is $ref, undef, 'weak refs to pad hashes go stale on scope exit'; } + +# [perl #107440] +sub A::DESTROY { $::ra = 0 } +$::ra = {a=>bless [], 'A'}; +undef %$::ra; +pass 'no crash when freeing hash that is being undeffed'; +$::ra = {a=>bless [], 'A'}; +%$::ra = ('a'..'z'); +pass 'no crash when freeing hash that is being exonerated, ahem, cleared'; |