summaryrefslogtreecommitdiff
path: root/archivers/libarchive/files/libarchive/archive_read_support_format_zip.c
diff options
context:
space:
mode:
authorjoerg <joerg@pkgsrc.org>2019-09-22 09:47:00 +0000
committerjoerg <joerg@pkgsrc.org>2019-09-22 09:47:00 +0000
commit3d58b3c8e51f686500fbe08fc5fea947dfa036b4 (patch)
tree54a4af7c883e75c1a11634a0a7f52e5bdc174484 /archivers/libarchive/files/libarchive/archive_read_support_format_zip.c
parent8ebf4e7079542370a0dd5eba7eed1790d20c7f96 (diff)
downloadpkgsrc-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.c32
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));