diff --git a/Modules/cPickle.c b/Modules/cPickle.c index b87f4983f21..c61035d57b4 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -68,6 +68,20 @@ static char cPickle_module_documentation[] = #define WRITE_BUF_SIZE 256 +/* -------------------------------------------------------------------------- +NOTES on format codes. +XXX much more is needed here + +Integer types +BININT1 8-bit unsigned integer; followed by 1 byte. +BININT2 16-bit unsigned integer; followed by 2 bytes, little-endian. +BININT 32-bit signed integer; followed by 4 bytes, little-endian. +INT Integer; natural decimal string conversion, then newline. + CAUTION: INT-reading code can't assume that what follows + fits in a Python int, because the size of Python ints varies + across platforms. +LONG Long (unbounded) integer; repr(i), then newline. +-------------------------------------------------------------------------- */ #define MARK '(' #define STOP '.' @@ -904,18 +918,20 @@ save_int(Picklerobject *self, PyObject *args) { if (!self->bin #if SIZEOF_LONG > 4 - || (l >> 32) + || l > 0x7fffffffL + || l < -0x80000000L #endif - ) { - /* Save extra-long ints in non-binary mode, so that - we can use python long parsing code to restore, - if necessary. */ + ) { + /* Text-mode pickle, or long too big to fit in the 4-byte + * signed BININT format: store as a string. + */ c_str[0] = INT; sprintf(c_str + 1, "%ld\n", l); if ((*self->write_func)(self, c_str, strlen(c_str)) < 0) return -1; } else { + /* Binary pickle and l fits in a signed 4-byte int. */ c_str[1] = (int)( l & 0xff); c_str[2] = (int)((l >> 8) & 0xff); c_str[3] = (int)((l >> 16) & 0xff);