From 9dfccdc227f530997203ab9eb509a861f6718f59 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 27 Mar 2017 16:49:05 -0400 Subject: libarchive: backport zip directory recognition fix Backport upstream libarchive commit 2ecf8d1c1e (Try harder to detect directories in zip archives, 2016-12-23). Fixes: #16741 --- .../libarchive/archive_read_support_format_zip.c | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c index c50ba84..8df52c3 100644 --- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c +++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c @@ -850,29 +850,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; } } -- cgit v0.12