summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2010-07-24 15:41:19 +0100
committerDavid Mitchell <davem@iabyn.com>2010-07-24 15:47:57 +0100
commite5c69c9b913b1a7f8a83beabb60e96958df29689 (patch)
tree4c740a408c1a98fefc38dbea873052d12258deea /gv.c
parent87f4ab41b64991a57643a80d84f9ca824fbdb9a4 (diff)
downloadperl-e5c69c9b913b1a7f8a83beabb60e96958df29689.tar.gz
[perl #76540] "print CONSTANT," gives double-free
gv_init() has name and len args, but newCONSTSUB() (which it calls) doesn't have a len arg, so any trailing garbage in name gets used by newCONSTSUB. In the test case, this means that we end up attaching the const CV to both the "FOO" and qq{FOO, "\\n";\n} GVs. So it gets freed twice.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/gv.c b/gv.c
index a5c33d93f1..a50878f549 100644
--- a/gv.c
+++ b/gv.c
@@ -288,8 +288,16 @@ Perl_gv_init(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, int multi)
CV *cv;
ENTER;
if (has_constant) {
+ char *name0 = NULL;
+ if (name[len])
+ /* newCONSTSUB doesn't take a len arg, so make sure we
+ * give it a \0-terminated string */
+ name0 = savepvn(name,len);
+
/* newCONSTSUB takes ownership of the reference from us. */
- cv = newCONSTSUB(stash, name, has_constant);
+ cv = newCONSTSUB(stash, (name0 ? name0 : name), has_constant);
+ if (name0)
+ Safefree(name0);
/* If this reference was a copy of another, then the subroutine
must have been "imported", by a Perl space assignment to a GV
from a reference to CV. */