The binary form is the one Apple’s tools usually write. A file starts with the eight
bytes bplist00, and everything is found through a table at the end. All
multi-byte integers in the header, trailer and objects are big-endian.
Layout
0Header the eight bytesbplist008 bytes8Objects one after another, in any ordervariestableAtOffset table where each object startscount × offsetSizesize − 32Trailer how to read the rest32 bytes
Trailer
The last 32 bytes. A reader starts here.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 5 | Unused | Written as zero. |
| 5 | 1 | Sort version | Written as 0. |
| 6 | 1 | offsetIntSize | Bytes in each offset table entry, 1 to 8. |
| 7 | 1 | objectRefSize | Bytes in each object number inside arrays, sets and dictionaries, 1 to 8. |
| 8 | 8 | numObjects | The number of objects. |
| 16 | 8 | topObject | The number of the root object, less than numObjects. |
| 24 | 8 | offsetTableOffset | Where the offset table starts, from the start of the file. |
Offset table
numObjects entries of offsetIntSize bytes each. Entry n
is the offset of object n from the start of the file. Objects need not be in
the file in order of their numbers.
The object numbers are what arrays and dictionaries hold. Two entries may hold the same offset, and an object can be referred to from many places.
Objects and their markers
Every object starts with a marker byte. The high four bits (the first hexadecimal digit) give the type, and the low four bits usually hold the count of what follows.
| Marker | Type | What follows |
|---|---|---|
00 | null | Nothing. |
08 | false | Nothing. |
09 | true | Nothing. |
0C | URL, no base | One object number: a string. |
0D | URL with base | Two object numbers: the base, then the string. |
0E | UUID | 16 bytes. |
0F | Fill | Nothing: a byte used only as padding. |
1n | Integer | 2n bytes, big-endian. Eight-byte integers are signed; one-, two- and four-byte integers are unsigned. |
2n | Real | 2n bytes: n = 2 is a 32-bit float, n = 3 a 64-bit double. |
33 | Date | 8 bytes: a 64-bit double counting seconds from 2001-01-01 00:00:00 UTC. |
4n | Data | n bytes, or a count object then that many bytes. |
5n | String | n bytes of ASCII, or a count object then that many. |
6n | String | n UTF-16 code units, big-endian, or a count object then that many. |
7n | String | n bytes of UTF-8, or a count object then that many. |
8n | UID | n + 1 bytes, big-endian: a small unsigned number used by NSKeyedArchiver’s archives. |
An | Array | n object numbers of objectRefSize bytes each, or a count object then that many. |
Bn | Ordered set | As an array. |
Cn | Set | As an array. |
Dn | Dictionary | n pairs: all n key numbers, then all n value numbers, or a count object first when there are 15 or more. |
Counts of 15 or more. Where the low four bits hold a count, the value
F means the count did not fit: an integer object (1n and its
bytes) follows the marker, and the payload follows that.
Markers not listed are not used. Dictionary keys are normally strings.
Other versions
The last two bytes of the header are a version. 00 is the version that
Apple’s tools write and that this page describes. Other values are reported to exist
(bplist15 and bplist16 have been seen), but they are not
publicly documented, so this site does not describe them, and its viewer turns them
down.
A complete file
A small list with two keys. Its value, written as JSON, would be
{"a": 1, "b": [true, "hi"]}. All 65 bytes:
00000000 62 70 6C 69 73 74 30 30 D2 01 02 03 04 51 61 51 bplist00.....QaQ
00000010 62 10 01 A2 05 06 09 52 68 69 08 0D 0F 11 13 16 b......Rhi......
00000020 17 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 ................
00000030 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040 1A .
| Offset | Bytes | Object | Meaning |
|---|---|---|---|
| 0x08 | D2 01 02 03 04 | 0 | A dictionary of 2 pairs: keys are objects 1 and 2, values are objects 3 and 4. This is the root. |
| 0x0D | 51 61 | 1 | An ASCII string of 1 byte: a |
| 0x0F | 51 62 | 2 | b |
| 0x11 | 10 01 | 3 | An integer of 1 byte: 1 |
| 0x13 | A2 05 06 | 4 | An array of 2: objects 5 and 6. |
| 0x16 | 09 | 5 | true |
| 0x17 | 52 68 69 | 6 | hi |
| 0x1A | 7 bytes | The offset table, 1-byte entries. | |
| 0x21 | 32 bytes | The trailer: offsets are 1 byte, object numbers 1 byte, 7 objects, top object 0, table at 0x1A. |
Reading safely
Everything in a binary list is reached by number or offset, so a damaged or hostile file can point anywhere. A reader should check that every offset lies inside the object area, that counts fit in the bytes that remain, and that no object contains itself: an array may name its own number, and following it would never end.