Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
2k stars 559 forks source link

$a["1foo"] same as $a[0] #2345

Closed p5pRT closed 21 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#3670 (status was 'resolved')

Searchable as RT3670$

p5pRT commented 24 years ago

From @gisle

Created by gisle@eik.g.aas.no

This program​:

--------------------------------- @​a = (1\, 2\, 3);

print $a["1foo"]\, "\n"; print $a["1"]\, "\n"; ---------------------------------

prints​:

Argument "1foo" isn't numeric in array element at xxx.pl line 4. 1 2

With perl5.005_03 I get "2\n2\n" as expected.

Perl Info ``` Flags: category=core severity=high Site configuration information for perl v5.6.0: Configured by gisle at Mon May 22 17:07:41 CEST 2000. Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration: Platform: osname=linux, osvers=2.2.5, archname=i686-linux uname='linux eik 2.2.5 #1 mon sep 13 14:53:01 cest 1999 i686 unknown ' config_args='-Dprefix=/local/perl/5.6.0_priv -Doptimize=-g -ders' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=define use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef Compiler: cc='cc', optimize='-g', gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) cppflags='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include' ccflags ='-DDEBUGGING -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' stdchar='char', d_stdstdio=define, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lndbm -lgdbm -ldbm -ldb -ldl -lm -lc -lposix -lcrypt libc=, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl v5.6.0: /local/perl/5.6.0_priv/lib/5.6.0/i686-linux /local/perl/5.6.0_priv/lib/5.6.0 /local/perl/5.6.0_priv/lib/site_perl/5.6.0/i686-linux /local/perl/5.6.0_priv/lib/site_perl/5.6.0 /local/perl/5.6.0_priv/lib/site_perl . Environment for perl v5.6.0: HOME=/home/gisle LANG=POSIX LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=[senosored] PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

gisle@​aas.no (lists.p5p)​:

This program​:

--------------------------------- @​a = (1\, 2\, 3);

print $a["1foo"]\, "\n"; print $a["1"]\, "\n"; ---------------------------------

prints​:

Argument "1foo" isn't numeric in array element at xxx.pl line 4. 1 2

Oh\, sheesh\, I am naughty. This is a bug I fixed in Sapphire but didn't backport to Perl. Sorry 'bout that. The problem is that sv_2iv calls looks_like_number to determine whether something can be converted to a number or not. looks_like_number is much stricter than the /^[\d.]+/ rule you'd imagine - it's actually more like /^[\d.]+\s*$/ with exceptions for infinity and "0 but true". Hence\, "1foo" doesn't match that\, and looks_like_number returns zero.

It's my contention that it shouldn't. The offending lines are 2039 and 2040 of sv.c​:

  if (s >= send)   return numtype;

That enforces the \s*$ bit of the above regular expression​: it says we have to have past the end of the string after we've dealt with the numbers and spaces.

This is what's in Sapphire​:

Inline Patch ```diff --- sv.c~ Thu Aug 10 21:21:08 2000 +++ sv.c Thu Aug 10 21:21:40 2000 @@ -2036,11 +2036,9 @@ } while (isSPACE(*s)) s++; - if (s >= send) - return numtype; if (len == 10 && memEQ(sbegin, "0 but true", 10)) return IS_NUMBER_TO_INT_BY_ATOL; - return 0; + return numtype; } char * Again, apologies for not having brought that up myself. :( ```
p5pRT commented 24 years ago

From @gisle

simon@​brecon.co.uk (Simon Cozens) writes​:

gisle@​aas.no (lists.p5p)​:

This program​:

--------------------------------- @​a = (1\, 2\, 3);

print $a["1foo"]\, "\n"; print $a["1"]\, "\n"; ---------------------------------

prints​:

Argument "1foo" isn't numeric in array element at xxx.pl line 4. 1 2

Oh\, sheesh\, I am naughty. This is a bug I fixed in Sapphire but didn't backport to Perl. Sorry 'bout that. The problem is that sv_2iv calls looks_like_number to determine whether something can be converted to a number or not. looks_like_number is much stricter than the /^[\d.]+/ rule you'd imagine - it's actually more like /^[\d.]+\s*$/ with exceptions for infinity and "0 but true". Hence\, "1foo" doesn't match that\, and looks_like_number returns zero.

It's my contention that it shouldn't. The offending lines are 2039 and 2040 of sv.c​:

if \(s >= send\)
    return numtype;

That enforces the \s*$ bit of the above regular expression​: it says we have to have past the end of the string after we've dealt with the numbers and spaces.

I would argue that looks_like_number is correct. The problem is the stuff in sv_2iv which says /* Not a number. Cache 0. */. It should invoke Atol() or Atof() always.

Regards\, Gisle

This is what's in Sapphire​:

--- sv.c~ Thu Aug 10 21​:21​:08 2000 +++ sv.c Thu Aug 10 21​:21​:40 2000 @​@​ -2036\,11 +2036\,9 @​@​ } while (isSPACE(*s)) s++; - if (s >= send) - return numtype; if (len == 10 && memEQ(sbegin\, "0 but true"\, 10)) return IS_NUMBER_TO_INT_BY_ATOL; - return 0; + return numtype; }

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Gisle Aas (lists.p5p)​:

I would argue that looks_like_number is correct. The problem is the stuff in sv_2iv which says /* Not a number. Cache 0. */. It should invoke Atol() or Atof() always.

This is probably a bit philosophical\, but I think that the job of looks_like_number is to determine whether and how Ato*() should be invoked. looks_like_number should only return zero if something doesn't look like a number.

Could go either way\, I guess.

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Gisle Aas \gisle@​ActiveState\.com wrote

I would argue that looks_like_number is correct. The problem is the stuff in sv_2iv which says /* Not a number. Cache 0. */. It should invoke Atol() or Atof() always.

I entirely agree\, not least because that's what 5.005_03 does.

Patch\, with regression test\, for bleadperl follows.

Mike Guy

Inline Patch ```diff --- ./sv.c.orig Sun Aug 6 17:59:17 2000 +++ ./sv.c Thu Aug 10 15:39:47 2000 @@ -1569,22 +1569,13 @@ goto ret_iv_max; } } - else if (numtype) { - /* The NV may be reconstructed from IV - safe to cache IV, - which may be calculated by atol(). */ - if (SvTYPE(sv) == SVt_PV) - sv_upgrade(sv, SVt_PVIV); - (void)SvIOK_on(sv); - SvIVX(sv) = Atol(SvPVX(sv)); - } - else { /* Not a number. Cache 0. */ - dTHR; - + else { /* The NV may be reconstructed from IV - safe to cache IV, + which may be calculated by atol(). */ if (SvTYPE(sv) < SVt_PVIV) sv_upgrade(sv, SVt_PVIV); (void)SvIOK_on(sv); - SvIVX(sv) = 0; - if (ckWARN(WARN_NUMERIC)) + SvIVX(sv) = Atol(SvPVX(sv)); + if (! numtype && ckWARN(WARN_NUMERIC)) not_a_number(sv); } } --- ./t/op/int.t.orig Tue Aug 1 03:32:13 2000 +++ ./t/op/int.t Thu Aug 10 15:36:40 2000 @@ -5,7 +5,7 @@ unshift @INC, '../lib'; } -print "1..6\n"; +print "1..7\n"; # compile time evaluation @@ -28,3 +28,9 @@ $y = (3/-10)*-10; print $x+$y == 3 && abs($x) < 10 ? "ok 6\n" : "not ok 6\n"; } + +# check bad strings still get converted + +@x = ( 6, 8, 10); +print "not " if $x["1foo"] != 8; +print "ok 7\n"; End of patch ```
p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

I just wrote

Patch\, with regression test\, for bleadperl follows.

I forgot to add that in the two branches I merged\, one had a dTHR and the other did not. So I left it out in the merge\, but I don't understand the rules. The patch has only been tested without threads.

YMMV.

Mike Guy

p5pRT commented 24 years ago

From @jhi

On Thu\, Aug 10\, 2000 at 03​:50​:54PM +0100\, Mike Guy wrote​:

Gisle Aas \gisle@&#8203;ActiveState\.com wrote

I would argue that looks_like_number is correct. The problem is the stuff in sv_2iv which says /* Not a number. Cache 0. */. It should invoke Atol() or Atof() always.

I entirely agree\, not least because that's what 5.005_03 does.

Patch\, with regression test\, for bleadperl follows.

It's in.