Null HeVAL and local delete → crash
authorFather Chrysostomos <sprout@cpan.org>
Wed, 27 Jun 2012 03:21:29 +0000 (20:21 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 27 Jun 2012 07:51:45 +0000 (00:51 -0700)
The XS API allows hash entries to be created with null values.  perl
itself uses these internally, too.

Though they should rarely be seen by Perl code, Perl ops should still
be able to handle them without crashing (by croaking).  I fixed helem
and hslice in 5.16 (commit 746f6409), but missed localised deletions.

ext/XS-APItest/t/hash.t
pp.c

index 84b6274..9e27af8 100644 (file)
@@ -258,6 +258,10 @@ sub test_precomputed_hashes {
          warnings; # thank you!
          @h{85} = 1 };
     pass 'no crash when writing to hash elem with null value via slice';
+    eval { delete local $h{86} };
+    pass 'no crash during local deletion of hash elem with null value';
+    eval { delete local @h{87,88} };
+    pass 'no crash during local deletion of hash slice with null values';
 }
 
 # [perl #111000] Bug number eleventy-one thousand:
diff --git a/pp.c b/pp.c
index 99ff027..82f7105 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -4453,6 +4453,7 @@ S_do_delete_local(pTHX)
                    SvREFCNT_inc_simple_void(sv); /* De-mortalize */
                }
                if (preeminent) {
+                   if (!sv) DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
                    save_helem_flags(hv, keysv, &sv, SAVEf_KEEPOLDELEM);
                    if (tied) {
                        *MARK = sv_mortalcopy(sv);
@@ -4539,6 +4540,7 @@ S_do_delete_local(pTHX)
                SvREFCNT_inc_simple_void(sv); /* De-mortalize */
            }
            if (preeminent) {
+               if (!sv) DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
                save_helem_flags(hv, keysv, &sv, SAVEf_KEEPOLDELEM);
                if (tied) {
                    SV *nsv = sv_mortalcopy(sv);