Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hex "e" misunderstood by Math::BigRat #9786

Closed
p5pRT opened this issue Jul 5, 2009 · 8 comments
Closed

hex "e" misunderstood by Math::BigRat #9786

p5pRT opened this issue Jul 5, 2009 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 5, 2009

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

Searchable as RT67244$

@p5pRT
Copy link
Author

p5pRT commented Jul 5, 2009

From zefram@fysh.org

Created by zefram@fysh.org

$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7d")'
125
$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7e")'
Use of uninitialized value in subroutine entry at /usr/share/perl/5.10/Math/BigFloat.pm line 193.
Can't use an undefined value as a SCALAR reference at /usr/share/perl/5.10/Math/BigFloat.pm line 194.
$

Looks like whatever's interpreting the input string sees the "e" and
decides that it must be a decimal-with-exponent input, such as "1.2e3".
It then falls over because the input isn't actually of that form. "1.2e3"
itself is interpreted as 1200.

The error message generated varies according to which Math​::BigInt backend
is used. All four that I tried (Calc, FastCalc, GMP, Pari) do error on
"0x7e", and don't error on "0x7d".

Math​::BigInt does not get confused. It handles "0x7e" correctly,
regardless of backend.

Perl Info

Flags:
    category=library
    severity=medium

Site configuration information for perl 5.10.0:

Configured by Debian Project at Thu Jan  1 12:43:38 UTC 2009.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.6.26-1-686, archname=i486-linux-gnu-thread-multi
    uname='linux rebekka 2.6.26-1-686 #1 smp mon dec 15 18:15:07 utc 2008 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.0 -Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    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, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/lib64
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.7.so, so=so, useshrplib=true, libperl=libperl.so.5.10.0
    gnulibc_version='2.7'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib'

Locally applied patches:
    


@INC for perl 5.10.0:
    /etc/perl
    /usr/local/lib/perl/5.10.0
    /usr/local/share/perl/5.10.0
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.10
    /usr/share/perl/5.10
    /usr/local/lib/site_perl
    .


Environment for perl 5.10.0:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/pub/i686-pc-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2009

From @sisyphus

----- Original Message -----
From​: "Zefram (via RT)" <perlbug-followup@​perl.org>
To​: <bugs-bitbucket@​netlabs.develooper.com>

$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7d")'
125
$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7e")'
Use of uninitialized value in subroutine entry at
/usr/share/perl/5.10/Math/BigFloat.pm line 193.
Can't use an undefined value as a SCALAR reference at
/usr/share/perl/5.10/Math/BigFloat.pm line 194.

This is fixed by the following patch​:

####################################
C​:\bleadperl\lib\Math>diff -u BigRat.pm_orig BigRat.pm

Inline Patch
--- BigRat.pm_orig      Mon Jul  6 21:08:19 2009
+++ BigRat.pm   Mon Jul  6 21:22:01 2009
@@ -191,7 +191,7 @@
     return $class->bnan() if $n =~ /\/\s*$/;   # 1/ isn't valid
     ($n,$d) = split (/\//,$n);
     # try as BigFloats first
-    if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/))
+    if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/) && $n !~ /^0x/)
       {
       local $Math::BigFloat::accuracy = undef;
       local $Math::BigFloat::precision = undef;
@@ -279,7 +279,7 @@
     }

   # simple string input
-  if (($n =~ /[\.eE]/))
+  if (($n =~ /[\.eE]/ && $n !~ /^0x/))
     {
     # looks like a float, quacks like a float, so probably is a float
     $self->{sign} = 'NaN';
####################################

All I've done is insert the "$n !~ /^0x/" condition in two places. It's the
second insertion that fixes the problem - the first insertion has no bearing
on the actual problem as reported, but might be a good idea anyway (or might
not be necessary at all).

And I *haven't* checked if that patch breaks anything else :-)

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2009

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2009

From @jimc

On Mon, Jul 6, 2009 at 7​:38 AM, Sisyphus<sisyphus1@​optusnet.com.au> wrote​:

----- Original Message ----- From​: "Zefram (via RT)"
<perlbug-followup@​perl.org>
To​: <bugs-bitbucket@​netlabs.develooper.com>

$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7d")'
125
$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7e")'
Use of uninitialized value in subroutine entry at
/usr/share/perl/5.10/Math/BigFloat.pm line 193.
Can't use an undefined value as a SCALAR reference at
/usr/share/perl/5.10/Math/BigFloat.pm line 194.

This is fixed by the following patch​:

####################################
C​:\bleadperl\lib\Math>diff -u BigRat.pm_orig BigRat.pm
--- BigRat.pm_orig      Mon Jul  6 21​:08​:19 2009
+++ BigRat.pm   Mon Jul  6 21​:22​:01 2009
@​@​ -191,7 +191,7 @​@​
   return $class->bnan() if $n =~ /\/\s*$/;   # 1/ isn't valid
   ($n,$d) = split (/\//,$n);
   # try as BigFloats first
-    if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/))
+    if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/) && $n !~ /^0x/)
     {
     local $Math​::BigFloat​::accuracy = undef;
     local $Math​::BigFloat​::precision = undef;
@​@​ -279,7 +279,7 @​@​
   }

 # simple string input
