An XFL document is a standard ZIP archive, as PKWARE’s APPNOTE describes it. Flash uses only the plain parts of ZIP: no encryption, no ZIP64, no spanning across disks. All numbers are little-endian. The archive is read from the end: the end record gives the central directory, and the central directory gives each member’s local header.
Local file header
Each member starts with a local file header of 30 bytes, then its name and extra field, then its data.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | Signature | 50 4B 03 04 (“PK\3\4”). |
| 4 | 2 | Version needed | The ZIP version needed to extract the member, times ten: 10 for stored, 20 for Deflate. |
| 6 | 2 | Flags | Bit 3: the CRC and sizes follow the data, in a data descriptor. Bit 11: the name is UTF-8. |
| 8 | 2 | Method | 0 stored, 8 Deflate. No other method occurs in XFL documents. |
| 10 | 2 | Time | MS-DOS time: hours (5 bits), minutes (6 bits), seconds ÷ 2 (5 bits). |
| 12 | 2 | Date | MS-DOS date: years since 1980 (7 bits), month (4 bits), day (5 bits). |
| 14 | 4 | CRC-32 | The CRC-32 of the uncompressed data; zero here when flag bit 3 is set. |
| 18 | 4 | Compressed size | The size of the data as stored. |
| 22 | 4 | Uncompressed size | The size of the data once inflated. |
| 26 | 2 | Name length | n, in bytes. |
| 28 | 2 | Extra field length | m, in bytes. |
| 30 | n | Name | The member’s path, with / between folders, such as LIBRARY/Tween 1.xml. |
| 30 + n | m | Extra field | Tagged blocks of extra data: a 2-byte tag, a 2-byte length and the data. |
When flag bit 3 is set, a data descriptor follows the data: an optional signature
50 4B 07 08, then the CRC-32, the compressed size and the uncompressed
size, four bytes each. The sizes in the central directory are then the ones to
trust.
Members
The data of each member follows its local header. In the XFL documents examined for this site:
- The XML files (
DOMDocument.xml, the symbol files inLIBRARY/,PublishSettings.xmland the rest) and the PNG images kept inLIBRARY/are compressed with Deflate (method 8, raw Deflate as in RFC 1951). - The members of
bin/, the JPEG images inLIBRARY/, themimetypemember and the.xflmarker are stored (method 0), as they are. - Folders have members of their own, with no data and a name ending in
/:LIBRARY/,META-INF/,LIBRARY/Assets/and so on.
To read a member: find its central directory record, go to the local header at the offset it gives, skip the 30 bytes, the name and the local extra field (whose length can differ from the central one), and take the compressed size of bytes. Inflate them if the method is 8, and check the CRC-32. The explorer shows each member as a byte range in the file and shows what it holds, once inflated, in the model, with offsets in the decompressed data. Bytes that no record points to are shown as unlisted bytes; they are often an older copy of a member.
The member list is in the files page.
Central directory
After the last member comes the central directory: one record for each member, 46 bytes followed by the name, the extra field and a comment.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | Signature | 50 4B 01 02. |
| 4 | 2 | Version made by | High byte: the system that made it (0 MS-DOS, 3 Unix, 19 macOS); low byte: the ZIP version times ten. |
| 6 | 2 | Version needed | As in the local header. |
| 8 | 2 | Flags | As in the local header. |
| 10 | 2 | Method | 0 stored, 8 Deflate. |
| 12 | 2 | Time | MS-DOS time. |
| 14 | 2 | Date | MS-DOS date. |
| 16 | 4 | CRC-32 | The CRC-32 of the uncompressed data. |
| 20 | 4 | Compressed size | The size as stored. |
| 24 | 4 | Uncompressed size | The size once inflated. |
| 28 | 2 | Name length | n. |
| 30 | 2 | Extra field length | m. |
| 32 | 2 | Comment length | k. |
| 34 | 2 | Disk number | The disk the member starts on: 0. |
| 36 | 2 | Internal attributes | Bit 0: the member is text. |
| 38 | 4 | External attributes | The system’s file attributes; for MS-DOS, 0x10 marks a folder. |
| 42 | 4 | Local header offset | Where the member’s local header starts, from the start of the file. |
| 46 | n | Name | The member’s path. |
| 46 + n | m | Extra field | Tagged extra data. |
| 46 + n + m | k | Comment | The member’s comment. |
End of central directory
The file ends with a 22-byte record and an optional comment. A reader finds it by searching back from the end for its signature.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | Signature | 50 4B 05 06. |
| 4 | 2 | Disk number | 0. |
| 6 | 2 | Central directory disk | 0. |
| 8 | 2 | Records on this disk | The number of central directory records on this disk: all of them. |
| 10 | 2 | Records | The number of central directory records, one a member. |
| 12 | 4 | Central directory size | Its size in bytes. |
| 16 | 4 | Central directory offset | Where it starts, from the start of the file. |
| 20 | 2 | Comment length | The length of the archive comment. |
| 22 | … | Comment | The archive comment. |
A record count of FFFF or an offset of FFFFFFFF would mean a
ZIP64 archive. XFL documents never are, and the explorer turns such a file down.
The mimetype member
Most XFL documents hold a stored member named mimetype whose 25 bytes are
the text application/vnd.adobe.xfl, with no line break. Unlike in EPUB or
OpenDocument files, it is not reliably the first member: in the files seen, all saved
by Flash CS5.5, it comes first in some and last in others. So it cannot be used to recognise the format; DOMDocument.xml is used instead.
Oddities
In the files seen whose mimetype member comes last, the central directory
size in the end record is exactly 54 bytes more than the records add up to (for
example 1,474 bytes given for 1,420 bytes of records). 54 is the size of one central
record for an 8-character name, 46 + 8, so it looks as if Flash counted the
mimetype record twice; this is an inference. Info-ZIP’s
unzip reports “missing 54 bytes” for such files and carries on. The
explorer reads the records by their count, not by the size, and reports the
mismatch.