Skip Menu |

This queue is for tickets about the version CPAN distribution.

Report information
The Basics
Id: 45241
Status: resolved
Priority: 0/
Queue: version

People
Owner: Nobody in particular
Requestors: kane [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.76
Fixed in: (no value)



Subject: Version.pm gives different results for comparisons under 5.8.9(broken) and 5.10.0
Hi John, I found a rather alarming bug in version.pm. It seems comparisons against big numbers (picked an arbitrary one, did not check for the lower bound) produce broken results on 64bit on 5.8.9 (and presumably all of 5.8.x): ### first with perl5.8.9 $ ~/perl/5.8.9/bin/perl -Mversion -le'print version->VERSION' 0.76 $ ~/perl/5.8.9/bin/perl -Mversion -le'print version->new(qq[3.26]) <= version->new( ~0/1000 )' ### now with perl5.10.0 $ ~/perl/5.10.0/bin/perl -Mversion -le'print version->VERSION' 0.76 $ ~/perl/5.10.0/bin/perl -Mversion -le'print version->new(qq[3.26]) <= version->new( ~0/1000 )' 1 Here's the full perl -V for both perls used: $ ~/perl/5.8.9/bin/perl -VSummary of my perl5 (revision 5 version 8 subversion 9) configuration: Platform: osname=solaris, osvers=2.11, archname=i86pc-solaris-64int uname='sunos open-solaris-noc 5.11 snv_95 i86pc i386 i86pc ' config_args='-Dcc=gcc -Dprefix=~/perl/5.8.9 -Duse64bitint -d' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-DPTR_IS_LONG -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DPERL_USE_SAFE_PUTENV', optimize='-O', cppflags='-DPTR_IS_LONG -fno-strict-aliasing -pipe' ccversion='', gccversion='3.4.3 (csl-sol210-3_4-20050802)', gccosandvers='solaris2.11' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc', ldflags =' ' libpth=/usr/lib /usr/ccs/lib libs=-lsocket -lnsl -ldl -lm -lc perllibs=-lsocket -lnsl -ldl -lm -lc libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-fPIC', lddlflags='-G' Characteristics of this binary (from libperl): Compile-time options: PERL_MALLOC_WRAP PERL_USE_SAFE_PUTENV USE_64_BIT_INT USE_FAST_STDIO USE_LARGE_FILES USE_PERLIO Built under solaris Compiled at Apr 23 2009 11:22:11 %ENV: PERL5LIB="/export/home/jos/sources/perl/CPANPLUS-0.85_08/inc/bundle" PERL5OPT="" @INC: /export/home/jos/sources/perl/CPANPLUS-0.85_08/inc/bundle /export/home/jos/perl/5.8.9/lib/5.8.9/i86pc-solaris-64int /export/home/jos/perl/5.8.9/lib/5.8.9 /export/home/jos/perl/5.8.9/lib/site_perl/5.8.9/i86pc-solaris-64int /export/home/jos/perl/5.8.9/lib/site_perl/5.8.9 . $ ~/perl/5.10.0/bin/perl -V Summary of my perl5 (revision 5 version 10 subversion 0) configuration: Platform: osname=solaris, osvers=2.11, archname=i86pc-solaris-64int uname='sunos open-solaris-noc 5.11 snv_95 i86pc i386 i86pc ' config_args='-Dcc=gcc -Dprefix=~/perl/5.8.10 -Duse64bitint -d' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-DPTR_IS_LONG -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DPERL_USE_SAFE_PUTENV', optimize='-O', cppflags='-DPTR_IS_LONG -fno-strict-aliasing -pipe' ccversion='', gccversion='3.4.3 (csl-sol210-3_4-20050802)', gccosandvers='solaris2.11' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc', ldflags =' ' libpth=/usr/lib /usr/ccs/lib libs=-lsocket -lnsl -ldl -lm -lc perllibs=-lsocket -lnsl -ldl -lm -lc libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-fPIC', lddlflags='-G' Characteristics of this binary (from libperl): Compile-time options: PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP PERL_USE_SAFE_PUTENV USE_64_BIT_INT USE_LARGE_FILES USE_PERLIO Built under solaris Compiled at Apr 23 2009 11:48:22 %ENV: PERL5LIB="/export/home/jos/sources/perl/CPANPLUS-0.85_08/inc/bundle" PERL5OPT="" @INC: /export/home/jos/sources/perl/CPANPLUS-0.85_08/inc/bundle /export/home/jos/perl/5.8.10/lib/5.10.0/i86pc-solaris-64int /export/home/jos/perl/5.8.10/lib/5.10.0 /export/home/jos/perl/5.8.10/lib/site_perl/5.10.0/i86pc-solaris-64int /export/home/jos/perl/5.8.10/lib/site_perl/5.10.0 .
On Thu Apr 23 07:57:15 2009, KANE wrote: Show quoted text
> Hi John, > > I found a rather alarming bug in version.pm. It seems comparisons > against big numbers (picked an arbitrary one, did not check for the > lower bound) produce broken results on 64bit on 5.8.9 (and presumably > all of 5.8.x): > > ### first with perl5.8.9 > $ ~/perl/5.8.9/bin/perl -Mversion -le'print version->VERSION' > 0.76 > $ ~/perl/5.8.9/bin/perl -Mversion -le'print version->new(qq[3.26]) <= > version->new( ~0/1000 )' > > ### now with perl5.10.0 > $ ~/perl/5.10.0/bin/perl -Mversion -le'print version->VERSION' > 0.76 > $ ~/perl/5.10.0/bin/perl -Mversion -le'print version->new(qq[3.26]) <= > version->new( ~0/1000 )' > 1 >
I cannot confirm this on a FreeBSD amd64 machine: $ /usr/perl5.8.9@RC2/bin/perl -Mversion\ 99999 version version 99999 required--this is only version 0.76 . $ /usr/perl5.8.9@RC2/bin/perl -Mversion -le'print version->new(qq[3.26]) <= version->new( ~0/1000 )' 1 $ /usr/perl5.8.9@RC2/bin/perl -V Summary of my perl5 (revision 5 version 8 subversion 9) configuration: Platform: osname=freebsd, osvers=7.0-release, archname=amd64-freebsd uname='freebsd biokovo-amd64.herceg.de 7.0-release freebsd 7.0-release #0: sun feb 24 10:35:36 utc 2008 root@driscoll.cse.buffalo.edu:usrobjusrsrcsysgeneric amd64 ' config_args='-ds -e -Dprefix=/usr/perl5.8.9@RC2' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=define uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -I/usr/local/include', optimize='-O', cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -I/usr/local/include' ccversion='', gccversion='4.2.1 20070719 [FreeBSD]', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags ='-Wl,-E -L/usr/local/lib' libpth=/usr/lib /usr/local/lib libs=-lgdbm -lm -lcrypt -lutil -lc perllibs=-lm -lcrypt -lutil -lc libc=, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-DPIC -fPIC', lddlflags='-shared -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: PERL_MALLOC_WRAP USE_64_BIT_ALL USE_64_BIT_INT USE_FAST_STDIO USE_LARGE_FILES USE_PERLIO Locally applied patches: RC2 Built under freebsd Compiled at Dec 6 2008 22:18:54 %ENV: PERL_HTML_DISPLAY_CLASS="HTML::Display::Mozilla" @INC: /usr/perl5.8.9@RC2/lib/5.8.9/amd64-freebsd /usr/perl5.8.9@RC2/lib/5.8.9 /usr/perl5.8.9@RC2/lib/site_perl/5.8.9/amd64-freebsd /usr/perl5.8.9@RC2/lib/site_perl/5.8.9 .
Subject: Re: [rt.cpan.org #45241] Version.pm gives different results for comparisons under 5.8.9(broken) and 5.10.0
Date: Sun, 26 Apr 2009 21:27:49 -0400
To: bug-version [...] rt.cpan.org
From: John Peacock <john.peacock [...] havurah-software.org>
Jos Boumans via RT wrote: Show quoted text
> I found a rather alarming bug in version.pm. It seems comparisons > against big numbers (picked an arbitrary one, did not check for the > lower bound) produce broken results on 64bit on 5.8.9 (and presumably > all of 5.8.x):
I can't recreate with 64-bit Perl 5.8.8 (Centos). Can you do this: $ perl5.8.8 -MDevel::Peek -e 'Dump(~0/1000)' SV = NV(0x36ec8a8) at 0x36c53d0 REFCNT = 1 FLAGS = (PADBUSY,PADTMP,NOK,READONLY,pNOK) NV = 1.84467440737096e+16 $ perl5.10.0 -MDevel::Peek -e 'Dump(~0/1000)' SV = NV(0xb74d8b8) at 0xb725e30 REFCNT = 1 FLAGS = (PADTMP,NOK,READONLY,pNOK) NV = 1.84467440737096e+16 on your box and show me the output? In any case, I can't consider this to be a bug in version.pm; you are passing a very large floating point number to code which immediately converts it to a PV and parses it as a string. It isn't surprising that you can come up with slight variations to the FP notation. version.pm is not a generic module: it is designed for precisely the purpose of parsing module VERSION's in a sensible and consistent fashion; if you actually want to use ~0/1000 as your module $VERSION (which will be radically different on 32 and 64-bit machines), then I feel sorry for your users... ;-) John
Subject: Re: [rt.cpan.org #45241] Version.pm gives different results for comparisons under 5.8.9(broken) and 5.10.0
Date: Mon, 27 Apr 2009 10:24:01 +0200
To: bug-version [...] rt.cpan.org
From: "Jos I. Boumans" <kane [...] cpan.org>
On Apr 27, 2009, at 3:29 AM, John Peacock via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=45241 > > > Jos Boumans via RT wrote:
>> I found a rather alarming bug in version.pm. It seems comparisons >> against big numbers (picked an arbitrary one, did not check for the >> lower bound) produce broken results on 64bit on 5.8.9 (and presumably >> all of 5.8.x):
> > I can't recreate with 64-bit Perl 5.8.8 (Centos). Can you do this:
A bit of extra digging shows that it's the pure perl version that has this problem. The XS version behaves correctly on both perl versions. Please make sure you're testing this problem with version::vpp as the backend. Show quoted text
> $ perl5.8.8 -MDevel::Peek -e 'Dump(~0/1000)' > SV = NV(0x36ec8a8) at 0x36c53d0 > REFCNT = 1 > FLAGS = (PADBUSY,PADTMP,NOK,READONLY,pNOK) > NV = 1.84467440737096e+16 > > $ perl5.10.0 -MDevel::Peek -e 'Dump(~0/1000)' > SV = NV(0xb74d8b8) at 0xb725e30 > REFCNT = 1 > FLAGS = (PADTMP,NOK,READONLY,pNOK) > NV = 1.84467440737096e+16 > > on your box and show me the output?
[jos@open-solaris-noc ~]$ ~/perl/5.10.0/bin/perl -MDevel::Peek -e 'Dump(~0/1000)' SV = NV(0x81837f0) at 0x816bd90 REFCNT = 1 FLAGS = (NOK,READONLY,pNOK) NV = 1.84467440737096e+16 [jos@open-solaris-noc ~]$ ~/perl/5.8.9/bin/perl -MDevel::Peek -e 'Dump (~0/1000)' SV = NV(0x8155594) at 0x813e218 REFCNT = 1 FLAGS = (NOK,READONLY,pNOK) NV = 1.84467440737096e+16 Show quoted text
> In any case, I can't consider this to be a bug in version.pm; you > are passing a > very large floating point number to code which immediately converts > it to a PV > and parses it as a string. It isn't surprising that you can come > up with slight > variations to the FP notation.
I hope you're kidding. 'slight variations' is a real understatement; in one case a number is BIGGER than 3.26, in the other it's not. Show quoted text
> version.pm is not a generic module: it is designed for precisely > the purpose of > parsing module VERSION's in a sensible and consistent fashion; if > you actually > want to use ~0/1000 as your module $VERSION (which will be > radically different > on 32 and 64-bit machines), then I feel sorry for your users... ;-)
As I said in the original bug report, i did not test for the lower bound, it merely displays that on 5.8, version::vpp behaves DIFFERENTLY from version::vxs. And *that* is the problem. Additional research shows it only happens (reproducably) for some ranges of values: $ ~/perl/5.8.9/bin/perl -I/tmp/version -Mversion -le'$d=1; while($d>0) {print "d=$d: ", version->new("2") <= version->new( ~0/$d ); $d<<=1}' d=1: 1 d=2: 1 d=4: 1 d=8: 1 d=16: d=32: 1 d=64: 1 d=128: d=256: 1 d=512: 1 d=1024: d=2048: 1 d=4096: 1 d=8192: 1 d=16384: d=32768: 1 d=65536: 1 d=131072: 1 d=262144: 1 d=524288: 1 d=1048576: 1 d=2097152: 1 d=4194304: 1 d=8388608: 1 d=16777216: 1 d=33554432: 1 d=67108864: 1 d=134217728: 1 d=268435456: 1 d=536870912: 1 d=1073741824: 1 d=2147483648: 1 d=4294967296: 1 d=8589934592: 1 d=17179869184: 1 d=34359738368: 1 d=68719476736: 1 d=137438953472: 1 d=274877906944: 1 d=549755813888: 1 d=1099511627776: 1 d=2199023255552: 1 d=4398046511104: 1 d=8796093022208: 1 d=17592186044416: 1 d=35184372088832: 1 d=70368744177664: 1 d=140737488355328: 1 d=281474976710656: 1 d=562949953421312: 1 d=1125899906842624: 1 d=2251799813685248: 1 d=4503599627370496: 1 d=9007199254740992: 1 d=18014398509481984: 1 d=36028797018963968: 1 d=72057594037927936: 1 d=144115188075855872: 1 d=288230376151711744: 1 d=576460752303423488: 1 d=1152921504606846976: 1 d=2305843009213693952: 1 d=4611686018427387904: 1 d=9223372036854775808: 1 The other tester machine that was affected by this problem: http://www.nntp.perl.org/group/perl.cpan.testers/2009/04/ msg3741982.html The box I'm testing this on is Jost Krieger's solaris smoker. He's been kind enough to give out an account to me. I'm sure if you ask him, he'll do the same for you. Cheers, -- Jos Boumans "Whenever you find you are on the side of the majority, it is time to pause and reflect." - Mark Twain
On Mon Apr 27 04:24:30 2009, KANE wrote: Show quoted text
>
[...] Show quoted text
> Additional research shows it only happens (reproducably) for some > ranges of values: > > $ ~/perl/5.8.9/bin/perl -I/tmp/version -Mversion -le'$d=1; while($d>0) > {print "d=$d: ", version->new("2") <= version->new( ~0/$d ); $d<<=1}' > d=1: 1 > d=2: 1 > d=4: 1 > d=8: 1 > d=16: > d=32: 1 > d=64: 1 > d=128: > d=256: 1 > d=512: 1 > d=1024: > d=2048: 1 > d=4096: 1 > d=8192: 1 > d=16384: > d=32768: 1
... You can see the pattern if you print out the value of the checked versions: you see a failure if scientific notation is used and the integer part of the mantissa is lower than 2: d=1: 18446744073709551615 d=2: 9.22337203685478e+18 d=4: 4.61168601842739e+18 d=8: 2.30584300921369e+18 d=16: 1.15292150460685e+18 d=32: 5.76460752303423e+17 d=64: 2.88230376151712e+17 d=128: 1.44115188075856e+17 d=256: 7.20575940379279e+16 d=512: 3.6028797018964e+16 d=1024: 1.8014398509482e+16 d=2048: 9.00719925474099e+15 d=4096: 4.5035996273705e+15 d=8192: 2.25179981368525e+15 d=16384: 1.12589990684262e+15 d=32768: 562949953421312 That said, I would tend to just declare the semantics of version numbers that large as undefined. Regards, Slaven
Subject: Re: [rt.cpan.org #45241] Version.pm gives different results for comparisons under 5.8.9(broken) and 5.10.0
Date: Mon, 27 Apr 2009 23:22:04 +0200
To: bug-version [...] rt.cpan.org
From: "Jos I. Boumans" <kane [...] cpan.org>
On Apr 27, 2009, at 11:18 PM, Slaven_Rezic via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=45241 > > > On Mon Apr 27 04:24:30 2009, KANE wrote:
>>
> [...]
>> Additional research shows it only happens (reproducably) for some >> ranges of values: >> >> $ ~/perl/5.8.9/bin/perl -I/tmp/version -Mversion -le'$d=1; while >> ($d>0) >> {print "d=$d: ", version->new("2") <= version->new( ~0/$d ); $d<<=1}' >> d=1: 1 >> d=2: 1 >> d=4: 1 >> d=8: 1 >> d=16: >> d=32: 1 >> d=64: 1 >> d=128: >> d=256: 1 >> d=512: 1 >> d=1024: >> d=2048: 1 >> d=4096: 1 >> d=8192: 1 >> d=16384: >> d=32768: 1
> ... > > You can see the pattern if you print out the value of the checked > versions: you see a failure if scientific notation is used and the > integer part of the mantissa is lower than 2: > > d=1: 18446744073709551615 > d=2: 9.22337203685478e+18 > d=4: 4.61168601842739e+18 > d=8: 2.30584300921369e+18 > d=16: 1.15292150460685e+18 > d=32: 5.76460752303423e+17 > d=64: 2.88230376151712e+17 > d=128: 1.44115188075856e+17 > d=256: 7.20575940379279e+16 > d=512: 3.6028797018964e+16 > d=1024: 1.8014398509482e+16 > d=2048: 9.00719925474099e+15 > d=4096: 4.5035996273705e+15 > d=8192: 2.25179981368525e+15 > d=16384: 1.12589990684262e+15 > d=32768: 562949953421312 > > That said, I would tend to just declare the semantics of version > numbers > that large as undefined.
I can live with that; but i'd like a version.pm that behaves the same in xs and pure perl. Whatever that behaviour should be I'm happy to leave to the version.pm developers, but right now this can lead to strange behaviours. Cheers, -- Jos Boumans "Whenever you find you are on the side of the majority, it is time to pause and reflect." - Mark Twain
On Mon Apr 27 17:22:32 2009, KANE wrote: Show quoted text
> > I'd like a version.pm that behaves the same > in xs and pure perl. Whatever that behaviour should be I'm happy to > leave to the version.pm developers, but right now this can lead to > strange behaviours.
Sorry I didn't pay close enough attention this this the first time around. The code that vpp.pm uses to try and eliminate any exponential notation: # exponential notation if ( $value =~ /\d+.?\d*e-?\d+/ ) { $value = sprintf("%.9f",$value); $value =~ s/(0+)$//; # trim trailing zeros } wasn't tuned for very large numbers, but rather to very small numbers. If I change that regex to the correct form: # exponential notation if ( $value =~ /\d+.?\d*e[-+]?\d+/ ) { $value = sprintf("%.9f",$value); $value =~ s/(0+)$//; # trim trailing zeros } then it works even on 64-bit platforms. I have no way to formulate a portable test for that (since it involves creating a large-enough number to trigger Perl's exponential notation), so you'll just have to take my word on it that it works. ;-) John