summaryrefslogtreecommitdiff
path: root/universal.c
diff options
context:
space:
mode:
authorÆvar Arnfjörð Bjarmason <avar@cpan.org>2010-09-11 09:58:02 +0000
committerNicholas Clark <nick@ccl4.org>2010-09-11 12:23:45 +0100
commit80b6a949dbabd822cf5e1cf2ece76164d772f0b9 (patch)
tree66971dc37db0dee1bc6222b441e0a0ed00ea83d6 /universal.c
parent3d8e05a034fc6625a503b87c8ac336d4d84fb338 (diff)
downloadperl-80b6a949dbabd822cf5e1cf2ece76164d772f0b9.tar.gz
segfault on &Internals::* due to missing SvROK()
Change the &Internals::* functions that use references in their prototypes to check if the argument is SvROK() before calling SvRV(). If the function is called as Internals::FOO() perl does this check for us, but prototypes are bypassed on &Internals::FOO() so we still have to check this manually. This fixes [perl #77776], this bug was present in 5.10.x, 5.12.x, and probably all earlier perl versions that had these functions, but I haven't tested that. I'm adding a new test file (t/lib/universal.t) to test universal.c functions as part of this patch. The testing for Internal::* in t/ was and is very sparse, but before universal.t there was no obvious place to put these tests. Signed-off-by: Ævar Arnfjörð Bjarmason <avar@cpan.org>
Diffstat (limited to 'universal.c')
-rw-r--r--universal.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/universal.c b/universal.c
index 65935018f8..6df104eb13 100644
--- a/universal.c
+++ b/universal.c
@@ -794,9 +794,16 @@ XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
{
dVAR;
dXSARGS;
- SV * const sv = SvRV(ST(0));
+ SV * const svz = ST(0);
+ SV * sv;
PERL_UNUSED_ARG(cv);
+ /* [perl #77776] - called as &foo() not foo() */
+ if (!SvROK(svz))
+ croak_xs_usage(cv, "SCALAR[, ON]");
+
+ sv = SvRV(svz);
+
if (items == 1) {
if (SvREADONLY(sv))
XSRETURN_YES;
@@ -821,9 +828,16 @@ XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
{
dVAR;
dXSARGS;
- SV * const sv = SvRV(ST(0));
+ SV * const svz = ST(0);
+ SV * sv;
PERL_UNUSED_ARG(cv);
+ /* [perl #77776] - called as &foo() not foo() */
+ if (!SvROK(svz))
+ croak_xs_usage(cv, "SCALAR[, REFCOUNT]");
+
+ sv = SvRV(svz);
+
if (items == 1)
XSRETURN_IV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
else if (items == 2) {
@@ -839,7 +853,7 @@ XS(XS_Internals_hv_clear_placehold)
dVAR;
dXSARGS;
- if (items != 1)
+ if (items != 1 || !SvROK(ST(0)))
croak_xs_usage(cv, "hv");
else {
HV * const hv = MUTABLE_HV(SvRV(ST(0)));