This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #92432] Storable::nfreeze shouldn't stringify ints
authorSam Kimbrel <kimbrel@me.com>
Tue, 21 Jun 2011 05:24:42 +0000 (22:24 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 21 Jun 2011 15:21:57 +0000 (08:21 -0700)
Storable::nfreeze's integer size check doesn't work correctly:

Using nfreeze to store an int larger than one byte produces a
frozen representation that thaws into a stringified integer, without
my having done string operations on the scalar beforehand.

I've confirmed this bug with the three versions I had available to me:
5.8.9 on 64-bit CentOS 4, 5.12.1 on 64-bit OS X 10.6, and
5.14.0 on 64-bit Debian squeeze.

The constants involved in the comparisons get created as 32-bit integers,
which wrap around and cause the comparison to yield true when it shouldn't.

This patch casts the constants before using them, which should make this
port correctly to 64-bit architectures. Running tests on a 64-bit Debian
host shows no problems.

dist/Storable/Storable.xs

index c6f9f70..fb25a78 100644 (file)
@@ -2117,9 +2117,9 @@ static int store_scalar(pTHX_ stcxt_t *cxt, SV *sv)
                 if (
 #ifdef SVf_IVisUV
                     /* Sorry. This isn't in 5.005_56 (IIRC) or earlier.  */
-                    ((flags & SVf_IVisUV) && SvUV(sv) > 0x7FFFFFFF) ||
+                    ((flags & SVf_IVisUV) && SvUV(sv) > (UV)0x7FFFFFFF) ||
 #endif
-                    (iv > 0x7FFFFFFF) || (iv < -0x80000000)) {
+                    (iv > (IV)0x7FFFFFFF) || (iv < -(IV)0x80000000)) {
                     /* Bigger than 32 bits.  */
                     TRACEME(("large network order integer as string, value = %"IVdf, iv));
                     goto string_readlen;