aboutsummaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_zip.c
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2016-12-27 00:51:53 +0000
committerMartin Matuska <mm@FreeBSD.org>2016-12-27 00:51:53 +0000
commitcda329a1ca4579ea4cef22edbcc299737dd8cb76 (patch)
treeb7a646cd83cbffa9f0b2c8e55459db5f3175050d /libarchive/archive_read_support_format_zip.c
parentfb179c62da3d1cc4313f6f8f8e53b2e319999dd3 (diff)
Notes
Diffstat (limited to 'libarchive/archive_read_support_format_zip.c')
-rw-r--r--libarchive/archive_read_support_format_zip.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 9796fca161a6..d19e7914e11c 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -864,29 +864,33 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
zip_entry->mode |= AE_IFREG;
}
- if ((zip_entry->mode & AE_IFMT) == 0) {
- /* Especially in streaming mode, we can end up
- here without having seen proper mode information.
- Guess from the filename. */
+ /* If the mode is totally empty, set some sane default. */
+ if (zip_entry->mode == 0) {
+ zip_entry->mode |= 0664;
+ }
+
+ /* 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. */
+ if ((zip_entry->mode & AE_IFMT) != AE_IFDIR) {
+ int has_slash;
+
wp = archive_entry_pathname_w(entry);
if (wp != NULL) {
len = wcslen(wp);
- if (len > 0 && wp[len - 1] == L'/')
- zip_entry->mode |= AE_IFDIR;
- else
- zip_entry->mode |= AE_IFREG;
+ has_slash = len > 0 && wp[len - 1] == L'/';
} else {
cp = archive_entry_pathname(entry);
len = (cp != NULL)?strlen(cp):0;
- if (len > 0 && cp[len - 1] == '/')
- zip_entry->mode |= AE_IFDIR;
- else
- zip_entry->mode |= AE_IFREG;
+ has_slash = len > 0 && cp[len - 1] == '/';
}
- if (zip_entry->mode == AE_IFDIR) {
- zip_entry->mode |= 0775;
- } else if (zip_entry->mode == AE_IFREG) {
- zip_entry->mode |= 0664;
+ /* Correct file type as needed. */
+ if (has_slash) {
+ zip_entry->mode &= ~AE_IFMT;
+ zip_entry->mode |= AE_IFDIR;
+ zip_entry->mode |= 0111;
+ } else if ((zip_entry->mode & AE_IFMT) == 0) {
+ zip_entry->mode |= AE_IFREG;
}
}