diff options
author | joerg <joerg@pkgsrc.org> | 2019-09-22 09:47:00 +0000 |
---|---|---|
committer | joerg <joerg@pkgsrc.org> | 2019-09-22 09:47:00 +0000 |
commit | 3d58b3c8e51f686500fbe08fc5fea947dfa036b4 (patch) | |
tree | 54a4af7c883e75c1a11634a0a7f52e5bdc174484 /archivers/libarchive/files/libarchive/archive_read_support_format_zip.c | |
parent | 8ebf4e7079542370a0dd5eba7eed1790d20c7f96 (diff) | |
download | pkgsrc-3d58b3c8e51f686500fbe08fc5fea947dfa036b4.tar.gz |
Import libarchive-3.3.3 as should have done originally.
Diffstat (limited to 'archivers/libarchive/files/libarchive/archive_read_support_format_zip.c')
-rw-r--r-- | archivers/libarchive/files/libarchive/archive_read_support_format_zip.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/archivers/libarchive/files/libarchive/archive_read_support_format_zip.c b/archivers/libarchive/files/libarchive/archive_read_support_format_zip.c index 4c4f6fad479..18f0d04e5c4 100644 --- a/archivers/libarchive/files/libarchive/archive_read_support_format_zip.c +++ b/archivers/libarchive/files/libarchive/archive_read_support_format_zip.c @@ -511,7 +511,13 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct case 0x5455: { /* Extended time field "UT". */ - int flags = p[offset]; + int flags; + if (datasize == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Incomplete extended time field"); + return ARCHIVE_FAILED; + } + flags = p[offset]; offset++; datasize--; /* Flag bits indicate which dates are present. */ @@ -723,6 +729,11 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct } case 0x9901: /* WinZip AES extra data field. */ + if (datasize < 6) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, + "Incomplete AES field"); + return ARCHIVE_FAILED; + } if (p[offset + 2] == 'A' && p[offset + 3] == 'E') { /* Vendor version. */ zip_entry->aes_extra.vendor = @@ -881,6 +892,24 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry, zip_entry->mode |= 0664; } + /* Windows archivers sometimes use backslash as the directory separator. + Normalize to slash. */ + if (zip_entry->system == 0 && + (wp = archive_entry_pathname_w(entry)) != NULL) { + if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) { + size_t i; + struct archive_wstring s; + archive_string_init(&s); + archive_wstrcpy(&s, wp); + for (i = 0; i < archive_strlen(&s); i++) { + if (s.s[i] == '\\') + s.s[i] = '/'; + } + archive_entry_copy_pathname_w(entry, s.s); + archive_wstring_free(&s); + } + } + /* Make sure that entries with a trailing '/' are marked as directories * even if the External File Attributes contains bogus values. If this * is not a directory and there is no type, assume regularfile. */ @@ -1056,6 +1085,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry, zip->end_of_entry = 1; /* Set up a more descriptive format name. */ + archive_string_empty(&zip->format_name); archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)", version / 10, version % 10, compression_name(zip->entry->compression)); |