-  if (($n =~ /[\.eE]/))
+  if (($n =~ /[\.eE]/ && $n !~ /^0x/))
   {
   # looks like a float, quacks like a float, so probably is a float
   $self->{sign} = 'NaN';
####################################

All I've done is insert the "$n !~ /^0x/" condition in two places. It's the
second insertion that fixes the problem - the first insertion has no bearing
on the actual problem as reported, but might be a good idea anyway (or might
not be necessary at all).

And I *haven't* checked if that patch breaks anything else :-)

Cheers,
Rob

patch passed all current tests here,
but *none* of the new ones (hint)

Summary of my perl5 (revision 5 version 11 subversion 0) configuration​:
  Commit id​: cceec05
  Platform​:
  osname=linux, osvers=2.6.29.5-191.fc11.i586,
archname=i686-linux-thread-multi
  uname='linux harpo.jimc.earth 2.6.29.5-191.fc11.i586 #1 smp tue
jun 16 23​:11​:39 edt 2009 i686 i686 i386 gnulinux '
  config_args='-des -Dusedevel'
  hint=previous, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2 -g',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include
-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64'
  ccversion='', gccversion='4.4.0 20090506 (Red Hat 4.4.0-4)', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  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, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
  libc=/lib/libc-2.10.1.so, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.10.1'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib
-fstack-protector'

Characteristics of this binary (from libperl)​:
  Compile-time options​: DEBUGGING MULTIPLICITY PERL_DONT_CREATE_GVSV
  PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
  PERL_TRACK_MEMPOOL PERL_USE_DEVEL USE_ITHREADS
  USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API
  Built under linux
  Compiled at Jul 6 2009 08​:49​:11
  @​INC​:
  lib
  /usr/local/lib/perl5/site_perl/5.11.0/i686-linux-thread-multi
  /usr/local/lib/perl5/site_perl/5.11.0
  /usr/local/lib/perl5/5.11.0/i686-linux-thread-multi
  /usr/local/lib/perl5/5.11.0
  /usr/local/lib/perl5/site_perl

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2009

From jaleto@gmail.com

Howdy,

Since I am co-maintainer of Math​::BigRat and TELS informed me that he
did not have time to maintain his modules, I am jumping in here. I
have created a git repo which lives on github [0] (as well as my
private mirror if github is down [1]).

I suggest this patch as a fix for this issue, which includes two new tests​:

$ git diff v0.22

Inline Patch
diff --git a/lib/Math/BigRat.pm b/lib/Math/BigRat.pm
index 6d77f98..570daef 100644
--- a/lib/Math/BigRat.pm
+++ b/lib/Math/BigRat.pm
@@ -279,7 +279,7 @@ sub new
     }

   # simple string input
-  if (($n =~ /[\.eE]/))
+  if (($n =~ /[\.eE]/) && $n !~ /^0x/)
     {
     # looks like a float, quacks like a float, so probably is a float
     $self->{sign} = 'NaN';
diff --git a/t/bigrat.t b/t/bigrat.t
index d898335..c7563e5 100755
--- a/t/bigrat.t
+++ b/t/bigrat.t
@@ -8,7 +8,7 @@ BEGIN
   $| = 1;
   chdir 't' if -d 't';
   unshift @INC, '../lib'; # for running manually
-  plan tests => 198;
+  plan tests => 200;
   }

 # basic testing of Math::BigRat
@@ -53,6 +53,8 @@ foreach my $func (qw/new bnorm/)
   $x = $cr->$func('-inf');     ok ($x,'-inf');
   $x = $cr->$func('1/');       ok ($x,'NaN');

+  $x = $cr->$func("0x7e");  ok($x, 126);
+
   # input ala '1+1/3' isn't parsed ok yet
   $x = $cr->$func('1+1/3');    ok ($x,'NaN');


The reason I do not include the additional checks that Sisyphus suggested is because I wrote more tests which did not pass with his patch\. This smaller patch only fixes the problem at hand \( Math​::BigRat still borks on \->new\("0x7e/0x7e"\) \) but has smaller probability of unintentional/untested side\-effects\.

I have created a "hex" topic branch to fully fix this issue. [2]

PS​: So I should be updating Porting/Maintainers.pl, right?

Cheers,

[0] http​://github.com/leto/Math-BigRat/tree/master
[1] http​://leto.net/gitweb/?p=Math-BigRat.git
[2] http​://github.com/leto/Math-BigRat/tree/hex

On Mon, Jul 6, 2009 at 8​:18 AM, Jim Cromie<jim.cromie@​gmail.com> wrote​:

On Mon, Jul 6, 2009 at 7​:38 AM, Sisyphus<sisyphus1@​optusnet.com.au> wrote​:

----- Original Message ----- From​: "Zefram (via RT)"
<perlbug-followup@​perl.org>
To​: <bugs-bitbucket@​netlabs.develooper.com>

