This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix two \&$tied regressions
authorFather Chrysostomos <sprout@cpan.org>
Thu, 1 Sep 2011 23:16:32 +0000 (16:16 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 1 Sep 2011 23:28:35 +0000 (16:28 -0700)
commitff55a0191f195519f46838f62b3cd22a95056579
tree9d09e639d033888175da3e6a05ca4a1eb5926769
parentad66d0c9a62d4dfd3104dc78e5ed404470286bb6
Fix two \&$tied regressions

If the tied variable holds a reference, but changes to something else
when FETCH is called, perl crashes, as of commit 9d0f7ed75
(5.10.1/5.12.0):

sub ::72 { 73 };
sub TIESCALAR {bless[]}
sub STORE{}
sub FETCH { 72 }
tie my $x, "main";
$x = \$y;
\&$x;

That’s because commit 7a5fd60d4 caused double magic for one branch of
an if/else chain in sv_2cv (by using gv_fetchsv), so commit 9d0f7ed75
removed the SvGETMAGIC preceding the if/else, putting it inside each
branch.  That meant that the type would be checked before get-magic
was called.  So the type could change unexpectedly.

Due to another bug, this did not affect globs returned from tied array
elements, which got stringified, and hence worked in sv_2cv.  But that
bug was fixed in 5.14.0 by commit 13be902ce, which allowed typeglobs
to be returned unflattened through elements of tied aggregates, caus-
ing this to stop working (‘Not a CODE reference’ instead of 73):

sub ::72 { 73 };
sub TIEARRAY {bless[]}
sub STORE{}
sub FETCH { 72 }
tie my @x, "main";
my $elem = \$x[0];
$$elem = *bar;
print &{\&$$elem}, "\n";

This commit fixes both issues by putting the SvGETMAGIC call
back where it belongs, above the if/else chain, and by using
SvPV_nomg_const and gv_fetchpvn_flags instead of gv_fetchsv, to avoid
an extra magic call.
sv.c
t/op/tie.t