summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp.c4
-rw-r--r--pp_hot.c4
-rw-r--r--t/op/array.t14
-rw-r--r--t/op/hash.t11
4 files changed, 25 insertions, 8 deletions
diff --git a/pp.c b/pp.c
index eaf6a85277..5910e8691d 100644
--- a/pp.c
+++ b/pp.c
@@ -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))
diff --git a/pp_hot.c b/pp_hot.c
index ec7674ea85..add940049b 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -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';