diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-01-23 11:21:21 (GMT) |
---|---|---|
committer | larryhastings <larry@hastings.org> | 2018-01-23 11:21:21 (GMT) |
commit | 43f014d3f12468edf61046f0612edc7660042fd5 (patch) | |
tree | 7f29fd3d15dddd271bd817f3fc9482640269bba3 /Lib/test | |
parent | 891c91d8d38848377a9f475242507510873eb9c3 (diff) | |
download | cpython-43f014d3f12468edf61046f0612edc7660042fd5.zip cpython-43f014d3f12468edf61046f0612edc7660042fd5.tar.gz cpython-43f014d3f12468edf61046f0612edc7660042fd5.tar.bz2 |
[3.5] bpo-32072: Fix issues with binary plists. (GH-4455) (#4656)
* [3.5] bpo-32072: Fix issues with binary plists. (GH-4455)
* Fixed saving bytearrays.
* Identical objects will be saved only once.
* Equal references will be load as identical objects.
* Added support for saving and loading recursive data structures.
(cherry picked from commit a897aee)
* Fix implementation dependent assertion in test_plistlib. (#4813)
It is failed with an advanced optimizer.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_plistlib.py | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index 692cac4..c9719e3 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -170,6 +170,17 @@ class TestPlistlib(unittest.TestCase): self.assertRaises(OverflowError, plistlib.dumps, pl, fmt=fmt) + def test_bytearray(self): + for pl in (b'<binary gunk>', b"<lots of binary gunk>\0\1\2\3" * 10): + for fmt in ALL_FORMATS: + with self.subTest(pl=pl, fmt=fmt): + data = plistlib.dumps(bytearray(pl), fmt=fmt) + pl2 = plistlib.loads(data) + self.assertIsInstance(pl2, bytes) + self.assertEqual(pl2, pl) + data2 = plistlib.dumps(pl2, fmt=fmt) + self.assertEqual(data, data2) + def test_bytes(self): pl = self._create() data = plistlib.dumps(pl) @@ -311,7 +322,8 @@ class TestPlistlib(unittest.TestCase): 'second': [1, 2], 'third': [3, 4], }) - self.assertIsNot(pl2['first'], pl2['second']) + if fmt != plistlib.FMT_BINARY: + self.assertIsNot(pl2['first'], pl2['second']) def test_list_members(self): pl = { @@ -423,6 +435,9 @@ class TestPlistlib(unittest.TestCase): pl2 = plistlib.loads(data) self.assertEqual(dict(pl), dict(pl2)) + +class TestBinaryPlistlib(unittest.TestCase): + def test_nonstandard_refs_size(self): # Issue #21538: Refs and offsets are 24-bit integers data = (b'bplist00' @@ -435,6 +450,47 @@ class TestPlistlib(unittest.TestCase): b'\x00\x00\x00\x00\x00\x00\x00\x13') self.assertEqual(plistlib.loads(data), {'a': 'b'}) + def test_dump_duplicates(self): + # Test effectiveness of saving duplicated objects + for x in (None, False, True, 12345, 123.45, 'abcde', b'abcde', + datetime.datetime(2004, 10, 26, 10, 33, 33), + plistlib.Data(b'abcde'), bytearray(b'abcde'), + [12, 345], (12, 345), {'12': 345}): + with self.subTest(x=x): + data = plistlib.dumps([x]*1000, fmt=plistlib.FMT_BINARY) + self.assertLess(len(data), 1100, repr(data)) + + def test_identity(self): + for x in (None, False, True, 12345, 123.45, 'abcde', b'abcde', + datetime.datetime(2004, 10, 26, 10, 33, 33), + plistlib.Data(b'abcde'), bytearray(b'abcde'), + [12, 345], (12, 345), {'12': 345}): + with self.subTest(x=x): + data = plistlib.dumps([x]*2, fmt=plistlib.FMT_BINARY) + a, b = plistlib.loads(data) + if isinstance(x, tuple): + x = list(x) + self.assertEqual(a, x) + self.assertEqual(b, x) + self.assertIs(a, b) + + def test_cycles(self): + # recursive list + a = [] + a.append(a) + b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) + self.assertIs(b[0], b) + # recursive tuple + a = ([],) + a[0].append(a) + b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) + self.assertIs(b[0][0], b) + # recursive dict + a = {} + a['x'] = a + b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) + self.assertIs(b['x'], b) + def test_large_timestamp(self): # Issue #26709: 32-bit timestamp out of range for ts in -2**31-1, 2**31: |