This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Don’t leak deleted iterator when tying hash
authorFather Chrysostomos <sprout@cpan.org>
Sat, 22 Sep 2012 01:23:20 +0000 (18:23 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 23 Sep 2012 00:10:43 +0000 (17:10 -0700)
pp_sys.c
t/op/tie.t

index 2a7f43e..a41c6d1 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -861,9 +861,16 @@ PP(pp_tie)
 
     switch(SvTYPE(varsv)) {
        case SVt_PVHV:
+       {
+           HE *entry;
            methname = "TIEHASH";
+           if (HvLAZYDEL(varsv) && (entry = HvEITER((HV *)varsv))) {
+               HvLAZYDEL_off(varsv);
+               hv_free_ent((HV *)varsv, entry);
+           }
            HvEITER_set(MUTABLE_HV(varsv), 0);
            break;
+       }
        case SVt_PVAV:
            methname = "TIEARRAY";
            if (!AvREAL(varsv)) {
index a997c41..5808a09 100644 (file)
@@ -1289,4 +1289,16 @@ untie @a;
 
 sub T::TIEARRAY { my $s; bless \$s => "T" }
 EXPECT
+########
 
+# NAME Test that tying a hash does not leak a deleted iterator
+# This produced unbalanced string table warnings under
+# PERL_DESTRUCT_LEVEL=2.
+package l {
+    sub TIEHASH{bless[]}
+}
+$h = {foo=>0};
+each %$h;
+delete $$h{foo};
+tie %$h, 'l';
+EXPECT