diff --git a/ChangeLog b/ChangeLog index 102eafb549..3207b2a717 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri May 23 15:16:16 2003 Nobuyoshi Nakada + + * pack.c (pack_unpack): sign-extend if sizeof long is bigger than + 32. (ruby-bugs-ja:PR#472) + Thu May 22 18:07:46 2003 why the lucky stiff * lib/token.c: single- and double-quoted root-level fix. diff --git a/pack.c b/pack.c index 58aa5d4105..b0b51c1b2a 100644 --- a/pack.c +++ b/pack.c @@ -351,6 +351,18 @@ num2u32(x) # endif #endif +#if SIZEOF_LONG == SIZE32 || SIZEOF_INT == SIZE32 +# define EXTEND32(x) ((I32)(x)) +#else +/* invariant in modulo 1<<31 */ +# define EXTEND32(x) (I32)(((1<<31)-1-(x))^~(~0<<31)) +#endif +#if SIZEOF_SHORT == SIZE16 +# define EXTEND16(x) (short)(x) +#else +# define EXTEND16(x) (short)(((1<<15)-1-(x))^~(~0<<15)) +#endif + #ifdef HAVE_LONG_LONG # define QUAD_SIZE sizeof(LONG_LONG) #else @@ -1317,6 +1329,9 @@ pack_unpack(str, fmt) while (len-- > 0) { short tmp = 0; memcpy(OFF16(&tmp), s, NATINT_LEN(short,2)); +#if SIZEOF_SHORT != SIZE16 + if (!natint) tmp = EXTEND16(tmp); +#endif s += NATINT_LEN(short,2); rb_ary_push(ary, INT2FIX(tmp)); } @@ -1361,6 +1376,9 @@ pack_unpack(str, fmt) while (len-- > 0) { long tmp = 0; memcpy(OFF32(&tmp), s, NATINT_LEN(long,4)); +#if SIZEOF_LONG != SIZE32 + if (!natint) tmp = EXTEND32(tmp); +#endif s += NATINT_LEN(long,4); rb_ary_push(ary, LONG2NUM(tmp)); }