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

Skip to content

Commit e060619

Browse files
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.
1 parent d455a50 commit e060619

4 files changed

Lines changed: 43 additions & 1 deletion

File tree

Lib/pickle.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,14 @@ def load_binunicode8(self):
12041204
self.append(str(self.read(len), 'utf-8', 'surrogatepass'))
12051205
dispatch[BINUNICODE8[0]] = load_binunicode8
12061206

1207+
def load_binbytes8(self):
1208+
len, = unpack('<Q', self.read(8))
1209+
if len > maxsize:
1210+
raise UnpicklingError("BINBYTES8 exceeds system's maximum size "
1211+
"of %d bytes" % maxsize)
1212+
self.append(self.read(len))
1213+
dispatch[BINBYTES8[0]] = load_binbytes8
1214+
12071215
def load_short_binstring(self):
12081216
len = self.read(1)[0]
12091217
data = self.read(len)

Lib/test/pickletester.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,26 @@ def test_misc_get(self):
857857
self.assert_is_copy([(100,), (100,)],
858858
self.loads(b'((Kdtp0\nh\x00l.))'))
859859

860+
def test_binbytes8(self):
861+
dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
862+
self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')
863+
864+
def test_binunicode8(self):
865+
dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
866+
self.assertEqual(self.loads(dumped), '\u20ac\x00')
867+
868+
@requires_32b
869+
def test_large_32b_binbytes8(self):
870+
dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
871+
with self.assertRaises((pickle.UnpicklingError, OverflowError)):
872+
self.loads(dumped)
873+
874+
@requires_32b
875+
def test_large_32b_binunicode8(self):
876+
dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
877+
with self.assertRaises((pickle.UnpicklingError, OverflowError)):
878+
self.loads(dumped)
879+
860880
def test_get(self):
861881
pickled = b'((lp100000\ng100000\nt.'
862882
unpickled = self.loads(pickled)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ Core and Builtins
7878
Library
7979
-------
8080

81+
- Issue #25262. Added support for BINBYTES8 opcode in Python implementation of
82+
unpickler. Highest 32 bits of 64-bit size for BINUNICODE8 and BINBYTES8
83+
opcodes no longer silently ignored on 32-bit platforms in C implementation.
84+
8185
- Issue #25034: Fix string.Formatter problem with auto-numbering and
8286
nested format_specs. Patch by Anthon van der Neut.
8387

Modules/_pickle.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4540,7 +4540,17 @@ calc_binsize(char *bytes, int nbytes)
45404540
int i;
45414541
size_t x = 0;
45424542

4543-
for (i = 0; i < nbytes && i < sizeof(size_t); i++) {
4543+
if (nbytes > (int)sizeof(size_t)) {
4544+
/* Check for integer overflow. BINBYTES8 and BINUNICODE8 opcodes
4545+
* have 64-bit size that can't be represented on 32-bit platform.
4546+
*/
4547+
for (i = (int)sizeof(size_t); i < nbytes; i++) {
4548+
if (s[i])
4549+
return -1;
4550+
}
4551+
nbytes = (int)sizeof(size_t);
4552+
}
4553+
for (i = 0; i < nbytes; i++) {
45444554
x |= (size_t) s[i] << (8 * i);
45454555
}
45464556

0 commit comments

Comments
 (0)