Commit e060619d authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #25262. Added support for BINBYTES8 opcode in Python implementation of

unpickler.  Highest 32 bits of 64-bit size for BINUNICODE8 and BINBYTES8
opcodes no longer silently ignored on 32-bit platforms in C implementation.
parent d455a507
...@@ -1204,6 +1204,14 @@ class _Unpickler: ...@@ -1204,6 +1204,14 @@ class _Unpickler:
self.append(str(self.read(len), 'utf-8', 'surrogatepass')) self.append(str(self.read(len), 'utf-8', 'surrogatepass'))
dispatch[BINUNICODE8[0]] = load_binunicode8 dispatch[BINUNICODE8[0]] = load_binunicode8
def load_binbytes8(self):
len, = unpack('<Q', self.read(8))
if len > maxsize:
raise UnpicklingError("BINBYTES8 exceeds system's maximum size "
"of %d bytes" % maxsize)
self.append(self.read(len))
dispatch[BINBYTES8[0]] = load_binbytes8
def load_short_binstring(self): def load_short_binstring(self):
len = self.read(1)[0] len = self.read(1)[0]
data = self.read(len) data = self.read(len)
......
...@@ -857,6 +857,26 @@ class AbstractUnpickleTests(unittest.TestCase): ...@@ -857,6 +857,26 @@ class AbstractUnpickleTests(unittest.TestCase):
self.assert_is_copy([(100,), (100,)], self.assert_is_copy([(100,), (100,)],
self.loads(b'((Kdtp0\nh\x00l.))')) self.loads(b'((Kdtp0\nh\x00l.))'))
def test_binbytes8(self):
dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
def test_binunicode8(self):
dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
self.assertEqual(self.loads(dumped), '\u20ac\x00')
@requires_32b
def test_large_32b_binbytes8(self):
dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
with self.assertRaises((pickle.UnpicklingError, OverflowError)):
self.loads(dumped)
@requires_32b
def test_large_32b_binunicode8(self):
dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
with self.assertRaises((pickle.UnpicklingError, OverflowError)):
self.loads(dumped)
def test_get(self): def test_get(self):
pickled = b'((lp100000\ng100000\nt.' pickled = b'((lp100000\ng100000\nt.'
unpickled = self.loads(pickled) unpickled = self.loads(pickled)
......
...@@ -78,6 +78,10 @@ Core and Builtins ...@@ -78,6 +78,10 @@ Core and Builtins
Library Library
------- -------
- Issue #25262. Added support for BINBYTES8 opcode in Python implementation of
unpickler. Highest 32 bits of 64-bit size for BINUNICODE8 and BINBYTES8
opcodes no longer silently ignored on 32-bit platforms in C implementation.
- Issue #25034: Fix string.Formatter problem with auto-numbering and - Issue #25034: Fix string.Formatter problem with auto-numbering and
nested format_specs. Patch by Anthon van der Neut. nested format_specs. Patch by Anthon van der Neut.
......
...@@ -4540,7 +4540,17 @@ calc_binsize(char *bytes, int nbytes) ...@@ -4540,7 +4540,17 @@ calc_binsize(char *bytes, int nbytes)
int i; int i;
size_t x = 0; size_t x = 0;
for (i = 0; i < nbytes && i < sizeof(size_t); i++) { if (nbytes > (int)sizeof(size_t)) {
/* Check for integer overflow. BINBYTES8 and BINUNICODE8 opcodes
* have 64-bit size that can't be represented on 32-bit platform.
*/
for (i = (int)sizeof(size_t); i < nbytes; i++) {
if (s[i])
return -1;
}
nbytes = (int)sizeof(size_t);
}
for (i = 0; i < nbytes; i++) {
x |= (size_t) s[i] << (8 * i); x |= (size_t) s[i] << (8 * i);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment