mirror of https://github.com/python/cpython
Issue #21538: The plistlib module now supports loading of binary plist files
when reference or offset size is not a power of two.
This commit is contained in:
commit
c083537b87
|
@ -619,10 +619,7 @@ class _BinaryPlistParser:
|
|||
offset_table_offset
|
||||
) = struct.unpack('>6xBBQQQ', trailer)
|
||||
self._fp.seek(offset_table_offset)
|
||||
offset_format = '>' + _BINARY_FORMAT[offset_size] * num_objects
|
||||
self._ref_format = _BINARY_FORMAT[self._ref_size]
|
||||
self._object_offsets = struct.unpack(
|
||||
offset_format, self._fp.read(offset_size * num_objects))
|
||||
self._object_offsets = self._read_ints(num_objects, offset_size)
|
||||
return self._read_object(self._object_offsets[top_object])
|
||||
|
||||
except (OSError, IndexError, struct.error):
|
||||
|
@ -638,9 +635,16 @@ class _BinaryPlistParser:
|
|||
|
||||
return tokenL
|
||||
|
||||
def _read_ints(self, n, size):
|
||||
data = self._fp.read(size * n)
|
||||
if size in _BINARY_FORMAT:
|
||||
return struct.unpack('>' + _BINARY_FORMAT[size] * n, data)
|
||||
else:
|
||||
return tuple(int.from_bytes(data[i: i + size], 'big')
|
||||
for i in range(0, size * n, size))
|
||||
|
||||
def _read_refs(self, n):
|
||||
return struct.unpack(
|
||||
'>' + self._ref_format * n, self._fp.read(n * self._ref_size))
|
||||
return self._read_ints(n, self._ref_size)
|
||||
|
||||
def _read_object(self, offset):
|
||||
"""
|
||||
|
|
|
@ -411,6 +411,18 @@ class TestPlistlib(unittest.TestCase):
|
|||
pl2 = plistlib.loads(data)
|
||||
self.assertEqual(dict(pl), dict(pl2))
|
||||
|
||||
def test_nonstandard_refs_size(self):
|
||||
# Issue #21538: Refs and offsets are 24-bit integers
|
||||
data = (b'bplist00'
|
||||
b'\xd1\x00\x00\x01\x00\x00\x02QaQb'
|
||||
b'\x00\x00\x08\x00\x00\x0f\x00\x00\x11'
|
||||
b'\x00\x00\x00\x00\x00\x00'
|
||||
b'\x03\x03'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x03'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x13')
|
||||
self.assertEqual(plistlib.loads(data), {'a': 'b'})
|
||||
|
||||
|
||||
class TestPlistlibDeprecated(unittest.TestCase):
|
||||
def test_io_deprecated(self):
|
||||
|
|
|
@ -89,6 +89,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #21538: The plistlib module now supports loading of binary plist files
|
||||
when reference or offset size is not a power of two.
|
||||
|
||||
- Issue #21455: Add a default backlog to socket.listen().
|
||||
|
||||
- Issue #21525: Most Tkinter methods which accepted tuples now accept lists too.
|
||||
|
|
Loading…
Reference in New Issue