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