Front page | perl.perl5.porters |
Postings from February 2020
Re: Bug in format introduced in 5.27.6
Thread Previous
From:
Dave Mitchell
Date:
February 4, 2020 12:51
Subject:
Re: Bug in format introduced in 5.27.6
Message ID:
20200204125122.GF4848@iabyn.com
On Tue, Jan 21, 2020 at 01:05:50PM +0100, H.Merijn Brand wrote:
> On Tue, 21 Jan 2020 12:49:16 +0100, "H.Merijn Brand"
> <h.m.brand@xs4all.nl> wrote:
>
> > perl -le '$~ = "L02"; { local $~ = "$~h"; print $~; }'
>
> FWIW, same for
> perl -le '$~ = "L02"; { local $~ = $~."h"; print $~; }'
>
> I had to assign $~ to a lexical for the workaround
>
> perl -le '$~ = "L02"; { my $f = $~; local $~ = $f."h"; print $~; }'
>
> > up to and including perl-5.27.5, this would print "L02h"
> > as of 5.27.6 this prints "h"
> >
> > this breaks production code :(
Fixed with the following commit. Note that localising magic vars has
always been a bit problematic. For example, the following fails on all
perls:
$~ = "FOO";
local $~ = $~;
print "[$~]\n"; # prints "[]"
'local $~ = "....$~...."' works only because the RHS is an expression
which returns a temporary value which doesn't change when $~ is changed by
the localization.
commit d5a02d973b44832f918778202d68f066c8af3963
Author: David Mitchell <davem@iabyn.com>
AuthorDate: Tue Feb 4 12:23:26 2020 +0000
Commit: David Mitchell <davem@iabyn.com>
CommitDate: Tue Feb 4 12:43:24 2020 +0000
multiconcat: keep assign for 'local $foo = "..."'
In something like
local $~ = "$~X";
i.e. where localising a magic variable whose previous value should be
used as part of a string concat on the RHS, don't fold the assign into
the multiconcat op. Otherwise the code execution path looks a bit like:
local($~) = undef;
multiconcat($~, $~, "X");
[ where multiconcat's args are (target, arg1, arg2,....) ]
and thus multiconcat sees an undef arg.
By leaving the assign out of the multiconcat, code execution now looks
like
my $targ;
multiconcat($targ, $~, "X");
local($~) = $targ;
See http://nntp.perl.org/group/perl.perl5.porters/256898,
"Bug in format introduced in 5.27.6".
Although the bug only appears with magic vars, this patch pessimises
all forms of 'local $foo = "..."', 'local $foo{bar} = "..."' etc.
Strictly speaking the bug occurs because with 'local' you end up with
two SVs (the saved one and the one currently in the glob) which both
have the same container magic and where mg_set()ing one changes the
mg_get() value of the other. Thus, vars like $!. One of the two SVs
becomes an arg of multiconcat, the other becomes its target. Part of
localising the target SV (before multiconcat is called) wipes the value
of the arg SV.
--
Fire extinguisher (n) a device for holding open fire doors.
Thread Previous