Skip to content
Open
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
31 changes: 17 additions & 14 deletions lib/zip_dirent.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,20 +506,6 @@ zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t
return -1;
}
}

if (check_consistency) {
zip_uint8_t *p;

for (p = zde->filename->raw; p < zde->filename->raw + zde->filename->length; p++) {
if (*p == 0) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_NUL_IN_FILENAME);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
}
}
}

if (ef_len) {
Expand Down Expand Up @@ -571,6 +557,23 @@ zip_int64_t _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t
return -1;
}
zde->filename = utf8_string;

/* Check for a NUL byte in the final name; the Info-ZIP Unicode Path extra
field can replace zde->filename above, so this must run after that. */
if (check_consistency && zde->filename != NULL) {
zip_uint8_t *p;

for (p = zde->filename->raw; p < zde->filename->raw + zde->filename->length; p++) {
if (*p == 0) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_NUL_IN_FILENAME);
if (!from_buffer) {
_zip_buffer_free(buffer);
}
return -1;
}
}
}

if (!local) {
if ((utf8_string = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment, check_consistency)) == NULL && zde->comment != NULL) {
zip_error_set(error, ZIP_ER_INCONS, ZIP_ER_DETAIL_UTF8_COMMENT_MISMATCH);
Expand Down
Binary file added regress/incons-utf8-nul-in-name.zip
Binary file not shown.
15 changes: 15 additions & 0 deletions regress/open_incons_utf8_nul_in_name.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# zip_open with consistency checking must reject an entry whose name contains a
# NUL byte. Here the header name is "A", but an Info-ZIP Unicode Path extra
# field (0x7075) with a matching CRC replaces it with the bytes 00 C3 A9
# (U+0000 U+00E9), so the NUL only appears in the final name. The check must
# run after the extra field is applied.
program tryopen
arguments -c -s test.zzip
file test.zzip incons-utf8-nul-in-name.zip
return 1
stdout
opening 'test.zzip' returned error Zip archive inconsistent: entry 0: NUL byte in file name
end-of-inline-data
stderr
1 errors
end-of-inline-data