diff options
author | Ævar Arnfjörð Bjarmason <avar@cpan.org> | 2010-09-11 09:58:02 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2010-09-11 12:23:45 +0100 |
commit | 80b6a949dbabd822cf5e1cf2ece76164d772f0b9 (patch) | |
tree | 66971dc37db0dee1bc6222b441e0a0ed00ea83d6 /universal.c | |
parent | 3d8e05a034fc6625a503b87c8ac336d4d84fb338 (diff) | |
download | perl-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.c | 20 |
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))); |