Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions testdata/readme.extra_data_before_central_directory
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
Section 4.3.6 specifies the layout of a ZIP file:

```
4.3.6 Overall .ZIP file format:

[local file header 1]
[encryption header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[encryption header n]
[file data n]
[data descriptor n]
[archive decryption header]
[archive extra data record]
[central directory header 1]
.
.
.
[central directory header n]
[zip64 end of central directory record]
[zip64 end of central directory locator]
[end of central directory record]
```

According to this layout there can be no layout between the last local file
header and the first central directory header, yet there are many files in
which this happens. As an example, Android packages store a signing block right
after the last local file header:

<https://source.android.com/docs/security/features/apksigning/v2>

Although this is not allowed APK files can still be unpacked, as programs use
the central directory to find the offsets to each individual file and
effectively skip the extra data. None of the regular ZIP programs seem to be
able to extract this extra data.

To create a file with extra data only one field needs to be adapted (not
tested for ZIP64 files) in the "end of central directory" (section 4.3.16),
namely:

```
offset of start of central directory with respect to the starting disk number
```

The file `test_with_extra_data_before_central_directory.zip` is a modified
version of `test.zip` with an addition 1024 bytes added in between the last
local file header and the first central directory header. This means that the
central directory is moved an additional 1024 bytes. This can be shown by
comparing the output of `hexdump -C` for both files:

The position of the central directory in the original file is `ba 03`:

```
00000470 00 00 ba 03 00 00 1a 00 54 68 69 73 20 69 73 20 |........This is |
```

In the new file the central directory has been moved 1024 bytes and is now
`ba 07`:

```
00000870 00 00 ba 07 00 00 1a 00 54 68 69 73 20 69 73 20 |........This is |
```
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
---
source: ziplinter/src/lib.rs
expression: result
---
{
"comment": "This is a zipfile comment.",
"contents": [
{
"central": {
"comment": "",
"compressed_size": 25,
"crc32": 3287144384,
"creator_version": {
"host_system": "Unix",
"version": 30
},
"disk_nbr_start": 0,
"external_attrs": 2175008768,
"extra": [
85,
84,
5,
0,
3,
113,
252,
130,
76,
117,
120,
11,
0,
1,
4,
245,
1,
0,
0,
4,
20,
0,
0,
0
],
"flags": 0,
"header_offset": 0,
"internal_attrs": 1,
"method": "Deflate",
"mode": 420,
"modified": "2010-09-05T02:12:01Z",
"name": "test.txt",
"reader_version": {
"host_system": "MsDos",
"version": 20
},
"uncompressed_size": 26
},
"local": {
"accessed": null,
"compressed_size": 25,
"crc32": 3287144384,
"created": null,
"extra": [
85,
84,
9,
0,
3,
113,
252,
130,
76,
118,
252,
130,
76,
117,
120,
11,
0,
1,
4,
245,
1,
0,
0,
4,
20,
0,
0,
0
],
"flags": 0,
"gid": 501,
"header_offset": 0,
"method": "Deflate",
"method_specific": "None",
"mode": 0,
"modified": "2010-09-05T02:12:01Z",
"name": "test.txt",
"reader_version": {
"host_system": "MsDos",
"version": 20
},
"uid": 501,
"uncompressed_size": 26
}
},
{
"central": {
"comment": "",
"compressed_size": 785,
"crc32": 1423258110,
"creator_version": {
"host_system": "Unix",
"version": 30
},
"disk_nbr_start": 0,
"external_attrs": 2175008768,
"extra": [
85,
84,
5,
0,
3,
58,
48,
131,
76,
117,
120,
11,
0,
1,
4,
245,
1,
0,
0,
4,
20,
0,
0,
0
],
"flags": 0,
"header_offset": 91,
"internal_attrs": 0,
"method": "Store",
"mode": 420,
"modified": "2010-09-05T05:52:58Z",
"name": "gophercolor16x16.png",
"reader_version": {
"host_system": "MsDos",
"version": 10
},
"uncompressed_size": 785
},
"local": {
"accessed": null,
"compressed_size": 785,
"crc32": 1423258110,
"created": null,
"extra": [
85,
84,
9,
0,
3,
58,
48,
131,
76,
59,
48,
131,
76,
117,
120,
11,
0,
1,
4,
245,
1,
0,
0,
4,
20,
0,
0,
0
],
"flags": 0,
"gid": 501,
"header_offset": 0,
"method": "Store",
"method_specific": "None",
"mode": 0,
"modified": "2010-09-05T05:52:58Z",
"name": "gophercolor16x16.png",
"reader_version": {
"host_system": "MsDos",
"version": 10
},
"uid": 501,
"uncompressed_size": 785
}
}
],
"encoding": "Utf8",
"eocd": {
"dir": {
"inner": {
"dir_disk_nbr": 0,
"dir_records_this_disk": 2,
"directory_offset": 1978,
"directory_records": 2,
"directory_size": 168,
"disk_nbr": 0
},
"offset": 2146
},
"dir64": null,
"global_offset": 0
},
"parsed_ranges": [
{
"contains": "end of central directory record",
"end": 2194,
"start": 2146
},
{
"contains": "central directory header",
"end": 2056,
"filename": "test.txt",
"start": 1978
},
{
"contains": "central directory header",
"end": 2146,
"filename": "gophercolor16x16.png",
"start": 2056
},
{
"contains": "local file header",
"end": 66,
"filename": "test.txt",
"start": 0
},
{
"contains": "file data",
"end": 91,
"filename": "test.txt",
"start": 66
},
{
"contains": "local file header",
"end": 169,
"filename": "gophercolor16x16.png",
"start": 91
},
{
"contains": "file data",
"end": 954,
"filename": "gophercolor16x16.png",
"start": 169
}
],
"size": 2194
}
Loading