summaryrefslogtreecommitdiff
path: root/cv.h
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-10-09 22:57:56 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-10-09 23:14:08 -0700
commit8fa6a40953ef88573ed3cbbb37666e7b72dec7dd (patch)
treee6e3b60bc8cc922ddf8a54d20a4d8fd3d9ab82e3 /cv.h
parent6911735f50121ad015d280f86e257e8e9eae797a (diff)
downloadperl-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 'cv.h')
-rw-r--r--cv.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/cv.h b/cv.h
index f47d171908..ebc876a540 100644
--- a/cv.h
+++ b/cv.h
@@ -71,6 +71,23 @@ For more information, see L<perlguts>.
#define CvFLAGS(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_flags
#define CvOUTSIDE_SEQ(sv) ((XPVCV*)MUTABLE_PTR(SvANY(sv)))->xcv_outside_seq
+/* These two are sometimes called on non-CVs */
+#define CvPROTO(sv) \
+ ( \
+ SvPOK(sv) \
+ ? SvTYPE(sv) == SVt_PVCV && CvAUTOLOAD(sv) \
+ ? SvEND(sv)+1 : SvPVX_const(sv) \
+ : NULL \
+ )
+#define CvPROTOLEN(sv) \
+ ( \
+ SvPOK(sv) \
+ ? SvTYPE(sv) == SVt_PVCV && CvAUTOLOAD(sv) \
+ ? SvLEN(sv)-SvCUR(sv)-2 \
+ : SvCUR(sv) \
+ : 0 \
+ )
+
#define CVf_METHOD 0x0001 /* CV is explicitly marked as a method */
#define CVf_LVALUE 0x0002 /* CV return value can be used as lvalue */
#define CVf_CONST 0x0004 /* inlinable sub */
@@ -86,6 +103,7 @@ For more information, see L<perlguts>.
(esp. useful for special XSUBs) */
#define CVf_CVGV_RC 0x0400 /* CvGV is reference counted */
#define CVf_DYNFILE 0x1000 /* The filename isn't static */
+#define CVf_AUTOLOAD 0x2000 /* SvPVX contains AUTOLOADed sub name */
/* This symbol for optimised communication between toke.c and op.c: */
#define CVf_BUILTIN_ATTRS (CVf_METHOD|CVf_LVALUE)
@@ -147,6 +165,10 @@ For more information, see L<perlguts>.
#define CvDYNFILE_on(cv) (CvFLAGS(cv) |= CVf_DYNFILE)
#define CvDYNFILE_off(cv) (CvFLAGS(cv) &= ~CVf_DYNFILE)
+#define CvAUTOLOAD(cv) (CvFLAGS(cv) & CVf_AUTOLOAD)
+#define CvAUTOLOAD_on(cv) (CvFLAGS(cv) |= CVf_AUTOLOAD)
+#define CvAUTOLOAD_off(cv) (CvFLAGS(cv) &= ~CVf_AUTOLOAD)
+
/* Flags for newXS_flags */
#define XS_DYNAMIC_FILENAME 0x01 /* The filename isn't static */