Skip to content

Commit

Permalink
[perl #119051] Fix crash with \&$glob_copy
Browse files Browse the repository at this point in the history
$ref = *Foo::nosub;
\&$ref;

The assignment creates a glob copy (coercible glob; one that down-
grades back to a simple scalar when assigned to).

\&$ref autovivifies a stub in that glob.  The CvGV pointer ends up
pointing to $ref, rather than *Foo::nosub.  $ref can easily cease
being a glob.  So crashes happen.

Stub autovivification used to stringify the glob, look it up again by
name, and then vivify the stub in the glob.

In commit 186a5ba I removed what seemed like a waste of CPU
cycles, but apparently it served some purpose.  The lookup caused CvGV
to point to *Foo::nosub, rather than $x.

This commit restores the stringfy-and-lookup if the glob is coercible
(SvFAKE).  It goes a little further and turns off the SvFAKE flag if
the glob just looked up is also FAKE.

It turns out this bug is old, and has been triggerable via glob copies
in stash elements for a long time.  186a5ba made it easier to
trigger the bug (so it is a regression from 5.16).
  • Loading branch information
Father Chrysostomos committed Jul 28, 2013
1 parent e82485c commit 2f222bb
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
8 changes: 7 additions & 1 deletion op.c
Expand Up @@ -7918,13 +7918,19 @@ CV *
Perl_newSTUB(pTHX_ GV *gv, bool fake)
{
CV *cv = MUTABLE_CV(newSV_type(SVt_PVCV));
GV *cvgv;
PERL_ARGS_ASSERT_NEWSTUB;
assert(!GvCVu(gv));
GvCV_set(gv, cv);
GvCVGEN(gv) = 0;
if (!fake && HvENAME_HEK(GvSTASH(gv)))
gv_method_changed(gv);
CvGV_set(cv, gv);
if (SvFAKE(gv)) {
cvgv = gv_fetchsv((SV *)gv, GV_ADDMULTI, SVt_PVCV);
SvFAKE_off(cvgv);
}
else cvgv = gv;
CvGV_set(cv, cvgv);
CvFILE_set_from_cop(cv, PL_curcop);
CvSTASH_set(cv, PL_curstash);
GvMULTI_on(gv);
Expand Down
16 changes: 15 additions & 1 deletion t/op/gv.t
Expand Up @@ -12,7 +12,7 @@ BEGIN {

use warnings;

plan( tests => 250 );
plan( tests => 252 );

# type coercion on assignment
$foo = 'foo';
Expand Down Expand Up @@ -959,6 +959,20 @@ package lrcg {
$::{aoeuaoeuaoeaoeu} = __PACKAGE__; # cow
() = *{"aoeuaoeuaoeaoeu"};

$x = *_119051;
$y = \&$x;
undef $x;
eval { &$y };
pass "No crash due to CvGV(vivified stub) pointing to flattened glob copy";
# Not really supported, but this should not crash either:
$x = *_119051again;
delete $::{_119051again};
$::{_119051again} = $x; # now we have a fake glob under the right name
$y = \&$x; # so when this tries to look up the right GV for
undef $::{_119051again}; # CvGV, it still gets a fake one
eval { $y->() };
pass "No crash due to CvGV pointing to glob copy in the stash";

__END__
Perl
Rules
Expand Down

0 comments on commit 2f222bb

Please sign in to comment.