17db96d56Sopenharmony_ci# Copyright (C) 2003-2013 Python Software Foundation 27db96d56Sopenharmony_ciimport copy 37db96d56Sopenharmony_ciimport operator 47db96d56Sopenharmony_ciimport pickle 57db96d56Sopenharmony_ciimport struct 67db96d56Sopenharmony_ciimport unittest 77db96d56Sopenharmony_ciimport plistlib 87db96d56Sopenharmony_ciimport os 97db96d56Sopenharmony_ciimport sys 107db96d56Sopenharmony_ciimport json 117db96d56Sopenharmony_ciimport datetime 127db96d56Sopenharmony_ciimport codecs 137db96d56Sopenharmony_ciimport subprocess 147db96d56Sopenharmony_ciimport binascii 157db96d56Sopenharmony_ciimport collections 167db96d56Sopenharmony_cifrom test import support 177db96d56Sopenharmony_cifrom test.support import os_helper 187db96d56Sopenharmony_cifrom io import BytesIO 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_cifrom plistlib import UID 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ciALL_FORMATS=(plistlib.FMT_XML, plistlib.FMT_BINARY) 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci# The testdata is generated using Mac/Tools/plistlib_generate_testdata.py 257db96d56Sopenharmony_ci# (which using PyObjC to control the Cocoa classes for generating plists) 267db96d56Sopenharmony_ciTESTDATA={ 277db96d56Sopenharmony_ci plistlib.FMT_XML: binascii.a2b_base64(b''' 287db96d56Sopenharmony_ci PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NU 297db96d56Sopenharmony_ci WVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VO 307db96d56Sopenharmony_ci IiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4w 317db96d56Sopenharmony_ci LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YUJp 327db96d56Sopenharmony_ci Z0ludDwva2V5PgoJPGludGVnZXI+OTIyMzM3MjAzNjg1NDc3NTc2NDwvaW50 337db96d56Sopenharmony_ci ZWdlcj4KCTxrZXk+YUJpZ0ludDI8L2tleT4KCTxpbnRlZ2VyPjkyMjMzNzIw 347db96d56Sopenharmony_ci MzY4NTQ3NzU4NTI8L2ludGVnZXI+Cgk8a2V5PmFEYXRlPC9rZXk+Cgk8ZGF0 357db96d56Sopenharmony_ci ZT4yMDA0LTEwLTI2VDEwOjMzOjMzWjwvZGF0ZT4KCTxrZXk+YURpY3Q8L2tl 367db96d56Sopenharmony_ci eT4KCTxkaWN0PgoJCTxrZXk+YUZhbHNlVmFsdWU8L2tleT4KCQk8ZmFsc2Uv 377db96d56Sopenharmony_ci PgoJCTxrZXk+YVRydWVWYWx1ZTwva2V5PgoJCTx0cnVlLz4KCQk8a2V5PmFV 387db96d56Sopenharmony_ci bmljb2RlVmFsdWU8L2tleT4KCQk8c3RyaW5nPk3DpHNzaWcsIE1hw588L3N0 397db96d56Sopenharmony_ci cmluZz4KCQk8a2V5PmFub3RoZXJTdHJpbmc8L2tleT4KCQk8c3RyaW5nPiZs 407db96d56Sopenharmony_ci dDtoZWxsbyAmYW1wOyAnaGknIHRoZXJlISZndDs8L3N0cmluZz4KCQk8a2V5 417db96d56Sopenharmony_ci PmRlZXBlckRpY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5hPC9rZXk+CgkJ 427db96d56Sopenharmony_ci CTxpbnRlZ2VyPjE3PC9pbnRlZ2VyPgoJCQk8a2V5PmI8L2tleT4KCQkJPHJl 437db96d56Sopenharmony_ci YWw+MzIuNTwvcmVhbD4KCQkJPGtleT5jPC9rZXk+CgkJCTxhcnJheT4KCQkJ 447db96d56Sopenharmony_ci CTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8aW50ZWdlcj4yPC9pbnRlZ2Vy 457db96d56Sopenharmony_ci PgoJCQkJPHN0cmluZz50ZXh0PC9zdHJpbmc+CgkJCTwvYXJyYXk+CgkJPC9k 467db96d56Sopenharmony_ci aWN0PgoJPC9kaWN0PgoJPGtleT5hRmxvYXQ8L2tleT4KCTxyZWFsPjAuNTwv 477db96d56Sopenharmony_ci cmVhbD4KCTxrZXk+YUxpc3Q8L2tleT4KCTxhcnJheT4KCQk8c3RyaW5nPkE8 487db96d56Sopenharmony_ci L3N0cmluZz4KCQk8c3RyaW5nPkI8L3N0cmluZz4KCQk8aW50ZWdlcj4xMjwv 497db96d56Sopenharmony_ci aW50ZWdlcj4KCQk8cmVhbD4zMi41PC9yZWFsPgoJCTxhcnJheT4KCQkJPGlu 507db96d56Sopenharmony_ci dGVnZXI+MTwvaW50ZWdlcj4KCQkJPGludGVnZXI+MjwvaW50ZWdlcj4KCQkJ 517db96d56Sopenharmony_ci PGludGVnZXI+MzwvaW50ZWdlcj4KCQk8L2FycmF5PgoJPC9hcnJheT4KCTxr 527db96d56Sopenharmony_ci ZXk+YU5lZ2F0aXZlQmlnSW50PC9rZXk+Cgk8aW50ZWdlcj4tODAwMDAwMDAw 537db96d56Sopenharmony_ci MDA8L2ludGVnZXI+Cgk8a2V5PmFOZWdhdGl2ZUludDwva2V5PgoJPGludGVn 547db96d56Sopenharmony_ci ZXI+LTU8L2ludGVnZXI+Cgk8a2V5PmFTdHJpbmc8L2tleT4KCTxzdHJpbmc+ 557db96d56Sopenharmony_ci RG9vZGFoPC9zdHJpbmc+Cgk8a2V5PmFuRW1wdHlEaWN0PC9rZXk+Cgk8ZGlj 567db96d56Sopenharmony_ci dC8+Cgk8a2V5PmFuRW1wdHlMaXN0PC9rZXk+Cgk8YXJyYXkvPgoJPGtleT5h 577db96d56Sopenharmony_ci bkludDwva2V5PgoJPGludGVnZXI+NzI4PC9pbnRlZ2VyPgoJPGtleT5uZXN0 587db96d56Sopenharmony_ci ZWREYXRhPC9rZXk+Cgk8YXJyYXk+CgkJPGRhdGE+CgkJUEd4dmRITWdiMlln 597db96d56Sopenharmony_ci WW1sdVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5k 607db96d56Sopenharmony_ci VzVyCgkJUGdBQkFnTThiRzkwY3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJ 617db96d56Sopenharmony_ci RFBHeHZkSE1nYjJZZ1ltbHVZWEo1CgkJSUdkMWJtcytBQUVDQXp4c2IzUnpJ 627db96d56Sopenharmony_ci RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZaaUJpCgkJYVc1 637db96d56Sopenharmony_ci aGNua2daM1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMr 647db96d56Sopenharmony_ci QUFFQ0F6eHNiM1J6CgkJSUc5bUlHSnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJH 657db96d56Sopenharmony_ci OTBjeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlECgkJUEd4dmRITWdiMlln 667db96d56Sopenharmony_ci WW1sdVlYSjVJR2QxYm1zK0FBRUNBdz09CgkJPC9kYXRhPgoJPC9hcnJheT4K 677db96d56Sopenharmony_ci CTxrZXk+c29tZURhdGE8L2tleT4KCTxkYXRhPgoJUEdKcGJtRnllU0JuZFc1 687db96d56Sopenharmony_ci clBnPT0KCTwvZGF0YT4KCTxrZXk+c29tZU1vcmVEYXRhPC9rZXk+Cgk8ZGF0 697db96d56Sopenharmony_ci YT4KCVBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXp4c2IzUnpJ 707db96d56Sopenharmony_ci RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004CgliRzkwY3lCdlppQmlhVzVo 717db96d56Sopenharmony_ci Y25rZ1ozVnVhejRBQVFJRFBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytB 727db96d56Sopenharmony_ci QUVDQXp4cwoJYjNSeklHOW1JR0pwYm1GeWVTQm5kVzVyUGdBQkFnTThiRzkw 737db96d56Sopenharmony_ci Y3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRFBHeHYKCWRITWdiMllnWW1s 747db96d56Sopenharmony_ci dVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5kVzVy 757db96d56Sopenharmony_ci UGdBQkFnTThiRzkwCgljeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlEUEd4 767db96d56Sopenharmony_ci dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNBdz09Cgk8L2RhdGE+Cgk8 777db96d56Sopenharmony_ci a2V5PsOFYmVucmFhPC9rZXk+Cgk8c3RyaW5nPlRoYXQgd2FzIGEgdW5pY29k 787db96d56Sopenharmony_ci ZSBrZXkuPC9zdHJpbmc+CjwvZGljdD4KPC9wbGlzdD4K'''), 797db96d56Sopenharmony_ci plistlib.FMT_BINARY: binascii.a2b_base64(b''' 807db96d56Sopenharmony_ci YnBsaXN0MDDfEBABAgMEBQYHCAkKCwwNDg8QERITFCgpLzAxMjM0NTc2OFdh 817db96d56Sopenharmony_ci QmlnSW50WGFCaWdJbnQyVWFEYXRlVWFEaWN0VmFGbG9hdFVhTGlzdF8QD2FO 827db96d56Sopenharmony_ci ZWdhdGl2ZUJpZ0ludFxhTmVnYXRpdmVJbnRXYVN0cmluZ1thbkVtcHR5RGlj 837db96d56Sopenharmony_ci dFthbkVtcHR5TGlzdFVhbkludFpuZXN0ZWREYXRhWHNvbWVEYXRhXHNvbWVN 847db96d56Sopenharmony_ci b3JlRGF0YWcAxQBiAGUAbgByAGEAYRN/////////1BQAAAAAAAAAAIAAAAAA 857db96d56Sopenharmony_ci AAAsM0GcuX30AAAA1RUWFxgZGhscHR5bYUZhbHNlVmFsdWVaYVRydWVWYWx1 867db96d56Sopenharmony_ci ZV1hVW5pY29kZVZhbHVlXWFub3RoZXJTdHJpbmdaZGVlcGVyRGljdAgJawBN 877db96d56Sopenharmony_ci AOQAcwBzAGkAZwAsACAATQBhAN9fEBU8aGVsbG8gJiAnaGknIHRoZXJlIT7T 887db96d56Sopenharmony_ci HyAhIiMkUWFRYlFjEBEjQEBAAAAAAACjJSYnEAEQAlR0ZXh0Iz/gAAAAAAAA 897db96d56Sopenharmony_ci pSorLCMtUUFRQhAMoyUmLhADE////+1foOAAE//////////7VkRvb2RhaNCg 907db96d56Sopenharmony_ci EQLYoTZPEPo8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmlu 917db96d56Sopenharmony_ci YXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBv 927db96d56Sopenharmony_ci ZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxs 937db96d56Sopenharmony_ci b3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4A 947db96d56Sopenharmony_ci AQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBn 957db96d56Sopenharmony_ci dW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDTTxiaW5hcnkgZ3Vu 967db96d56Sopenharmony_ci az5fEBdUaGF0IHdhcyBhIHVuaWNvZGUga2V5LgAIACsAMwA8AEIASABPAFUA 977db96d56Sopenharmony_ci ZwB0AHwAiACUAJoApQCuALsAygDTAOQA7QD4AQQBDwEdASsBNgE3ATgBTwFn 987db96d56Sopenharmony_ci AW4BcAFyAXQBdgF/AYMBhQGHAYwBlQGbAZ0BnwGhAaUBpwGwAbkBwAHBAcIB 997db96d56Sopenharmony_ci xQHHAsQC0gAAAAAAAAIBAAAAAAAAADkAAAAAAAAAAAAAAAAAAALs'''), 1007db96d56Sopenharmony_ci 'KEYED_ARCHIVE': binascii.a2b_base64(b''' 1017db96d56Sopenharmony_ci YnBsaXN0MDDUAQIDBAUGHB1YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVy 1027db96d56Sopenharmony_ci VCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVnB5dHlwZVYkY2xhc3NZTlMu 1037db96d56Sopenharmony_ci c3RyaW5nEAGAAl8QE0tleUFyY2hpdmUgVUlEIFRlc3TTEBESExQZWiRjbGFz 1047db96d56Sopenharmony_ci c25hbWVYJGNsYXNzZXNbJGNsYXNzaGludHNfEBdPQ19CdWlsdGluUHl0aG9u 1057db96d56Sopenharmony_ci VW5pY29kZaQVFhcYXxAXT0NfQnVpbHRpblB5dGhvblVuaWNvZGVfEBBPQ19Q 1067db96d56Sopenharmony_ci eXRob25Vbmljb2RlWE5TU3RyaW5nWE5TT2JqZWN0ohobXxAPT0NfUHl0aG9u 1077db96d56Sopenharmony_ci U3RyaW5nWE5TU3RyaW5nXxAPTlNLZXllZEFyY2hpdmVy0R4fVHJvb3SAAQAI 1087db96d56Sopenharmony_ci ABEAGgAjAC0AMgA3ADsAQQBIAE8AVgBgAGIAZAB6AIEAjACVAKEAuwDAANoA 1097db96d56Sopenharmony_ci 7QD2AP8BAgEUAR0BLwEyATcAAAAAAAACAQAAAAAAAAAgAAAAAAAAAAAAAAAA 1107db96d56Sopenharmony_ci AAABOQ=='''), 1117db96d56Sopenharmony_ci} 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ciXML_PLIST_WITH_ENTITY=b'''\ 1147db96d56Sopenharmony_ci<?xml version="1.0" encoding="UTF-8"?> 1157db96d56Sopenharmony_ci<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" [ 1167db96d56Sopenharmony_ci <!ENTITY entity "replacement text"> 1177db96d56Sopenharmony_ci ]> 1187db96d56Sopenharmony_ci<plist version="1.0"> 1197db96d56Sopenharmony_ci <dict> 1207db96d56Sopenharmony_ci <key>A</key> 1217db96d56Sopenharmony_ci <string>&entity;</string> 1227db96d56Sopenharmony_ci </dict> 1237db96d56Sopenharmony_ci</plist> 1247db96d56Sopenharmony_ci''' 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ciINVALID_BINARY_PLISTS = [ 1277db96d56Sopenharmony_ci ('too short data', 1287db96d56Sopenharmony_ci b'' 1297db96d56Sopenharmony_ci ), 1307db96d56Sopenharmony_ci ('too large offset_table_offset and offset_size = 1', 1317db96d56Sopenharmony_ci b'\x00\x08' 1327db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1337db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 1347db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1357db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x2a' 1367db96d56Sopenharmony_ci ), 1377db96d56Sopenharmony_ci ('too large offset_table_offset and nonstandard offset_size', 1387db96d56Sopenharmony_ci b'\x00\x00\x00\x08' 1397db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x03\x01' 1407db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 1417db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1427db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x2c' 1437db96d56Sopenharmony_ci ), 1447db96d56Sopenharmony_ci ('integer overflow in offset_table_offset', 1457db96d56Sopenharmony_ci b'\x00\x08' 1467db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1477db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 1487db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1497db96d56Sopenharmony_ci b'\xff\xff\xff\xff\xff\xff\xff\xff' 1507db96d56Sopenharmony_ci ), 1517db96d56Sopenharmony_ci ('too large top_object', 1527db96d56Sopenharmony_ci b'\x00\x08' 1537db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1547db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 1557db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 1567db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1577db96d56Sopenharmony_ci ), 1587db96d56Sopenharmony_ci ('integer overflow in top_object', 1597db96d56Sopenharmony_ci b'\x00\x08' 1607db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1617db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 1627db96d56Sopenharmony_ci b'\xff\xff\xff\xff\xff\xff\xff\xff' 1637db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1647db96d56Sopenharmony_ci ), 1657db96d56Sopenharmony_ci ('too large num_objects and offset_size = 1', 1667db96d56Sopenharmony_ci b'\x00\x08' 1677db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1687db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\xff' 1697db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1707db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1717db96d56Sopenharmony_ci ), 1727db96d56Sopenharmony_ci ('too large num_objects and nonstandard offset_size', 1737db96d56Sopenharmony_ci b'\x00\x00\x00\x08' 1747db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x03\x01' 1757db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\xff' 1767db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1777db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1787db96d56Sopenharmony_ci ), 1797db96d56Sopenharmony_ci ('extremally large num_objects (32 bit)', 1807db96d56Sopenharmony_ci b'\x00\x08' 1817db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1827db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x7f\xff\xff\xff' 1837db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1847db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1857db96d56Sopenharmony_ci ), 1867db96d56Sopenharmony_ci ('extremally large num_objects (64 bit)', 1877db96d56Sopenharmony_ci b'\x00\x08' 1887db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1897db96d56Sopenharmony_ci b'\x00\x00\x00\xff\xff\xff\xff\xff' 1907db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1917db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1927db96d56Sopenharmony_ci ), 1937db96d56Sopenharmony_ci ('integer overflow in num_objects', 1947db96d56Sopenharmony_ci b'\x00\x08' 1957db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 1967db96d56Sopenharmony_ci b'\xff\xff\xff\xff\xff\xff\xff\xff' 1977db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 1987db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 1997db96d56Sopenharmony_ci ), 2007db96d56Sopenharmony_ci ('offset_size = 0', 2017db96d56Sopenharmony_ci b'\x00\x08' 2027db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2037db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2047db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2057db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 2067db96d56Sopenharmony_ci ), 2077db96d56Sopenharmony_ci ('ref_size = 0', 2087db96d56Sopenharmony_ci b'\xa1\x01\x00\x08\x0a' 2097db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x00' 2107db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2117db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2127db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0b' 2137db96d56Sopenharmony_ci ), 2147db96d56Sopenharmony_ci ('too large offset', 2157db96d56Sopenharmony_ci b'\x00\x2a' 2167db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2177db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2187db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2197db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 2207db96d56Sopenharmony_ci ), 2217db96d56Sopenharmony_ci ('integer overflow in offset', 2227db96d56Sopenharmony_ci b'\x00\xff\xff\xff\xff\xff\xff\xff\xff' 2237db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x08\x01' 2247db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2257db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2267db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x09' 2277db96d56Sopenharmony_ci ), 2287db96d56Sopenharmony_ci ('too large array size', 2297db96d56Sopenharmony_ci b'\xaf\x00\x01\xff\x00\x08\x0c' 2307db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2317db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2327db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2337db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0d' 2347db96d56Sopenharmony_ci ), 2357db96d56Sopenharmony_ci ('extremally large array size (32-bit)', 2367db96d56Sopenharmony_ci b'\xaf\x02\x7f\xff\xff\xff\x01\x00\x08\x0f' 2377db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2387db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2397db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2407db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x10' 2417db96d56Sopenharmony_ci ), 2427db96d56Sopenharmony_ci ('extremally large array size (64-bit)', 2437db96d56Sopenharmony_ci b'\xaf\x03\x00\x00\x00\xff\xff\xff\xff\xff\x01\x00\x08\x13' 2447db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2457db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2467db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2477db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x14' 2487db96d56Sopenharmony_ci ), 2497db96d56Sopenharmony_ci ('integer overflow in array size', 2507db96d56Sopenharmony_ci b'\xaf\x03\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x08\x13' 2517db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2527db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2537db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2547db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x14' 2557db96d56Sopenharmony_ci ), 2567db96d56Sopenharmony_ci ('too large reference index', 2577db96d56Sopenharmony_ci b'\xa1\x02\x00\x08\x0a' 2587db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2597db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2607db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2617db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0b' 2627db96d56Sopenharmony_ci ), 2637db96d56Sopenharmony_ci ('integer overflow in reference index', 2647db96d56Sopenharmony_ci b'\xa1\xff\xff\xff\xff\xff\xff\xff\xff\x00\x08\x11' 2657db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x08' 2667db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 2677db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2687db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x12' 2697db96d56Sopenharmony_ci ), 2707db96d56Sopenharmony_ci ('too large bytes size', 2717db96d56Sopenharmony_ci b'\x4f\x00\x23\x41\x08' 2727db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2737db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2747db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2757db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0c' 2767db96d56Sopenharmony_ci ), 2777db96d56Sopenharmony_ci ('extremally large bytes size (32-bit)', 2787db96d56Sopenharmony_ci b'\x4f\x02\x7f\xff\xff\xff\x41\x08' 2797db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2807db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2817db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2827db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0f' 2837db96d56Sopenharmony_ci ), 2847db96d56Sopenharmony_ci ('extremally large bytes size (64-bit)', 2857db96d56Sopenharmony_ci b'\x4f\x03\x00\x00\x00\xff\xff\xff\xff\xff\x41\x08' 2867db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2877db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2887db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2897db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x13' 2907db96d56Sopenharmony_ci ), 2917db96d56Sopenharmony_ci ('integer overflow in bytes size', 2927db96d56Sopenharmony_ci b'\x4f\x03\xff\xff\xff\xff\xff\xff\xff\xff\x41\x08' 2937db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 2947db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 2957db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 2967db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x13' 2977db96d56Sopenharmony_ci ), 2987db96d56Sopenharmony_ci ('too large ASCII size', 2997db96d56Sopenharmony_ci b'\x5f\x00\x23\x41\x08' 3007db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3017db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3027db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3037db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0c' 3047db96d56Sopenharmony_ci ), 3057db96d56Sopenharmony_ci ('extremally large ASCII size (32-bit)', 3067db96d56Sopenharmony_ci b'\x5f\x02\x7f\xff\xff\xff\x41\x08' 3077db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3087db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3097db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3107db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0f' 3117db96d56Sopenharmony_ci ), 3127db96d56Sopenharmony_ci ('extremally large ASCII size (64-bit)', 3137db96d56Sopenharmony_ci b'\x5f\x03\x00\x00\x00\xff\xff\xff\xff\xff\x41\x08' 3147db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3157db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3167db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3177db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x13' 3187db96d56Sopenharmony_ci ), 3197db96d56Sopenharmony_ci ('integer overflow in ASCII size', 3207db96d56Sopenharmony_ci b'\x5f\x03\xff\xff\xff\xff\xff\xff\xff\xff\x41\x08' 3217db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3227db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3237db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3247db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x13' 3257db96d56Sopenharmony_ci ), 3267db96d56Sopenharmony_ci ('invalid ASCII', 3277db96d56Sopenharmony_ci b'\x51\xff\x08' 3287db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3297db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3307db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3317db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0a' 3327db96d56Sopenharmony_ci ), 3337db96d56Sopenharmony_ci ('too large UTF-16 size', 3347db96d56Sopenharmony_ci b'\x6f\x00\x13\x20\xac\x00\x08' 3357db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3367db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3377db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3387db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0e' 3397db96d56Sopenharmony_ci ), 3407db96d56Sopenharmony_ci ('extremally large UTF-16 size (32-bit)', 3417db96d56Sopenharmony_ci b'\x6f\x02\x4f\xff\xff\xff\x20\xac\x00\x08' 3427db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3437db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3447db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3457db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x11' 3467db96d56Sopenharmony_ci ), 3477db96d56Sopenharmony_ci ('extremally large UTF-16 size (64-bit)', 3487db96d56Sopenharmony_ci b'\x6f\x03\x00\x00\x00\xff\xff\xff\xff\xff\x20\xac\x00\x08' 3497db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3507db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3517db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3527db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x15' 3537db96d56Sopenharmony_ci ), 3547db96d56Sopenharmony_ci ('integer overflow in UTF-16 size', 3557db96d56Sopenharmony_ci b'\x6f\x03\xff\xff\xff\xff\xff\xff\xff\xff\x20\xac\x00\x08' 3567db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3577db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3587db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3597db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x15' 3607db96d56Sopenharmony_ci ), 3617db96d56Sopenharmony_ci ('invalid UTF-16', 3627db96d56Sopenharmony_ci b'\x61\xd8\x00\x08' 3637db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3647db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3657db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3667db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0b' 3677db96d56Sopenharmony_ci ), 3687db96d56Sopenharmony_ci ('non-hashable key', 3697db96d56Sopenharmony_ci b'\xd1\x01\x01\xa0\x08\x0b' 3707db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3717db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x02' 3727db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3737db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x0c' 3747db96d56Sopenharmony_ci ), 3757db96d56Sopenharmony_ci ('too large datetime (datetime overflow)', 3767db96d56Sopenharmony_ci b'\x33\x42\x50\x00\x00\x00\x00\x00\x00\x08' 3777db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3787db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3797db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3807db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x11' 3817db96d56Sopenharmony_ci ), 3827db96d56Sopenharmony_ci ('too large datetime (timedelta overflow)', 3837db96d56Sopenharmony_ci b'\x33\x42\xe0\x00\x00\x00\x00\x00\x00\x08' 3847db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3857db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3867db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3877db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x11' 3887db96d56Sopenharmony_ci ), 3897db96d56Sopenharmony_ci ('invalid datetime (Infinity)', 3907db96d56Sopenharmony_ci b'\x33\x7f\xf0\x00\x00\x00\x00\x00\x00\x08' 3917db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3927db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 3937db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 3947db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x11' 3957db96d56Sopenharmony_ci ), 3967db96d56Sopenharmony_ci ('invalid datetime (NaN)', 3977db96d56Sopenharmony_ci b'\x33\x7f\xf8\x00\x00\x00\x00\x00\x00\x08' 3987db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x01\x01' 3997db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x01' 4007db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 4017db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x11' 4027db96d56Sopenharmony_ci ), 4037db96d56Sopenharmony_ci] 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci 4067db96d56Sopenharmony_ciclass TestPlistlib(unittest.TestCase): 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci def tearDown(self): 4097db96d56Sopenharmony_ci try: 4107db96d56Sopenharmony_ci os.unlink(os_helper.TESTFN) 4117db96d56Sopenharmony_ci except: 4127db96d56Sopenharmony_ci pass 4137db96d56Sopenharmony_ci 4147db96d56Sopenharmony_ci def _create(self, fmt=None): 4157db96d56Sopenharmony_ci pl = dict( 4167db96d56Sopenharmony_ci aString="Doodah", 4177db96d56Sopenharmony_ci aList=["A", "B", 12, 32.5, [1, 2, 3]], 4187db96d56Sopenharmony_ci aFloat = 0.5, 4197db96d56Sopenharmony_ci anInt = 728, 4207db96d56Sopenharmony_ci aBigInt = 2 ** 63 - 44, 4217db96d56Sopenharmony_ci aBigInt2 = 2 ** 63 + 44, 4227db96d56Sopenharmony_ci aNegativeInt = -5, 4237db96d56Sopenharmony_ci aNegativeBigInt = -80000000000, 4247db96d56Sopenharmony_ci aDict=dict( 4257db96d56Sopenharmony_ci anotherString="<hello & 'hi' there!>", 4267db96d56Sopenharmony_ci aUnicodeValue='M\xe4ssig, Ma\xdf', 4277db96d56Sopenharmony_ci aTrueValue=True, 4287db96d56Sopenharmony_ci aFalseValue=False, 4297db96d56Sopenharmony_ci deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]), 4307db96d56Sopenharmony_ci ), 4317db96d56Sopenharmony_ci someData = b"<binary gunk>", 4327db96d56Sopenharmony_ci someMoreData = b"<lots of binary gunk>\0\1\2\3" * 10, 4337db96d56Sopenharmony_ci nestedData = [b"<lots of binary gunk>\0\1\2\3" * 10], 4347db96d56Sopenharmony_ci aDate = datetime.datetime(2004, 10, 26, 10, 33, 33), 4357db96d56Sopenharmony_ci anEmptyDict = dict(), 4367db96d56Sopenharmony_ci anEmptyList = list() 4377db96d56Sopenharmony_ci ) 4387db96d56Sopenharmony_ci pl['\xc5benraa'] = "That was a unicode key." 4397db96d56Sopenharmony_ci return pl 4407db96d56Sopenharmony_ci 4417db96d56Sopenharmony_ci def test_create(self): 4427db96d56Sopenharmony_ci pl = self._create() 4437db96d56Sopenharmony_ci self.assertEqual(pl["aString"], "Doodah") 4447db96d56Sopenharmony_ci self.assertEqual(pl["aDict"]["aFalseValue"], False) 4457db96d56Sopenharmony_ci 4467db96d56Sopenharmony_ci def test_io(self): 4477db96d56Sopenharmony_ci pl = self._create() 4487db96d56Sopenharmony_ci with open(os_helper.TESTFN, 'wb') as fp: 4497db96d56Sopenharmony_ci plistlib.dump(pl, fp) 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_ci with open(os_helper.TESTFN, 'rb') as fp: 4527db96d56Sopenharmony_ci pl2 = plistlib.load(fp) 4537db96d56Sopenharmony_ci 4547db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 4557db96d56Sopenharmony_ci 4567db96d56Sopenharmony_ci self.assertRaises(AttributeError, plistlib.dump, pl, 'filename') 4577db96d56Sopenharmony_ci self.assertRaises(AttributeError, plistlib.load, 'filename') 4587db96d56Sopenharmony_ci 4597db96d56Sopenharmony_ci def test_invalid_type(self): 4607db96d56Sopenharmony_ci pl = [ object() ] 4617db96d56Sopenharmony_ci 4627db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 4637db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 4647db96d56Sopenharmony_ci self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt) 4657db96d56Sopenharmony_ci 4667db96d56Sopenharmony_ci def test_invalid_uid(self): 4677db96d56Sopenharmony_ci with self.assertRaises(TypeError): 4687db96d56Sopenharmony_ci UID("not an int") 4697db96d56Sopenharmony_ci with self.assertRaises(ValueError): 4707db96d56Sopenharmony_ci UID(2 ** 64) 4717db96d56Sopenharmony_ci with self.assertRaises(ValueError): 4727db96d56Sopenharmony_ci UID(-19) 4737db96d56Sopenharmony_ci 4747db96d56Sopenharmony_ci def test_int(self): 4757db96d56Sopenharmony_ci for pl in [0, 2**8-1, 2**8, 2**16-1, 2**16, 2**32-1, 2**32, 4767db96d56Sopenharmony_ci 2**63-1, 2**64-1, 1, -2**63]: 4777db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 4787db96d56Sopenharmony_ci with self.subTest(pl=pl, fmt=fmt): 4797db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt) 4807db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 4817db96d56Sopenharmony_ci self.assertIsInstance(pl2, int) 4827db96d56Sopenharmony_ci self.assertEqual(pl, pl2) 4837db96d56Sopenharmony_ci data2 = plistlib.dumps(pl2, fmt=fmt) 4847db96d56Sopenharmony_ci self.assertEqual(data, data2) 4857db96d56Sopenharmony_ci 4867db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 4877db96d56Sopenharmony_ci for pl in (2 ** 64 + 1, 2 ** 127-1, -2**64, -2 ** 127): 4887db96d56Sopenharmony_ci with self.subTest(pl=pl, fmt=fmt): 4897db96d56Sopenharmony_ci self.assertRaises(OverflowError, plistlib.dumps, 4907db96d56Sopenharmony_ci pl, fmt=fmt) 4917db96d56Sopenharmony_ci 4927db96d56Sopenharmony_ci def test_bytearray(self): 4937db96d56Sopenharmony_ci for pl in (b'<binary gunk>', b"<lots of binary gunk>\0\1\2\3" * 10): 4947db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 4957db96d56Sopenharmony_ci with self.subTest(pl=pl, fmt=fmt): 4967db96d56Sopenharmony_ci data = plistlib.dumps(bytearray(pl), fmt=fmt) 4977db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 4987db96d56Sopenharmony_ci self.assertIsInstance(pl2, bytes) 4997db96d56Sopenharmony_ci self.assertEqual(pl2, pl) 5007db96d56Sopenharmony_ci data2 = plistlib.dumps(pl2, fmt=fmt) 5017db96d56Sopenharmony_ci self.assertEqual(data, data2) 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ci def test_bytes(self): 5047db96d56Sopenharmony_ci pl = self._create() 5057db96d56Sopenharmony_ci data = plistlib.dumps(pl) 5067db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 5077db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 5087db96d56Sopenharmony_ci data2 = plistlib.dumps(pl2) 5097db96d56Sopenharmony_ci self.assertEqual(data, data2) 5107db96d56Sopenharmony_ci 5117db96d56Sopenharmony_ci def test_indentation_array(self): 5127db96d56Sopenharmony_ci data = [[[[[[[[{'test': b'aaaaaa'}]]]]]]]] 5137db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(plistlib.dumps(data)), data) 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci def test_indentation_dict(self): 5167db96d56Sopenharmony_ci data = {'1': {'2': {'3': {'4': {'5': {'6': {'7': {'8': {'9': b'aaaaaa'}}}}}}}}} 5177db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(plistlib.dumps(data)), data) 5187db96d56Sopenharmony_ci 5197db96d56Sopenharmony_ci def test_indentation_dict_mix(self): 5207db96d56Sopenharmony_ci data = {'1': {'2': [{'3': [[[[[{'test': b'aaaaaa'}]]]]]}]}} 5217db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(plistlib.dumps(data)), data) 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_ci def test_uid(self): 5247db96d56Sopenharmony_ci data = UID(1) 5257db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(plistlib.dumps(data, fmt=plistlib.FMT_BINARY)), data) 5267db96d56Sopenharmony_ci dict_data = { 5277db96d56Sopenharmony_ci 'uid0': UID(0), 5287db96d56Sopenharmony_ci 'uid2': UID(2), 5297db96d56Sopenharmony_ci 'uid8': UID(2 ** 8), 5307db96d56Sopenharmony_ci 'uid16': UID(2 ** 16), 5317db96d56Sopenharmony_ci 'uid32': UID(2 ** 32), 5327db96d56Sopenharmony_ci 'uid63': UID(2 ** 63) 5337db96d56Sopenharmony_ci } 5347db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(plistlib.dumps(dict_data, fmt=plistlib.FMT_BINARY)), dict_data) 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ci def test_uid_data(self): 5377db96d56Sopenharmony_ci uid = UID(1) 5387db96d56Sopenharmony_ci self.assertEqual(uid.data, 1) 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_ci def test_uid_eq(self): 5417db96d56Sopenharmony_ci self.assertEqual(UID(1), UID(1)) 5427db96d56Sopenharmony_ci self.assertNotEqual(UID(1), UID(2)) 5437db96d56Sopenharmony_ci self.assertNotEqual(UID(1), "not uid") 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci def test_uid_hash(self): 5467db96d56Sopenharmony_ci self.assertEqual(hash(UID(1)), hash(UID(1))) 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci def test_uid_repr(self): 5497db96d56Sopenharmony_ci self.assertEqual(repr(UID(1)), "UID(1)") 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci def test_uid_index(self): 5527db96d56Sopenharmony_ci self.assertEqual(operator.index(UID(1)), 1) 5537db96d56Sopenharmony_ci 5547db96d56Sopenharmony_ci def test_uid_pickle(self): 5557db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 5567db96d56Sopenharmony_ci self.assertEqual(pickle.loads(pickle.dumps(UID(19), protocol=proto)), UID(19)) 5577db96d56Sopenharmony_ci 5587db96d56Sopenharmony_ci def test_uid_copy(self): 5597db96d56Sopenharmony_ci self.assertEqual(copy.copy(UID(1)), UID(1)) 5607db96d56Sopenharmony_ci self.assertEqual(copy.deepcopy(UID(1)), UID(1)) 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_ci def test_appleformatting(self): 5637db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 5647db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 5657db96d56Sopenharmony_ci pl = plistlib.loads(TESTDATA[fmt]) 5667db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt) 5677db96d56Sopenharmony_ci self.assertEqual(data, TESTDATA[fmt], 5687db96d56Sopenharmony_ci "generated data was not identical to Apple's output") 5697db96d56Sopenharmony_ci 5707db96d56Sopenharmony_ci 5717db96d56Sopenharmony_ci def test_appleformattingfromliteral(self): 5727db96d56Sopenharmony_ci self.maxDiff = None 5737db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 5747db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 5757db96d56Sopenharmony_ci pl = self._create(fmt=fmt) 5767db96d56Sopenharmony_ci pl2 = plistlib.loads(TESTDATA[fmt], fmt=fmt) 5777db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2), 5787db96d56Sopenharmony_ci "generated data was not identical to Apple's output") 5797db96d56Sopenharmony_ci pl2 = plistlib.loads(TESTDATA[fmt]) 5807db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2), 5817db96d56Sopenharmony_ci "generated data was not identical to Apple's output") 5827db96d56Sopenharmony_ci 5837db96d56Sopenharmony_ci def test_bytesio(self): 5847db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 5857db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 5867db96d56Sopenharmony_ci b = BytesIO() 5877db96d56Sopenharmony_ci pl = self._create(fmt=fmt) 5887db96d56Sopenharmony_ci plistlib.dump(pl, b, fmt=fmt) 5897db96d56Sopenharmony_ci pl2 = plistlib.load(BytesIO(b.getvalue()), fmt=fmt) 5907db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 5917db96d56Sopenharmony_ci pl2 = plistlib.load(BytesIO(b.getvalue())) 5927db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 5937db96d56Sopenharmony_ci 5947db96d56Sopenharmony_ci def test_keysort_bytesio(self): 5957db96d56Sopenharmony_ci pl = collections.OrderedDict() 5967db96d56Sopenharmony_ci pl['b'] = 1 5977db96d56Sopenharmony_ci pl['a'] = 2 5987db96d56Sopenharmony_ci pl['c'] = 3 5997db96d56Sopenharmony_ci 6007db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 6017db96d56Sopenharmony_ci for sort_keys in (False, True): 6027db96d56Sopenharmony_ci with self.subTest(fmt=fmt, sort_keys=sort_keys): 6037db96d56Sopenharmony_ci b = BytesIO() 6047db96d56Sopenharmony_ci 6057db96d56Sopenharmony_ci plistlib.dump(pl, b, fmt=fmt, sort_keys=sort_keys) 6067db96d56Sopenharmony_ci pl2 = plistlib.load(BytesIO(b.getvalue()), 6077db96d56Sopenharmony_ci dict_type=collections.OrderedDict) 6087db96d56Sopenharmony_ci 6097db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 6107db96d56Sopenharmony_ci if sort_keys: 6117db96d56Sopenharmony_ci self.assertEqual(list(pl2.keys()), ['a', 'b', 'c']) 6127db96d56Sopenharmony_ci else: 6137db96d56Sopenharmony_ci self.assertEqual(list(pl2.keys()), ['b', 'a', 'c']) 6147db96d56Sopenharmony_ci 6157db96d56Sopenharmony_ci def test_keysort(self): 6167db96d56Sopenharmony_ci pl = collections.OrderedDict() 6177db96d56Sopenharmony_ci pl['b'] = 1 6187db96d56Sopenharmony_ci pl['a'] = 2 6197db96d56Sopenharmony_ci pl['c'] = 3 6207db96d56Sopenharmony_ci 6217db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 6227db96d56Sopenharmony_ci for sort_keys in (False, True): 6237db96d56Sopenharmony_ci with self.subTest(fmt=fmt, sort_keys=sort_keys): 6247db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt, sort_keys=sort_keys) 6257db96d56Sopenharmony_ci pl2 = plistlib.loads(data, dict_type=collections.OrderedDict) 6267db96d56Sopenharmony_ci 6277db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 6287db96d56Sopenharmony_ci if sort_keys: 6297db96d56Sopenharmony_ci self.assertEqual(list(pl2.keys()), ['a', 'b', 'c']) 6307db96d56Sopenharmony_ci else: 6317db96d56Sopenharmony_ci self.assertEqual(list(pl2.keys()), ['b', 'a', 'c']) 6327db96d56Sopenharmony_ci 6337db96d56Sopenharmony_ci def test_keys_no_string(self): 6347db96d56Sopenharmony_ci pl = { 42: 'aNumber' } 6357db96d56Sopenharmony_ci 6367db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 6377db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 6387db96d56Sopenharmony_ci self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt) 6397db96d56Sopenharmony_ci 6407db96d56Sopenharmony_ci b = BytesIO() 6417db96d56Sopenharmony_ci self.assertRaises(TypeError, plistlib.dump, pl, b, fmt=fmt) 6427db96d56Sopenharmony_ci 6437db96d56Sopenharmony_ci def test_skipkeys(self): 6447db96d56Sopenharmony_ci pl = { 6457db96d56Sopenharmony_ci 42: 'aNumber', 6467db96d56Sopenharmony_ci 'snake': 'aWord', 6477db96d56Sopenharmony_ci } 6487db96d56Sopenharmony_ci 6497db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 6507db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 6517db96d56Sopenharmony_ci data = plistlib.dumps( 6527db96d56Sopenharmony_ci pl, fmt=fmt, skipkeys=True, sort_keys=False) 6537db96d56Sopenharmony_ci 6547db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 6557db96d56Sopenharmony_ci self.assertEqual(pl2, {'snake': 'aWord'}) 6567db96d56Sopenharmony_ci 6577db96d56Sopenharmony_ci fp = BytesIO() 6587db96d56Sopenharmony_ci plistlib.dump( 6597db96d56Sopenharmony_ci pl, fp, fmt=fmt, skipkeys=True, sort_keys=False) 6607db96d56Sopenharmony_ci data = fp.getvalue() 6617db96d56Sopenharmony_ci pl2 = plistlib.loads(fp.getvalue()) 6627db96d56Sopenharmony_ci self.assertEqual(pl2, {'snake': 'aWord'}) 6637db96d56Sopenharmony_ci 6647db96d56Sopenharmony_ci def test_tuple_members(self): 6657db96d56Sopenharmony_ci pl = { 6667db96d56Sopenharmony_ci 'first': (1, 2), 6677db96d56Sopenharmony_ci 'second': (1, 2), 6687db96d56Sopenharmony_ci 'third': (3, 4), 6697db96d56Sopenharmony_ci } 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 6727db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 6737db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt) 6747db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 6757db96d56Sopenharmony_ci self.assertEqual(pl2, { 6767db96d56Sopenharmony_ci 'first': [1, 2], 6777db96d56Sopenharmony_ci 'second': [1, 2], 6787db96d56Sopenharmony_ci 'third': [3, 4], 6797db96d56Sopenharmony_ci }) 6807db96d56Sopenharmony_ci if fmt != plistlib.FMT_BINARY: 6817db96d56Sopenharmony_ci self.assertIsNot(pl2['first'], pl2['second']) 6827db96d56Sopenharmony_ci 6837db96d56Sopenharmony_ci def test_list_members(self): 6847db96d56Sopenharmony_ci pl = { 6857db96d56Sopenharmony_ci 'first': [1, 2], 6867db96d56Sopenharmony_ci 'second': [1, 2], 6877db96d56Sopenharmony_ci 'third': [3, 4], 6887db96d56Sopenharmony_ci } 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 6917db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 6927db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt) 6937db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 6947db96d56Sopenharmony_ci self.assertEqual(pl2, { 6957db96d56Sopenharmony_ci 'first': [1, 2], 6967db96d56Sopenharmony_ci 'second': [1, 2], 6977db96d56Sopenharmony_ci 'third': [3, 4], 6987db96d56Sopenharmony_ci }) 6997db96d56Sopenharmony_ci self.assertIsNot(pl2['first'], pl2['second']) 7007db96d56Sopenharmony_ci 7017db96d56Sopenharmony_ci def test_dict_members(self): 7027db96d56Sopenharmony_ci pl = { 7037db96d56Sopenharmony_ci 'first': {'a': 1}, 7047db96d56Sopenharmony_ci 'second': {'a': 1}, 7057db96d56Sopenharmony_ci 'third': {'b': 2 }, 7067db96d56Sopenharmony_ci } 7077db96d56Sopenharmony_ci 7087db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 7097db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 7107db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt) 7117db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 7127db96d56Sopenharmony_ci self.assertEqual(pl2, { 7137db96d56Sopenharmony_ci 'first': {'a': 1}, 7147db96d56Sopenharmony_ci 'second': {'a': 1}, 7157db96d56Sopenharmony_ci 'third': {'b': 2 }, 7167db96d56Sopenharmony_ci }) 7177db96d56Sopenharmony_ci self.assertIsNot(pl2['first'], pl2['second']) 7187db96d56Sopenharmony_ci 7197db96d56Sopenharmony_ci def test_controlcharacters(self): 7207db96d56Sopenharmony_ci for i in range(128): 7217db96d56Sopenharmony_ci c = chr(i) 7227db96d56Sopenharmony_ci testString = "string containing %s" % c 7237db96d56Sopenharmony_ci if i >= 32 or c in "\r\n\t": 7247db96d56Sopenharmony_ci # \r, \n and \t are the only legal control chars in XML 7257db96d56Sopenharmony_ci data = plistlib.dumps(testString, fmt=plistlib.FMT_XML) 7267db96d56Sopenharmony_ci if c != "\r": 7277db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(data), testString) 7287db96d56Sopenharmony_ci else: 7297db96d56Sopenharmony_ci with self.assertRaises(ValueError): 7307db96d56Sopenharmony_ci plistlib.dumps(testString, fmt=plistlib.FMT_XML) 7317db96d56Sopenharmony_ci plistlib.dumps(testString, fmt=plistlib.FMT_BINARY) 7327db96d56Sopenharmony_ci 7337db96d56Sopenharmony_ci def test_non_bmp_characters(self): 7347db96d56Sopenharmony_ci pl = {'python': '\U0001f40d'} 7357db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 7367db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 7377db96d56Sopenharmony_ci data = plistlib.dumps(pl, fmt=fmt) 7387db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(data), pl) 7397db96d56Sopenharmony_ci 7407db96d56Sopenharmony_ci def test_lone_surrogates(self): 7417db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 7427db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 7437db96d56Sopenharmony_ci with self.assertRaises(UnicodeEncodeError): 7447db96d56Sopenharmony_ci plistlib.dumps('\ud8ff', fmt=fmt) 7457db96d56Sopenharmony_ci with self.assertRaises(UnicodeEncodeError): 7467db96d56Sopenharmony_ci plistlib.dumps('\udcff', fmt=fmt) 7477db96d56Sopenharmony_ci 7487db96d56Sopenharmony_ci def test_nondictroot(self): 7497db96d56Sopenharmony_ci for fmt in ALL_FORMATS: 7507db96d56Sopenharmony_ci with self.subTest(fmt=fmt): 7517db96d56Sopenharmony_ci test1 = "abc" 7527db96d56Sopenharmony_ci test2 = [1, 2, 3, "abc"] 7537db96d56Sopenharmony_ci result1 = plistlib.loads(plistlib.dumps(test1, fmt=fmt)) 7547db96d56Sopenharmony_ci result2 = plistlib.loads(plistlib.dumps(test2, fmt=fmt)) 7557db96d56Sopenharmony_ci self.assertEqual(test1, result1) 7567db96d56Sopenharmony_ci self.assertEqual(test2, result2) 7577db96d56Sopenharmony_ci 7587db96d56Sopenharmony_ci def test_invalidarray(self): 7597db96d56Sopenharmony_ci for i in ["<key>key inside an array</key>", 7607db96d56Sopenharmony_ci "<key>key inside an array2</key><real>3</real>", 7617db96d56Sopenharmony_ci "<true/><key>key inside an array3</key>"]: 7627db96d56Sopenharmony_ci self.assertRaises(ValueError, plistlib.loads, 7637db96d56Sopenharmony_ci ("<plist><array>%s</array></plist>"%i).encode()) 7647db96d56Sopenharmony_ci 7657db96d56Sopenharmony_ci def test_invaliddict(self): 7667db96d56Sopenharmony_ci for i in ["<key><true/>k</key><string>compound key</string>", 7677db96d56Sopenharmony_ci "<key>single key</key>", 7687db96d56Sopenharmony_ci "<string>missing key</string>", 7697db96d56Sopenharmony_ci "<key>k1</key><string>v1</string><real>5.3</real>" 7707db96d56Sopenharmony_ci "<key>k1</key><key>k2</key><string>double key</string>"]: 7717db96d56Sopenharmony_ci self.assertRaises(ValueError, plistlib.loads, 7727db96d56Sopenharmony_ci ("<plist><dict>%s</dict></plist>"%i).encode()) 7737db96d56Sopenharmony_ci self.assertRaises(ValueError, plistlib.loads, 7747db96d56Sopenharmony_ci ("<plist><array><dict>%s</dict></array></plist>"%i).encode()) 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci def test_invalidinteger(self): 7777db96d56Sopenharmony_ci self.assertRaises(ValueError, plistlib.loads, 7787db96d56Sopenharmony_ci b"<plist><integer>not integer</integer></plist>") 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci def test_invalidreal(self): 7817db96d56Sopenharmony_ci self.assertRaises(ValueError, plistlib.loads, 7827db96d56Sopenharmony_ci b"<plist><integer>not real</integer></plist>") 7837db96d56Sopenharmony_ci 7847db96d56Sopenharmony_ci def test_integer_notations(self): 7857db96d56Sopenharmony_ci pl = b"<plist><integer>456</integer></plist>" 7867db96d56Sopenharmony_ci value = plistlib.loads(pl) 7877db96d56Sopenharmony_ci self.assertEqual(value, 456) 7887db96d56Sopenharmony_ci 7897db96d56Sopenharmony_ci pl = b"<plist><integer>0xa</integer></plist>" 7907db96d56Sopenharmony_ci value = plistlib.loads(pl) 7917db96d56Sopenharmony_ci self.assertEqual(value, 10) 7927db96d56Sopenharmony_ci 7937db96d56Sopenharmony_ci pl = b"<plist><integer>0123</integer></plist>" 7947db96d56Sopenharmony_ci value = plistlib.loads(pl) 7957db96d56Sopenharmony_ci self.assertEqual(value, 123) 7967db96d56Sopenharmony_ci 7977db96d56Sopenharmony_ci def test_xml_encodings(self): 7987db96d56Sopenharmony_ci base = TESTDATA[plistlib.FMT_XML] 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci for xml_encoding, encoding, bom in [ 8017db96d56Sopenharmony_ci (b'utf-8', 'utf-8', codecs.BOM_UTF8), 8027db96d56Sopenharmony_ci (b'utf-16', 'utf-16-le', codecs.BOM_UTF16_LE), 8037db96d56Sopenharmony_ci (b'utf-16', 'utf-16-be', codecs.BOM_UTF16_BE), 8047db96d56Sopenharmony_ci # Expat does not support UTF-32 8057db96d56Sopenharmony_ci #(b'utf-32', 'utf-32-le', codecs.BOM_UTF32_LE), 8067db96d56Sopenharmony_ci #(b'utf-32', 'utf-32-be', codecs.BOM_UTF32_BE), 8077db96d56Sopenharmony_ci ]: 8087db96d56Sopenharmony_ci 8097db96d56Sopenharmony_ci pl = self._create(fmt=plistlib.FMT_XML) 8107db96d56Sopenharmony_ci with self.subTest(encoding=encoding): 8117db96d56Sopenharmony_ci data = base.replace(b'UTF-8', xml_encoding) 8127db96d56Sopenharmony_ci data = bom + data.decode('utf-8').encode(encoding) 8137db96d56Sopenharmony_ci pl2 = plistlib.loads(data) 8147db96d56Sopenharmony_ci self.assertEqual(dict(pl), dict(pl2)) 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_ci def test_dump_invalid_format(self): 8177db96d56Sopenharmony_ci with self.assertRaises(ValueError): 8187db96d56Sopenharmony_ci plistlib.dumps({}, fmt="blah") 8197db96d56Sopenharmony_ci 8207db96d56Sopenharmony_ci def test_load_invalid_file(self): 8217db96d56Sopenharmony_ci with self.assertRaises(plistlib.InvalidFileException): 8227db96d56Sopenharmony_ci plistlib.loads(b"these are not plist file contents") 8237db96d56Sopenharmony_ci 8247db96d56Sopenharmony_ci def test_modified_uid_negative(self): 8257db96d56Sopenharmony_ci neg_uid = UID(1) 8267db96d56Sopenharmony_ci neg_uid.data = -1 # dodge the negative check in the constructor 8277db96d56Sopenharmony_ci with self.assertRaises(ValueError): 8287db96d56Sopenharmony_ci plistlib.dumps(neg_uid, fmt=plistlib.FMT_BINARY) 8297db96d56Sopenharmony_ci 8307db96d56Sopenharmony_ci def test_modified_uid_huge(self): 8317db96d56Sopenharmony_ci huge_uid = UID(1) 8327db96d56Sopenharmony_ci huge_uid.data = 2 ** 64 # dodge the size check in the constructor 8337db96d56Sopenharmony_ci with self.assertRaises(OverflowError): 8347db96d56Sopenharmony_ci plistlib.dumps(huge_uid, fmt=plistlib.FMT_BINARY) 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci def test_xml_plist_with_entity_decl(self): 8377db96d56Sopenharmony_ci with self.assertRaisesRegex(plistlib.InvalidFileException, 8387db96d56Sopenharmony_ci "XML entity declarations are not supported"): 8397db96d56Sopenharmony_ci plistlib.loads(XML_PLIST_WITH_ENTITY, fmt=plistlib.FMT_XML) 8407db96d56Sopenharmony_ci 8417db96d56Sopenharmony_ci 8427db96d56Sopenharmony_ciclass TestBinaryPlistlib(unittest.TestCase): 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ci @staticmethod 8457db96d56Sopenharmony_ci def decode(*objects, offset_size=1, ref_size=1): 8467db96d56Sopenharmony_ci data = [b'bplist00'] 8477db96d56Sopenharmony_ci offset = 8 8487db96d56Sopenharmony_ci offsets = [] 8497db96d56Sopenharmony_ci for x in objects: 8507db96d56Sopenharmony_ci offsets.append(offset.to_bytes(offset_size, 'big')) 8517db96d56Sopenharmony_ci data.append(x) 8527db96d56Sopenharmony_ci offset += len(x) 8537db96d56Sopenharmony_ci tail = struct.pack('>6xBBQQQ', offset_size, ref_size, 8547db96d56Sopenharmony_ci len(objects), 0, offset) 8557db96d56Sopenharmony_ci data.extend(offsets) 8567db96d56Sopenharmony_ci data.append(tail) 8577db96d56Sopenharmony_ci return plistlib.loads(b''.join(data), fmt=plistlib.FMT_BINARY) 8587db96d56Sopenharmony_ci 8597db96d56Sopenharmony_ci def test_nonstandard_refs_size(self): 8607db96d56Sopenharmony_ci # Issue #21538: Refs and offsets are 24-bit integers 8617db96d56Sopenharmony_ci data = (b'bplist00' 8627db96d56Sopenharmony_ci b'\xd1\x00\x00\x01\x00\x00\x02QaQb' 8637db96d56Sopenharmony_ci b'\x00\x00\x08\x00\x00\x0f\x00\x00\x11' 8647db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00' 8657db96d56Sopenharmony_ci b'\x03\x03' 8667db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x03' 8677db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00' 8687db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x13') 8697db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(data), {'a': 'b'}) 8707db96d56Sopenharmony_ci 8717db96d56Sopenharmony_ci def test_dump_duplicates(self): 8727db96d56Sopenharmony_ci # Test effectiveness of saving duplicated objects 8737db96d56Sopenharmony_ci for x in (None, False, True, 12345, 123.45, 'abcde', 'абвгд', b'abcde', 8747db96d56Sopenharmony_ci datetime.datetime(2004, 10, 26, 10, 33, 33), 8757db96d56Sopenharmony_ci bytearray(b'abcde'), [12, 345], (12, 345), {'12': 345}): 8767db96d56Sopenharmony_ci with self.subTest(x=x): 8777db96d56Sopenharmony_ci data = plistlib.dumps([x]*1000, fmt=plistlib.FMT_BINARY) 8787db96d56Sopenharmony_ci self.assertLess(len(data), 1100, repr(data)) 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ci def test_identity(self): 8817db96d56Sopenharmony_ci for x in (None, False, True, 12345, 123.45, 'abcde', b'abcde', 8827db96d56Sopenharmony_ci datetime.datetime(2004, 10, 26, 10, 33, 33), 8837db96d56Sopenharmony_ci bytearray(b'abcde'), [12, 345], (12, 345), {'12': 345}): 8847db96d56Sopenharmony_ci with self.subTest(x=x): 8857db96d56Sopenharmony_ci data = plistlib.dumps([x]*2, fmt=plistlib.FMT_BINARY) 8867db96d56Sopenharmony_ci a, b = plistlib.loads(data) 8877db96d56Sopenharmony_ci if isinstance(x, tuple): 8887db96d56Sopenharmony_ci x = list(x) 8897db96d56Sopenharmony_ci self.assertEqual(a, x) 8907db96d56Sopenharmony_ci self.assertEqual(b, x) 8917db96d56Sopenharmony_ci self.assertIs(a, b) 8927db96d56Sopenharmony_ci 8937db96d56Sopenharmony_ci def test_cycles(self): 8947db96d56Sopenharmony_ci # recursive list 8957db96d56Sopenharmony_ci a = [] 8967db96d56Sopenharmony_ci a.append(a) 8977db96d56Sopenharmony_ci b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) 8987db96d56Sopenharmony_ci self.assertIs(b[0], b) 8997db96d56Sopenharmony_ci # recursive tuple 9007db96d56Sopenharmony_ci a = ([],) 9017db96d56Sopenharmony_ci a[0].append(a) 9027db96d56Sopenharmony_ci b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) 9037db96d56Sopenharmony_ci self.assertIs(b[0][0], b) 9047db96d56Sopenharmony_ci # recursive dict 9057db96d56Sopenharmony_ci a = {} 9067db96d56Sopenharmony_ci a['x'] = a 9077db96d56Sopenharmony_ci b = plistlib.loads(plistlib.dumps(a, fmt=plistlib.FMT_BINARY)) 9087db96d56Sopenharmony_ci self.assertIs(b['x'], b) 9097db96d56Sopenharmony_ci 9107db96d56Sopenharmony_ci def test_deep_nesting(self): 9117db96d56Sopenharmony_ci for N in [300, 100000]: 9127db96d56Sopenharmony_ci chunks = [b'\xa1' + (i + 1).to_bytes(4, 'big') for i in range(N)] 9137db96d56Sopenharmony_ci try: 9147db96d56Sopenharmony_ci result = self.decode(*chunks, b'\x54seed', offset_size=4, ref_size=4) 9157db96d56Sopenharmony_ci except RecursionError: 9167db96d56Sopenharmony_ci pass 9177db96d56Sopenharmony_ci else: 9187db96d56Sopenharmony_ci for i in range(N): 9197db96d56Sopenharmony_ci self.assertIsInstance(result, list) 9207db96d56Sopenharmony_ci self.assertEqual(len(result), 1) 9217db96d56Sopenharmony_ci result = result[0] 9227db96d56Sopenharmony_ci self.assertEqual(result, 'seed') 9237db96d56Sopenharmony_ci 9247db96d56Sopenharmony_ci def test_large_timestamp(self): 9257db96d56Sopenharmony_ci # Issue #26709: 32-bit timestamp out of range 9267db96d56Sopenharmony_ci for ts in -2**31-1, 2**31: 9277db96d56Sopenharmony_ci with self.subTest(ts=ts): 9287db96d56Sopenharmony_ci d = (datetime.datetime.utcfromtimestamp(0) + 9297db96d56Sopenharmony_ci datetime.timedelta(seconds=ts)) 9307db96d56Sopenharmony_ci data = plistlib.dumps(d, fmt=plistlib.FMT_BINARY) 9317db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(data), d) 9327db96d56Sopenharmony_ci 9337db96d56Sopenharmony_ci def test_load_singletons(self): 9347db96d56Sopenharmony_ci self.assertIs(self.decode(b'\x00'), None) 9357db96d56Sopenharmony_ci self.assertIs(self.decode(b'\x08'), False) 9367db96d56Sopenharmony_ci self.assertIs(self.decode(b'\x09'), True) 9377db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x0f'), b'') 9387db96d56Sopenharmony_ci 9397db96d56Sopenharmony_ci def test_load_int(self): 9407db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x10\x00'), 0) 9417db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x10\xfe'), 0xfe) 9427db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x11\xfe\xdc'), 0xfedc) 9437db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x12\xfe\xdc\xba\x98'), 0xfedcba98) 9447db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x13\x01\x23\x45\x67\x89\xab\xcd\xef'), 9457db96d56Sopenharmony_ci 0x0123456789abcdef) 9467db96d56Sopenharmony_ci self.assertEqual(self.decode(b'\x13\xfe\xdc\xba\x98\x76\x54\x32\x10'), 9477db96d56Sopenharmony_ci -0x123456789abcdf0) 9487db96d56Sopenharmony_ci 9497db96d56Sopenharmony_ci def test_unsupported(self): 9507db96d56Sopenharmony_ci unsupported = [*range(1, 8), *range(10, 15), 9517db96d56Sopenharmony_ci 0x20, 0x21, *range(0x24, 0x33), *range(0x34, 0x40)] 9527db96d56Sopenharmony_ci for i in [0x70, 0x90, 0xb0, 0xc0, 0xe0, 0xf0]: 9537db96d56Sopenharmony_ci unsupported.extend(i + j for j in range(16)) 9547db96d56Sopenharmony_ci for token in unsupported: 9557db96d56Sopenharmony_ci with self.subTest(f'token {token:02x}'): 9567db96d56Sopenharmony_ci with self.assertRaises(plistlib.InvalidFileException): 9577db96d56Sopenharmony_ci self.decode(bytes([token]) + b'\x00'*16) 9587db96d56Sopenharmony_ci 9597db96d56Sopenharmony_ci def test_invalid_binary(self): 9607db96d56Sopenharmony_ci for name, data in INVALID_BINARY_PLISTS: 9617db96d56Sopenharmony_ci with self.subTest(name): 9627db96d56Sopenharmony_ci with self.assertRaises(plistlib.InvalidFileException): 9637db96d56Sopenharmony_ci plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY) 9647db96d56Sopenharmony_ci 9657db96d56Sopenharmony_ci 9667db96d56Sopenharmony_ciclass TestKeyedArchive(unittest.TestCase): 9677db96d56Sopenharmony_ci def test_keyed_archive_data(self): 9687db96d56Sopenharmony_ci # This is the structure of a NSKeyedArchive packed plist 9697db96d56Sopenharmony_ci data = { 9707db96d56Sopenharmony_ci '$version': 100000, 9717db96d56Sopenharmony_ci '$objects': [ 9727db96d56Sopenharmony_ci '$null', { 9737db96d56Sopenharmony_ci 'pytype': 1, 9747db96d56Sopenharmony_ci '$class': UID(2), 9757db96d56Sopenharmony_ci 'NS.string': 'KeyArchive UID Test' 9767db96d56Sopenharmony_ci }, 9777db96d56Sopenharmony_ci { 9787db96d56Sopenharmony_ci '$classname': 'OC_BuiltinPythonUnicode', 9797db96d56Sopenharmony_ci '$classes': [ 9807db96d56Sopenharmony_ci 'OC_BuiltinPythonUnicode', 9817db96d56Sopenharmony_ci 'OC_PythonUnicode', 9827db96d56Sopenharmony_ci 'NSString', 9837db96d56Sopenharmony_ci 'NSObject' 9847db96d56Sopenharmony_ci ], 9857db96d56Sopenharmony_ci '$classhints': [ 9867db96d56Sopenharmony_ci 'OC_PythonString', 'NSString' 9877db96d56Sopenharmony_ci ] 9887db96d56Sopenharmony_ci } 9897db96d56Sopenharmony_ci ], 9907db96d56Sopenharmony_ci '$archiver': 'NSKeyedArchiver', 9917db96d56Sopenharmony_ci '$top': { 9927db96d56Sopenharmony_ci 'root': UID(1) 9937db96d56Sopenharmony_ci } 9947db96d56Sopenharmony_ci } 9957db96d56Sopenharmony_ci self.assertEqual(plistlib.loads(TESTDATA["KEYED_ARCHIVE"]), data) 9967db96d56Sopenharmony_ci 9977db96d56Sopenharmony_ci 9987db96d56Sopenharmony_ciclass MiscTestCase(unittest.TestCase): 9997db96d56Sopenharmony_ci def test__all__(self): 10007db96d56Sopenharmony_ci not_exported = {"PlistFormat", "PLISTHEADER"} 10017db96d56Sopenharmony_ci support.check__all__(self, plistlib, not_exported=not_exported) 10027db96d56Sopenharmony_ci 10037db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "darwin", "plutil utility is for Mac os") 10047db96d56Sopenharmony_ciclass TestPlutil(unittest.TestCase): 10057db96d56Sopenharmony_ci file_name = "plutil_test.plist" 10067db96d56Sopenharmony_ci properties = { 10077db96d56Sopenharmony_ci "fname" : "H", 10087db96d56Sopenharmony_ci "lname":"A", 10097db96d56Sopenharmony_ci "marks" : {"a":100, "b":0x10} 10107db96d56Sopenharmony_ci } 10117db96d56Sopenharmony_ci exptected_properties = { 10127db96d56Sopenharmony_ci "fname" : "H", 10137db96d56Sopenharmony_ci "lname": "A", 10147db96d56Sopenharmony_ci "marks" : {"a":100, "b":16} 10157db96d56Sopenharmony_ci } 10167db96d56Sopenharmony_ci pl = { 10177db96d56Sopenharmony_ci "HexType" : 0x0100000c, 10187db96d56Sopenharmony_ci "IntType" : 0o123 10197db96d56Sopenharmony_ci } 10207db96d56Sopenharmony_ci 10217db96d56Sopenharmony_ci @classmethod 10227db96d56Sopenharmony_ci def setUpClass(cls) -> None: 10237db96d56Sopenharmony_ci ## Generate plist file with plistlib and parse with plutil 10247db96d56Sopenharmony_ci with open(cls.file_name,'wb') as f: 10257db96d56Sopenharmony_ci plistlib.dump(cls.properties, f, fmt=plistlib.FMT_BINARY) 10267db96d56Sopenharmony_ci 10277db96d56Sopenharmony_ci @classmethod 10287db96d56Sopenharmony_ci def tearDownClass(cls) -> None: 10297db96d56Sopenharmony_ci os.remove(cls.file_name) 10307db96d56Sopenharmony_ci 10317db96d56Sopenharmony_ci def get_lint_status(self): 10327db96d56Sopenharmony_ci return subprocess.run(['plutil', "-lint", self.file_name], capture_output=True, text=True).stdout 10337db96d56Sopenharmony_ci 10347db96d56Sopenharmony_ci def convert_to_json(self): 10357db96d56Sopenharmony_ci """Convert binary file to json using plutil 10367db96d56Sopenharmony_ci """ 10377db96d56Sopenharmony_ci subprocess.run(['plutil', "-convert", 'json', self.file_name]) 10387db96d56Sopenharmony_ci 10397db96d56Sopenharmony_ci def convert_to_bin(self): 10407db96d56Sopenharmony_ci """Convert file to binary using plutil 10417db96d56Sopenharmony_ci """ 10427db96d56Sopenharmony_ci subprocess.run(['plutil', "-convert", 'binary1', self.file_name]) 10437db96d56Sopenharmony_ci 10447db96d56Sopenharmony_ci def write_pl(self): 10457db96d56Sopenharmony_ci """Write Hex properties to file using writePlist 10467db96d56Sopenharmony_ci """ 10477db96d56Sopenharmony_ci with open(self.file_name, 'wb') as f: 10487db96d56Sopenharmony_ci plistlib.dump(self.pl, f, fmt=plistlib.FMT_BINARY) 10497db96d56Sopenharmony_ci 10507db96d56Sopenharmony_ci def test_lint_status(self): 10517db96d56Sopenharmony_ci # check lint status of file using plutil 10527db96d56Sopenharmony_ci self.assertEqual(f"{self.file_name}: OK\n", self.get_lint_status()) 10537db96d56Sopenharmony_ci 10547db96d56Sopenharmony_ci def check_content(self): 10557db96d56Sopenharmony_ci # check file content with plutil converting binary to json 10567db96d56Sopenharmony_ci self.convert_to_json() 10577db96d56Sopenharmony_ci with open(self.file_name) as f: 10587db96d56Sopenharmony_ci ff = json.loads(f.read()) 10597db96d56Sopenharmony_ci self.assertEqual(ff, self.exptected_properties) 10607db96d56Sopenharmony_ci 10617db96d56Sopenharmony_ci def check_plistlib_parse(self): 10627db96d56Sopenharmony_ci # Generate plist files with plutil and parse with plistlib 10637db96d56Sopenharmony_ci self.convert_to_bin() 10647db96d56Sopenharmony_ci with open(self.file_name, 'rb') as f: 10657db96d56Sopenharmony_ci self.assertEqual(plistlib.load(f), self.exptected_properties) 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_ci def test_octal_and_hex(self): 10687db96d56Sopenharmony_ci self.write_pl() 10697db96d56Sopenharmony_ci self.convert_to_json() 10707db96d56Sopenharmony_ci with open(self.file_name, 'r') as f: 10717db96d56Sopenharmony_ci p = json.loads(f.read()) 10727db96d56Sopenharmony_ci self.assertEqual(p.get("HexType"), 16777228) 10737db96d56Sopenharmony_ci self.assertEqual(p.get("IntType"), 83) 10747db96d56Sopenharmony_ci 10757db96d56Sopenharmony_ciif __name__ == '__main__': 10767db96d56Sopenharmony_ci unittest.main() 1077