From 00987f6230fcdbecc8d9ab4b2b9fae8f99a1a4a9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 15 Nov 2017 17:41:05 +0200 Subject: [PATCH] bpo-32011: Revert "Issue #15480: Remove the deprecated and unused TYPE_INT64 code from marshal." (#4381) Simplify the reverted code. This reverts commit e9bbe8b87ba2874efba0474af5cc7d5941dbf742. --- Lib/test/test_marshal.py | 23 +++++++++++++++++++ .../2017-11-12-20-47-59.bpo-32011.NzVDdZ.rst | 2 ++ Python/marshal.c | 21 +++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-11-12-20-47-59.bpo-32011.NzVDdZ.rst diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index b378ffea00c..29dda987d0b 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -34,6 +34,29 @@ class IntTestCase(unittest.TestCase, HelperMixin): self.helper(expected) n = n >> 1 + def test_int64(self): + # Simulate int marshaling with TYPE_INT64. + maxint64 = (1 << 63) - 1 + minint64 = -maxint64-1 + for base in maxint64, minint64, -maxint64, -(minint64 >> 1): + while base: + s = b'I' + int.to_bytes(base, 8, 'little', signed=True) + got = marshal.loads(s) + self.assertEqual(base, got) + if base == -1: # a fixed-point for shifting right 1 + base = 0 + else: + base >>= 1 + + got = marshal.loads(b'I\xfe\xdc\xba\x98\x76\x54\x32\x10') + self.assertEqual(got, 0x1032547698badcfe) + got = marshal.loads(b'I\x01\x23\x45\x67\x89\xab\xcd\xef') + self.assertEqual(got, -0x1032547698badcff) + got = marshal.loads(b'I\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f') + self.assertEqual(got, 0x7f6e5d4c3b2a1908) + got = marshal.loads(b'I\xf7\xe6\xd5\xc4\xb3\xa2\x91\x80') + self.assertEqual(got, -0x7f6e5d4c3b2a1909) + def test_bool(self): for b in (True, False): self.helper(b) diff --git a/Misc/NEWS.d/next/Library/2017-11-12-20-47-59.bpo-32011.NzVDdZ.rst b/Misc/NEWS.d/next/Library/2017-11-12-20-47-59.bpo-32011.NzVDdZ.rst new file mode 100644 index 00000000000..e2ba502c657 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-12-20-47-59.bpo-32011.NzVDdZ.rst @@ -0,0 +1,2 @@ +Restored support of loading marshal files with the TYPE_INT64 code. These +files can be produced in Python 2.7. diff --git a/Python/marshal.c b/Python/marshal.c index 7b583eef1a1..e23daf6497b 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -39,6 +39,9 @@ module marshal #define TYPE_STOPITER 'S' #define TYPE_ELLIPSIS '.' #define TYPE_INT 'i' +/* TYPE_INT64 is not generated anymore. + Supported for backward compatibility only. */ +#define TYPE_INT64 'I' #define TYPE_FLOAT 'f' #define TYPE_BINARY_FLOAT 'g' #define TYPE_COMPLEX 'x' @@ -783,6 +786,19 @@ r_long(RFILE *p) return x; } +/* r_long64 deals with the TYPE_INT64 code. */ +static PyObject * +r_long64(RFILE *p) +{ + const unsigned char *buffer = (const unsigned char *) r_string(8, p); + if (buffer == NULL) { + return NULL; + } + return _PyLong_FromByteArray(buffer, 8, + 1 /* little endian */, + 1 /* signed */); +} + static PyObject * r_PyLong(RFILE *p) { @@ -982,6 +998,11 @@ r_object(RFILE *p) R_REF(retval); break; + case TYPE_INT64: + retval = r_long64(p); + R_REF(retval); + break; + case TYPE_LONG: retval = r_PyLong(p); R_REF(retval);