summaryrefslogtreecommitdiffstats
path: root/Modules/cPickle.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-04-10 01:54:42 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-04-10 01:54:42 (GMT)
commitbfa18f711f01477b143aab37921eafabc0cb38fb (patch)
tree49824803bd8fe4e92cec93e59b74061feef1f000 /Modules/cPickle.c
parent4e6a7a626de58887c270461a546cde5f435e6178 (diff)
downloadcpython-bfa18f711f01477b143aab37921eafabc0cb38fb.zip
cpython-bfa18f711f01477b143aab37921eafabc0cb38fb.tar.gz
cpython-bfa18f711f01477b143aab37921eafabc0cb38fb.tar.bz2
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).
Diffstat (limited to 'Modules/cPickle.c')
-rw-r--r--Modules/cPickle.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
index 92325b6..b87f498 100644
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -2528,7 +2528,14 @@ calc_binint(char *s, int x) {
c = (unsigned char)s[i];
l |= (long)c << (i * 8);
}
-
+#if SIZEOF_LONG > 4
+ /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
+ * is signed, so on a box with longs bigger than 4 bytes we need
+ * to extend a BININT's sign bit to the full width.
+ */
+ if (x == 4 && l & (1L << 31))
+ l |= (~0L) << 32;
+#endif
return l;
}