Skip Menu |

This queue is for tickets about the Convert-IBM390 CPAN distribution.

Report information
The Basics
Id: 9518
Status: new
Priority: 0/
Queue: Convert-IBM390

People
Owner: Nobody in particular
Requestors: chris.madsen [...] trx.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.19
Fixed in: 0.20



Subject: Crash in Convert::IBM390::packeb
'make test' was failing with a segmentation fault on packeb. Also, unpackeb('p5.2') was returning the wrong numbers. The problem turned out to be a conflict with a library function named pow10, which was causing pow10[ndec] to return garbage instead of the proper power of 10. This wouldn't have caused a segfault, except that CF_num2packed & CF_num2zoned don't check for numbers that are too big. If you do something like packeb('p16', 1.0e99); you get a segfault. The attached patch: 1) renames pow10 to pows_of_10 and makes it static. This fixes the actual problem I was having. 2) changes CF_num2packed & CF_num2zoned to check the size of the number they're about to pass to sprintf. If it's too big, they exit with croak instead of segfaulting. The patch also includes two new tests to make sure behavior 2 is working. Even with this problem, Convert::IBM390 has been really useful. Thanks. Summary of my perl5 (revision 5.0 version 8 subversion 3) configuration: Platform: osname=linux, osvers=2.6.4, archname=i586-linux-thread-multi uname='linux d209 2.6.4 #1 smp thu mar 11 17:56:49 utc 2004 i686 i686 i386 gnulinux ' config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Duseshrplib=true -Doptimize=-O2 -march=i586 -mcpu=i686 -fmessage-length=0 -Wall -Wall -pipe' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef 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 -DTHREADS_HAVE_PIDS -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -march=i586 -mcpu=i686 -fmessage-length=0 -Wall -Wall -pipe', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing' ccversion='', gccversion='3.3.3 (SuSE Linux)', 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 ='' libpth=/lib /usr/lib /usr/local/lib libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.3.3' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.8.3/i586-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared'
--- Convert-IBM390-0.19/d/IBM390lib.ccc 2004-07-12 14:29:52.000000000 -0500 +++ Convert-IBM390-0.20/d/IBM390lib.ccc 2005-01-07 14:26:49.821436640 -0600 @@ -1,5 +1,10 @@ #include <stdio.h> #include <time.h> + +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + /*------------------------------------------------------------------- Module: Convert::IBM390 The C functions defined here are faster than straight Perl code. @@ -7,7 +12,7 @@ /* Powers of 10 */ -double pow10[32] = { 1.0, 10.0, 100.0, 1000.0, 10000.0, +static const double pows_of_10[32] = { 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 1.0E8, 1.0E9, 1.0E10, 1.0E11, 1.0E12, 1.0E13, 1.0E14, 1.0E15, 1.0E16, 1.0E17, 1.0E18, 1.0E19, 1.0E20, 1.0E21, 1.0E22, 1.0E23, @@ -71,7 +76,7 @@ /* If ndec is 0, we're finished; if it's nonzero, correct the number of decimal places. */ if ( ndec != 0 ) { - out_num = out_num / pow10[ndec]; + out_num = out_num / pows_of_10[ndec]; } #ifdef DEBUG390 @@ -103,12 +108,14 @@ } else { perl_absval = 0 - perlnum; signum = 0x0D; } + if (ndec) perl_absval *= pows_of_10[ndec]; + + if (perl_absval >= 1.0E31) { + croak("Number %g too long for packed decimal", perlnum); + } /* sprintf will round to an "integral" value. */ - if (ndec == 0) { sprintf(digits, "%031.0f", perl_absval); - } else { - sprintf(digits, "%031.0f", perl_absval * pow10[ndec]); - } + outdigits = outbytes * 2 - 1; digit_ptr = digits; out_ptr = packed_ptr; @@ -188,7 +195,7 @@ /* If ndec is 0, we're finished; if it's nonzero, correct the number of decimal places. */ if ( ndec != 0 ) { - out_num = out_num / pow10[ndec]; + out_num = out_num / pows_of_10[ndec]; } #ifdef DEBUG390 @@ -219,12 +226,15 @@ } else { perl_absval = 0 - perlnum; signum = 0xD0; } + + if (ndec) perl_absval *= pows_of_10[ndec]; + + if (perl_absval >= 1.0E31) { + croak("Number %g too long for zoned decimal", perlnum); + } /* sprintf will round to an "integral" value. */ - if (ndec == 0) { sprintf(digits, "%031.0f", perl_absval); - } else { - sprintf(digits, "%031.0f", perl_absval * pow10[ndec]); - } + digit_ptr = digits; out_ptr = zoned_ptr; for (i = 31 - outbytes; i < 31; i++) { --- Convert-IBM390-0.19/test.pl 2004-07-14 15:38:58.000000000 -0500 +++ Convert-IBM390-0.20/test.pl 2005-01-07 14:24:26.229265968 -0600 @@ -3,7 +3,7 @@ ################## We start with some black magic to print on failure. -BEGIN { $| = 1; print "1..11\n"; } +BEGIN { $| = 1; print "1..13\n"; } END {print "not ok 1\n" unless $loaded;} use Convert::IBM390 qw(:all); $loaded = 1; @@ -98,6 +98,15 @@ ($pp, $vv) = unpackeb("p2v", $ebrecord); was_it_ok_b(11, !defined($pp) && !defined($vv)); +#----- packeb with over-large numbers +print "packeb crash....."; +eval { packeb('p16', 1.0e99) }; +was_it_ok_b(12, $@ && $@ =~ /too long/); + +print " ....."; +eval { packeb('z32', 1.0e99) }; +was_it_ok_b(13, $@ && $@ =~ /too long/); + if ($failed == 0) { print "All tests successful.\n"; } else { $tt = ($failed == 1) ? "1 test" : "$failed tests";
Date: Mon, 10 Jan 2005 06:49:47 -0800 (PST)
From: Geoffrey Rommel <nazconsult [...] sbcglobal.net>
Subject: Re: [cpan #9518] Crash in Convert::IBM390::packeb
To: bug-Convert-IBM390 [...] rt.cpan.org
RT-Send-Cc:
Weird. Somebody else reported a similar bug, but I could never reproduce it. (I don't use gcc -- maybe that's it.) Anyhow, I will look into it. Thanks. wgr Christopher_J_Madsen via RT <bug-Convert-IBM390@rt.cpan.org> wrote: This message about Convert-IBM390 was sent to you by CJM via rt.cpan.org Full context and any attached attachments can be found at: 'make test' was failing with a segmentation fault on packeb. Also, unpackeb('p5.2') was returning the wrong numbers. The problem turned out to be a conflict with a library function named pow10, which was causing pow10[ndec] to return garbage instead of the proper power of 10. This wouldn't have caused a segfault, except that CF_num2packed & CF_num2zoned don't check for numbers that are too big. If you do something like packeb('p16', 1.0e99); you get a segfault. The attached patch: 1) renames pow10 to pows_of_10 and makes it static. This fixes the actual problem I was having. 2) changes CF_num2packed & CF_num2zoned to check the size of the number they're about to pass to sprintf. If it's too big, they exit with croak instead of segfaulting. The patch also includes two new tests to make sure behavior 2 is working. Even with this problem, Convert::IBM390 has been really useful. Thanks. Summary of my perl5 (revision 5.0 version 8 subversion 3) configuration: Platform: osname=linux, osvers=2.6.4, archname=i586-linux-thread-multi uname='linux d209 2.6.4 #1 smp thu mar 11 17:56:49 utc 2004 i686 i686 i386 gnulinux ' config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Duseshrplib=true -Doptimize=-O2 -march=i586 -mcpu=i686 -fmessage-length=0 -Wall -Wall -pipe' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef 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 -DTHREADS_HAVE_PIDS -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -march=i586 -mcpu=i686 -fmessage-length=0 -Wall -Wall -pipe', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -fno-strict-aliasing' ccversion='', gccversion='3.3.3 (SuSE Linux)', 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 ='' libpth=/lib /usr/lib /usr/local/lib libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.3.3' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.8.3/i586-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared'
From: Cat
I ran into this same problem and using your fix on #1 fixed it right up and allows the 'make test' to pass. I am using .... Convert-IBM390-0.19 Red Hat Enterprise Linux 2.4.21-15.ELsmp Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man -- infodir=/usr/share/info --enable-shared --enable-threads=posix -- disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386- redhat-linux Thread model: posix gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-34) [CJM - Fri Jan 7 15:57:21 2005]: Show quoted text
> 'make test' was failing with a segmentation fault on packeb. Also, > unpackeb('p5.2') was returning the wrong numbers. The problem > turned out to be a conflict with a library function named pow10, > which was causing pow10[ndec] to return garbage instead of the > proper power of 10. > > This wouldn't have caused a segfault, except that CF_num2packed & > CF_num2zoned don't check for numbers that are too big. If you do > something like > > packeb('p16', 1.0e99); > > you get a segfault. > > The attached patch: > 1) renames pow10 to pows_of_10 and makes it static. This fixes the > actual problem I was having. > > 2) changes CF_num2packed & CF_num2zoned to check the size of the > number they're about to pass to sprintf. If it's too big, they > exit with croak instead of segfaulting. > > The patch also includes two new tests to make sure behavior 2 is > working. > > Even with this problem, Convert::IBM390 has been really useful. > Thanks. > > > Summary of my perl5 (revision 5.0 version 8 subversion 3) > configuration: > Platform: > osname=linux, osvers=2.6.4, archname=i586-linux-thread-multi > uname='linux d209 2.6.4 #1 smp thu mar 11 17:56:49 utc 2004 i686 > i686 i386 gnulinux ' > config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr > -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm > -Duseshrplib=true -Doptimize=-O2 -march=i586 -mcpu=i686 > -fmessage-length=0 -Wall -Wall -pipe' > hint=recommended, useposix=true, d_sigaction=define > usethreads=define use5005threads=undef 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 -DTHREADS_HAVE_PIDS > -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', > optimize='-O2 -march=i586 -mcpu=i686 -fmessage-length=0 -Wall > -Wall -pipe', > cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS > -fno-strict-aliasing' > ccversion='', gccversion='3.3.3 (SuSE Linux)', 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 ='' > libpth=/lib /usr/lib /usr/local/lib > libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc > perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc > libc=, so=so, useshrplib=true, libperl=libperl.so > gnulibc_version='2.3.3' > Dynamic Linking: > dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='- > rdynamic > -Wl,-rpath,/usr/lib/perl5/5.8.3/i586-linux-thread-multi/CORE' > cccdlflags='-fPIC', lddlflags='-shared'
This fix was added in release 0.20. --wgr