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

Skip to content

Commit 0652664

Browse files
Issue #21538: The plistlib module now supports loading of binary plist files
when reference or offset size is not a power of two.
1 parent f01fffe commit 0652664

3 files changed

Lines changed: 28 additions & 6 deletions

File tree

Lib/plistlib.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,7 @@ def parse(self, fp):
619619
offset_table_offset
620620
) = struct.unpack('>6xBBQQQ', trailer)
621621
self._fp.seek(offset_table_offset)
622-
offset_format = '>' + _BINARY_FORMAT[offset_size] * num_objects
623-
self._ref_format = _BINARY_FORMAT[self._ref_size]
624-
self._object_offsets = struct.unpack(
625-
offset_format, self._fp.read(offset_size * num_objects))
622+
self._object_offsets = self._read_ints(num_objects, offset_size)
626623
return self._read_object(self._object_offsets[top_object])
627624

628625
except (OSError, IndexError, struct.error):
@@ -638,9 +635,16 @@ def _get_size(self, tokenL):
638635

639636
return tokenL
640637

638+
def _read_ints(self, n, size):
639+
data = self._fp.read(size * n)
640+
if size in _BINARY_FORMAT:
641+
return struct.unpack('>' + _BINARY_FORMAT[size] * n, data)
642+
else:
643+
return tuple(int.from_bytes(data[i: i + size], 'big')
644+
for i in range(0, size * n, size))
645+
641646
def _read_refs(self, n):
642-
return struct.unpack(
643-
'>' + self._ref_format * n, self._fp.read(n * self._ref_size))
647+
return self._read_ints(n, self._ref_size)
644648

645649
def _read_object(self, offset):
646650
"""

Lib/test/test_plistlib.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,18 @@ def test_xml_encodings(self):
411411
pl2 = plistlib.loads(data)
412412
self.assertEqual(dict(pl), dict(pl2))
413413

414+
def test_nonstandard_refs_size(self):
415+
# Issue #21538: Refs and offsets are 24-bit integers
416+
data = (b'bplist00'
417+
b'\xd1\x00\x00\x01\x00\x00\x02QaQb'
418+
b'\x00\x00\x08\x00\x00\x0f\x00\x00\x11'
419+
b'\x00\x00\x00\x00\x00\x00'
420+
b'\x03\x03'
421+
b'\x00\x00\x00\x00\x00\x00\x00\x03'
422+
b'\x00\x00\x00\x00\x00\x00\x00\x00'
423+
b'\x00\x00\x00\x00\x00\x00\x00\x13')
424+
self.assertEqual(plistlib.loads(data), {'a': 'b'})
425+
414426

415427
class TestPlistlibDeprecated(unittest.TestCase):
416428
def test_io_deprecated(self):

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ Core and Builtins
1515
time issue noticeable when compiling code with a large number of "and"
1616
and "or" operators.
1717

18+
Library
19+
-------
20+
21+
- Issue #21538: The plistlib module now supports loading of binary plist files
22+
when reference or offset size is not a power of two.
23+
1824
Tests
1925
-----
2026

0 commit comments

Comments
 (0)