The end header, which the signature
header points to, describes the packed streams, how to unpack them and which files
they hold. It is a tree of sections, each opened by a one-byte property ID and most
closed by kEnd (00). Numbers written UINT64 are
the variable-length numbers of
1 to 9 bytes.
Property IDs
| ID | Name | Where it is used |
|---|---|---|
00 | kEnd | Ends a section or a list of properties. |
01 | kHeader | Starts a plain header. |
02 | kArchiveProperties | Archive properties, a list of type, size and data. |
03 | kAdditionalStreamsInfo | Streams holding data that the header refers to as “external”. |
04 | kMainStreamsInfo | The streams that hold the files’ data. |
05 | kFilesInfo | The list of files and their properties. |
06 | kPackInfo | Where the packed streams are and how big. |
07 | kUnPackInfo | The folders: coders and how their streams connect. |
08 | kSubStreamsInfo | How each folder’s output divides into files. |
09 | kSize | A list of sizes. |
0A | kCRC | A list of CRC-32 digests. |
0B | kFolder | The folder records. |
0C | kCodersUnPackSize | The unpacked size of every coder output. |
0D | kNumUnPackStream | How many files each folder holds. |
0E | kEmptyStream | Files property: which items have no data stream (folders and empty files). |
0F | kEmptyFile | Files property: which empty-stream items are empty files rather than folders. |
10 | kAnti | Files property: which empty-stream items are “anti-items”, which delete a file when an update archive is applied. |
11 | kName | Files property: names. |
12 | kCTime | Files property: creation times. |
13 | kATime | Files property: last access times. |
14 | kMTime | Files property: modification times. |
15 | kWinAttributes | Files property: attributes. |
16 | kComment | Comment. Listed in the specification with no layout. |
17 | kEncodedHeader | The end header is packed: the streams information that follows says how to unpack it. |
18 | kStartPos | Files property: start position. Listed with no layout. |
19 | kDummy | Files property: padding, skipped by readers. 7-Zip writes it so that the names that follow start on an even offset. |
Newer 7-Zip versions read and write further file properties with higher IDs (such
as kNtSecure for Windows security data); they are not in
7zFormat.txt. A reader skips any files property it does not know, using
its size.
Header
| Item | Type | Meaning |
|---|---|---|
kHeader | BYTE 01 | Start of the header. |
| Archive properties | optional | 02, then repeated: BYTE type (00 ends the list), UINT64 size, the data. |
| Additional streams | optional | 03, then streams info. |
| Main streams | optional | 04, then streams info. |
| Files | optional | Files info. |
kEnd | BYTE 00 | End of the header. |
An encoded header is 17 followed by streams info (pack info and unpack
info, normally one folder). Unpacking that folder gives the bytes of a plain header,
starting with 01. It may itself be encoded again, though 7-Zip does not
do that.
Streams info
Pack info, unpack info and substreams info, each optional, in that order, then
kEnd.
Pack info
| Item | Type | Meaning |
|---|---|---|
kPackInfo | BYTE 06 | |
PackPos | UINT64 | Where the first packed stream starts, counted from offset 32. |
NumPackStreams | UINT64 | How many packed streams follow one another from there. |
| Sizes | optional | 09, then UINT64 PackSizes[NumPackStreams]. |
| Digests | optional | 0A, then digests of the packed streams. |
kEnd | BYTE 00 |
Unpack info (coders info)
| Item | Type | Meaning |
|---|---|---|
kUnPackInfo | BYTE 07 | |
kFolder | BYTE 0B | |
NumFolders | UINT64 | Number of folders. |
External | BYTE | 0: the folder records follow. 1: a UINT64 DataStreamIndex follows and the records are in that additional stream. |
kCodersUnPackSize | BYTE 0C | |
| Unpack sizes | UINT64 each | For every folder, one size for every output stream of every coder in it. |
| Digests | optional | 0A, then digests of each folder’s final output. |
kEnd | BYTE 00 |
Substreams info
A folder’s output can hold several files one after another (a solid block). This section says how many and how big.
| Item | Type | Meaning |
|---|---|---|
kSubStreamsInfo | BYTE 08 | |
| Counts | optional | 0D, then UINT64 NumUnPackStreams for each folder. Without it, each folder holds one stream. |
| Sizes | optional | 09, then UINT64 sizes: for each folder with n streams, the first n − 1 sizes. The last one is the folder’s unpack size minus the others. |
| Digests | optional | 0A, then digests for every stream whose CRC is not already known: a folder with exactly one stream and a folder CRC already has one. |
kEnd | BYTE 00 |
Digests
| Item | Type | Meaning |
|---|---|---|
AllAreDefined | BYTE | Non-zero: every item has a CRC. 0: a bit array of n items says which have one. |
Defined | BIT[n] | Only when AllAreDefined is 0. |
CRCs | UINT32[] | One CRC-32 for each defined item. |
Folder
A folder is a small graph of coders: decompressors, filters and decryptors. Each coder has input and output streams; bind pairs connect one coder’s stream to another’s, and the streams left unconnected are read from packed streams.
| Item | Type | Meaning |
|---|---|---|
NumCoders | UINT64 | Number of coders. 7-Zip allows at most 64. |
| Coder flags | BYTE | See coder flags. |
CodecId | BYTE[CodecIdSize] | The method ID, big-endian as written in the method list. |
NumInStreams, NumOutStreams | UINT64 each | Only for a complex coder. A simple coder has one of each. |
PropertiesSize, Properties | UINT64, bytes | Only when the coder has attributes: the method’s properties, such as LZMA’s dictionary size. |
| Bind pairs | UINT64 InIndex, UINT64 OutIndex | One fewer than the total number of output streams. |
| Packed stream indexes | UINT64[] | The number of packed streams is the total of input streams minus the bind pairs. When it is more than one, the index of each is listed; when it is one, it is the single unbound input. |
The flags, ID, stream counts and properties repeat for each coder before the bind pairs. 7-Zip uses these names from the writer’s side: when compressing, BCJ2 has one input and four outputs; the reader sees four packed streams that make one file stream.
Coder flags
| Bits | Name | Meaning |
|---|---|---|
| 0 to 3 | CodecIdSize | Length of the method ID in bytes (the specification labels the field bits 0:3). |
| 4 | IsComplexCoder | Set: the coder has its own stream counts. |
| 5 | HasAttributes | Set: properties follow. |
| 6 | reserved | Zero. |
| 7 | alternative methods | Meant for “more alternative methods”; not used, must be zero. |
A typical LZMA2 coder is 21 21 01 18: flags 21 (ID size 1,
has attributes), ID 21 (LZMA2), one byte of properties, 18
(a 16 MiB dictionary).
Files info
| Item | Type | Meaning |
|---|---|---|
kFilesInfo | BYTE 05 | |
NumFiles | UINT64 | Number of items: files, folders and anti-items. |
| Properties | repeated | BYTE property ID (00 ends the list), UINT64 size, then that many bytes. |
| Property | Data |
|---|---|
0E kEmptyStream | BIT[NumFiles]: set for each item with no data. Items without the bit take the substreams in order. |
0F kEmptyFile | BIT[number of empty streams]: set when that empty-stream item is a file of zero length. Clear means a folder. |
10 kAnti | BIT[number of empty streams]: set when that item is an anti-item. |
11 kName | BYTE External; if non-zero, UINT64 DataIndex of an additional stream holding the names. Otherwise one name per item: UTF-16LE characters ending with a zero character. A name is the item’s whole path inside the archive. |
12, 13, 14 times | BYTE AllAreDefined; if 0, BIT[NumFiles] defined; BYTE External; if non-zero, UINT64 DataIndex; then a REAL_UINT64 for each defined item: a Windows FILETIME, in 100-nanosecond units since 1 January 1601 UTC. |
15 kWinAttributes | BYTE AllAreDefined; if 0, BIT[NumFiles]; BYTE External; if non-zero, UINT64 DataIndex; then a UINT32 for each defined item. |
18 kStartPos | Listed with no layout in the specification. |
19 kDummy | Padding bytes; skip. |
The format description does not say which character separates the folders in a
path. Archives in the wild use / or \ depending on the
writer, so a reader should accept both.
Attributes
The low 16 bits are Windows file attributes: 01 read-only,
02 hidden, 04 system, 10 directory,
20 archive, 80 normal, 400 reparse point and so
on. When bit 15 (0x8000, called FILE_ATTRIBUTE_UNIX_EXTENSION
in 7-Zip’s source) is set, the high 16 bits hold the Unix st_mode: file
type and permission bits. 7-Zip and p7zip write this on Unix. It is a convention of
the program, not part of 7zFormat.txt.