diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2014-05-23 13:15:06 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2014-05-23 13:15:06 (GMT) |
commit | c083537b8731c8f2ffe607a12f96a3eb95f788f7 (patch) | |
tree | c1687e6f23de98a1f0b8787a89af8516a9b5e60c | |
parent | a7834d31c7cec6948f56d5f0b9c9a5ff29b5d05e (diff) | |
parent | 065266450ea5519a43bcc199e48d304f1e7038e8 (diff) | |
download | cpython-c083537b8731c8f2ffe607a12f96a3eb95f788f7.zip cpython-c083537b8731c8f2ffe607a12f96a3eb95f788f7.tar.gz cpython-c083537b8731c8f2ffe607a12f96a3eb95f788f7.tar.bz2 |
Issue #21538: The plistlib module now supports loading of binary plist files
when reference or offset size is not a power of two.
-rw-r--r-- | Lib/plistlib.py | 16 | ||||
-rw-r--r-- | Lib/test/test_plistlib.py | 12 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 25 insertions, 6 deletions
diff --git a/Lib/plistlib.py b/Lib/plistlib.py index dcb0f9c..8c148a8 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -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): """ diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index bb7cc15..dc2fdf6 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -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. |