diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-10-09 22:57:56 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-10-09 23:14:08 -0700 |
commit | 8fa6a40953ef88573ed3cbbb37666e7b72dec7dd (patch) | |
tree | e6e3b60bc8cc922ddf8a54d20a4d8fd3d9ab82e3 /toke.c | |
parent | 6911735f50121ad015d280f86e257e8e9eae797a (diff) | |
download | perl-8fa6a40953ef88573ed3cbbb37666e7b72dec7dd.tar.gz |
Resolve XS AUTOLOAD-prototype conflict
Did you know that a subroutine’s prototype can be modified with s///?
Don’t look:
*AUTOLOAD = *Internals'SvREFCNT;
my $f = "Just another "; eval{main->$f};
print prototype AUTOLOAD;
$f =~ s/Just another /Perl hacker,\n/;
print prototype AUTOLOAD;
You did look, didn’t you? You must admit that’s creepy.
The problem goes back to this:
commit adb5a9ae91a0bed93d396bb0abda99831f9e2e6f
Author: Doug MacEachern <dougm@covalent.net>
Date: Sat Jan 6 01:30:05 2001 -0800
[patch] xsub AUTOLOAD fix/optimization
Message-ID: <Pine.LNX.4.10.10101060924280.24460-100000@mojo.covalent.net>
Allow AUTOLOAD to be an xsub and allow such xsubs
to avoid use of $AUTOLOAD.
p4raw-id: //depot/perl@8362
which includes this:
+ if (CvXSUB(cv)) {
+ /* rather than lookup/init $AUTOLOAD here
+ * only to have the XSUB do another lookup for $AUTOLOAD
+ * and split that value on the last '::',
+ * pass along the same data via some unused fields in the CV
+ */
+ CvSTASH(cv) = stash;
+ SvPVX(cv) = (char *)name; /* cast to loose constness warning */
+ SvCUR(cv) = len;
+ return gv;
+ }
That ‘unused’ field is not unused. It’s where the prototype is
stored. So, not only is it clobbering the prototype, it’s also leak-
ing it by assigning over the top of SvPVX. Furthermore, it’s blindly
assigning someone else’s string, which could be freed before it’s
even used.
Since it has been documented for a long time that SvPVX contains the
name of the AUTOLOADed sub, and since the use of SvPVX for prototypes
is documented nowhere, we have to preserve the former.
So this commit makes the prototype and the sub name share the same
buffer, in a manner resembling that which CvFILE used before I changed
it with bad4ae38.
There are two new internal macros, CvPROTO and CvPROTOLEN for retriev-
ing the prototype.
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -3739,7 +3739,7 @@ S_intuit_method(pTHX_ char *start, GV *gv, CV *cv) return 0; if (cv) { if (SvPOK(cv)) { - const char *proto = SvPVX_const(cv); + const char *proto = CvPROTO(cv); if (proto) { if (*proto == ';') proto++; @@ -6775,8 +6775,8 @@ Perl_yylex(pTHX) #endif SvPOK(cv)) { - STRLEN protolen; - const char *proto = SvPV_const(MUTABLE_SV(cv), protolen); + STRLEN protolen = CvPROTOLEN(cv); + const char *proto = CvPROTO(cv); if (!protolen) TERM(FUNC0SUB); while (*proto == ';') |