develooper Front page | perl.perl5.porters | Postings from May 2015

Re: FYI - PM posted about a horrible List::Util::first bug

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
May 27, 2015 09:57
Subject:
Re: FYI - PM posted about a horrible List::Util::first bug
Message ID:
20150527095725.GN15483@iabyn.com
On Wed, May 27, 2015 at 09:17:21AM +0200, H.Merijn Brand wrote:
> http://www.perlmonks.org/?node_id=1127889

Which is that in 5.20.0 onwards, this:

    use List::Util qw{ first };
    my %hash = ( ASD => 1, ZXC => 2, QWE => 3, TYU => 4);
    print first { lc $_ eq 'qwe' } keys %hash;

prints "qwe" rather than "QWE".

It bisects to this:

    commit 5cd5e2d6301836ca9b0f94e9a100e697bd374cd8
    Author:     Father Chrysostomos <sprout@cpan.org>
    AuthorDate: Wed Jan 1 05:51:36 2014 -0800

        Re├źnable in-place lc/uc
        
        It used to be that this code:
        
        for("$foo") {
          lc $_;
          ...
        }

I think the logic is flawed in lc/uc/etc that does (as an optimisation)
an in-place modification of the arg and return that value, rather than
copying, when it thinks that the arg is a temporary that wont otherwise
be used again.

The arg passed to lc in the first() code block above is

    SV = PV(0xa8ac28) at 0xaaa2d0
      REFCNT = 1
      FLAGS = (TEMP,POK,IsCOW,pPOK)
      PV = 0xaa3c78 "ZXC"
      CUR = 3
      LEN = 0

which satisfies the 'in-place' test of

    if (   (  SvPADTMP(source)
	   || (  SvTEMP(source) && !SvSMAGICAL(source)
	      && SvREFCNT(source) == 1  )
	   )
	&& !SvREADONLY(source) && SvPOK(source)
	&& !DO_UTF8(source)) {

So I don' think that condition is strong enough, and I'm not sure that
that there is such a safe condition.

-- 
Please note that ash-trays are provided for the use of smokers,
whereas the floor is provided for the use of all patrons.
    -- Bill Royston

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About