summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-09-24 18:56:57 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-09-24 19:24:28 -0700
commit73c02f1564c743dc981bd8ea1ce2b967131cbd83 (patch)
tree0904fe8796a823bd2a9e991fd3de58eacb8602b6 /gv.c
parent1b7228c9af61f2feb164874a11b82557fc988b5f (diff)
downloadperl-73c02f1564c743dc981bd8ea1ce2b967131cbd83.tar.gz
Avoid a double free with CORE->lc
The code for autovivifying coresubs for method calls ended up calling hv_store(stash,name,len,(SV *)gv,0) where gv is already in the stash under that entry. Since hv_store takes ownership of one reference count and decrements that of what it overwrites (which is the same gv in this case), it ends up freeing the gv prematurely. It ended up making that call because S_maybe_add_coresub needs the stash to get its ENAME (which happens when called by gv_fetchmeth), but it also assumed that the presence of the stash meant the gv needed to be stored in it (as is the case with the other caller, gv_fetchpvn_flags). This patch reuses the fullen (full length) parameter as a flag to indicate that that hv_store call should be skipped. These workarounds for the assumptions that newATTRSUB makes are start- ing to make inlining look very attractive....
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/gv.c b/gv.c
index 4ba2c79867..19059bc28f 100644
--- a/gv.c
+++ b/gv.c
@@ -458,7 +458,8 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
it this order as we need an op number before calling
new ATTRSUB. */
(void)core_prototype((SV *)cv, name, code, &opnum);
- if (stash) (void)hv_store(stash,name,len,(SV *)gv,0);
+ if (stash && (fullname || !fullen))
+ (void)hv_store(stash,name,len,(SV *)gv,0);
if (ampable) {
SV *tmpstr;
CvLVALUE_on(cv);
@@ -584,7 +585,7 @@ Perl_gv_fetchmeth(pTHX_ HV *stash, const char *name, STRLEN len, I32 level)
}
else if (len > 1 /* shortest is uc */ && HvNAMELEN_get(stash) == 4
&& strnEQ(hvname, "CORE", 4)
- && S_maybe_add_coresub(aTHX_ stash,topgv,name,len,0,0))
+ && S_maybe_add_coresub(aTHX_ stash,topgv,name,len,0,1))
goto have_gv;
}