Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bfa18f7

Browse files
committed
Critical fix: if cPickle on a sizeof(long)==8 box is used to read a
binary pickle, and the latter contains a pickle of a negative Python int i written on a sizeof(long)==4 box (and whether by cPickle or pickle.py), it's read incorrectly as i + 2**32. The patch repairs that, and allows test_cpickle.py (to which I added a relevant test case earlier today) to work again on sizeof(long)==8 boxes. There's another (at least one) sizeof(long)==8 binary pickle bug, but in pickle.py instead. That bug is still there, and test_pickle.py doesn't catch it yet (try pickling and unpickling, e.g., 1 << 46).
1 parent 4e6a7a6 commit bfa18f7

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

Modules/cPickle.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2528,7 +2528,14 @@ calc_binint(char *s, int x) {
25282528
c = (unsigned char)s[i];
25292529
l |= (long)c << (i * 8);
25302530
}
2531-
2531+
#if SIZEOF_LONG > 4
2532+
/* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
2533+
* is signed, so on a box with longs bigger than 4 bytes we need
2534+
* to extend a BININT's sign bit to the full width.
2535+
*/
2536+
if (x == 4 && l & (1L << 31))
2537+
l |= (~0L) << 32;
2538+
#endif
25322539
return l;
25332540
}
25342541

0 commit comments

Comments
 (0)