summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-09-23 12:42:15 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-09-23 18:29:33 -0700
commit0db511c03fa45894d146905ba3408b3be3f5baa0 (patch)
tree837511055c3fc3642b425a28d566267fd20f9211 /hv.c
parent518618af9da07b079c1585df2b7c76a1aed0f19c (diff)
downloadperl-0db511c03fa45894d146905ba3408b3be3f5baa0.tar.gz
[perl #107000] Don’t leak if hh copying dies
When %^H is copied on entering a new scope, if it happens to have been tied it can die. This was resulting in leaks, because no protections were added to handle that case. The two things that were leaking were the new hash in hv_copy_hints_hv and the new value (for an element) in newSVsv. By fixing newSVsv itself, this also fixes any potential leaks when other pieces of code call newSVsv on explosive values.
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/hv.c b/hv.c
index 14f3399a3e..d54246271b 100644
--- a/hv.c
+++ b/hv.c
@@ -1462,6 +1462,9 @@ Perl_hv_copy_hints_hv(pTHX_ HV *const ohv)
const I32 riter = HvRITER_get(ohv);
HE * const eiter = HvEITER_get(ohv);
+ ENTER;
+ SAVEFREESV(hv);
+
while (hv_max && hv_max + 1 >= hv_fill * 2)
hv_max = hv_max / 2;
HvMAX(hv) = hv_max;
@@ -1483,6 +1486,9 @@ Perl_hv_copy_hints_hv(pTHX_ HV *const ohv)
}
HvRITER_set(ohv, riter);
HvEITER_set(ohv, eiter);
+
+ SvREFCNT_inc_simple_void_NN(hv);
+ LEAVE;
}
hv_magic(hv, NULL, PERL_MAGIC_hints);
return hv;