$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7d")'
125
$ perl -MMath​::BigRat -lwe 'print Math​::BigRat->new("0x7e")'
Use of uninitialized value in subroutine entry at
/usr/share/perl/5.10/Math/BigFloat.pm line 193.
Can't use an undefined value as a SCALAR reference at
/usr/share/perl/5.10/Math/BigFloat.pm line 194.

This is fixed by the following patch​:

####################################
C​:\bleadperl\lib\Math>diff -u BigRat.pm_orig BigRat.pm
--- BigRat.pm_orig      Mon Jul  6 21​:08​:19 2009
+++ BigRat.pm   Mon Jul  6 21​:22​:01 2009
@​@​ -191,7 +191,7 @​@​
   return $class->bnan() if $n =~ /\/\s*$/;   # 1/ isn't valid
   ($n,$d) = split (/\//,$n);
   # try as BigFloats first
-    if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/))
+    if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/) && $n !~ /^0x/)
     {
     local $Math​::BigFloat​::accuracy = undef;
     local $Math​::BigFloat​::precision = undef;
@​@​ -279,7 +279,7 @​@​
   }

 # simple string input
-  if (($n =~ /[\.eE]/))
+  if (($n =~ /[\.eE]/ && $n !~ /^0x/))
   {
   # looks like a float, quacks like a float, so probably is a float
   $self->{sign} = 'NaN';
####################################

All I've done is insert the "$n !~ /^0x/" condition in two places. It's the
second insertion that fixes the problem - the first insertion has no bearing
on the actual problem as reported, but might be a good idea anyway (or might
not be necessary at all).

And I *haven't* checked if that patch breaks anything else :-)

Cheers,
Rob

patch passed all current tests here,
but *none* of the new ones (hint)

Summary of my perl5 (revision 5 version 11 subversion 0) configuration​:
 Commit id​: cceec05
 Platform​:
   osname=linux, osvers=2.6.29.5-191.fc11.i586,
archname=i686-linux-thread-multi
   uname='linux harpo.jimc.earth 2.6.29.5-191.fc11.i586 #1 smp tue
jun 16 23​:11​:39 edt 2009 i686 i686 i386 gnulinux '
   config_args='-des -Dusedevel'
   hint=previous, useposix=true, d_sigaction=define
   useithreads=define, usemultiplicity=define
   useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
   use64bitint=undef, use64bitall=undef, uselongdouble=undef
   usemymalloc=n, bincompat5005=undef
 Compiler​:
   cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
   optimize='-O2 -g',
   cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include
-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64'
   ccversion='', gccversion='4.4.0 20090506 (Red Hat 4.4.0-4)', gccosandvers=''
   intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
   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, prototype=define
 Linker and Libraries​:
   ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
   libpth=/usr/local/lib /lib /usr/lib
   libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
   perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
   libc=/lib/libc-2.10.1.so, so=so, useshrplib=false, libperl=libperl.a
   gnulibc_version='2.10.1'
 Dynamic Linking​:
   dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
   cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib
-fstack-protector'

Characteristics of this binary (from libperl)​:
 Compile-time options​: DEBUGGING MULTIPLICITY PERL_DONT_CREATE_GVSV
                       PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                       PERL_TRACK_MEMPOOL PERL_USE_DEVEL USE_ITHREADS
                       USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API
 Built under linux
 Compiled at Jul  6 2009 08​:49​:11
 @​INC​:
   lib
   /usr/local/lib/perl5/site_perl/5.11.0/i686-linux-thread-multi
   /usr/local/lib/perl5/site_perl/5.11.0
   /usr/local/lib/perl5/5.11.0/i686-linux-thread-multi
   /usr/local/lib/perl5/5.11.0
   /usr/local/lib/perl5/site_perl

--

Jonathan Leto
jonathan@​leto.net
http​://leto.net

@p5pRT
Copy link
Author

p5pRT commented Jul 7, 2009

From @rgs

2009/7/7 Jonathan Leto <jaleto@​gmail.com>​:

PS​: So I should be updating Porting/Maintainers.pl, right?

Yes.

In the list of things that might be nice to do in blead (but won't be
in 5.10.1), is that you can move Math-BigRat from lib/ to a new
subdirectory ext/Math-BigRat that would be in sync with the CPAN dist.
Which is the plan for most modules.

I'm not sure if there is yet a sane solution (that is, not submodules)
to use your Math-BigRat repository as a kind of remote for the future
ext/Math-BigRat subdir in blead.

[0] http​://github.com/leto/Math-BigRat/tree/master
[1] http​://leto.net/gitweb/?p=Math-BigRat.git
[2] http​://github.com/leto/Math-BigRat/tree/hex

@p5pRT
Copy link
Author

p5pRT commented Jul 20, 2016

From @dcollinsn

Fixed in 5.12.0.

--
Respectfully,
Dan Collins

@p5pRT
Copy link
Author

p5pRT commented Jul 20, 2016

@dcollinsn - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant