]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Issue 407: Tar reader tries to examine last character of an empty filename
authorTim Kientzle <kientzle@acm.org>
Sat, 21 Feb 2015 17:36:23 +0000 (09:36 -0800)
committerTim Kientzle <kientzle@acm.org>
Sat, 21 Feb 2015 17:36:23 +0000 (09:36 -0800)
Of interest:  While working on this, I noted that we have
an existing test for tar files with empty filenames.
That test asserts that the correct behavior here is for the
format handler to return the entry with the empty filename
and a status of ARCHIVE_OK.  Clients need to be robust against
empty filenames.

libarchive/archive_read_support_format_tar.c

index 37399a0ef371982dfde668953d3268754059f71a..1e780936b83312af1d3d3ba76f24ba4a67098f13 100644 (file)
@@ -456,6 +456,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
        static int default_dev;
        struct tar *tar;
        const char *p;
+       const wchar_t *wp;
        int r;
        size_t l, unconsumed = 0;
 
@@ -506,27 +507,22 @@ archive_read_format_tar_read_header(struct archive_read *a,
                }
        }
 
-       if (r == ARCHIVE_OK) {
+       if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) {
                /*
                 * "Regular" entry with trailing '/' is really
                 * directory: This is needed for certain old tar
                 * variants and even for some broken newer ones.
                 */
-               const wchar_t *wp;
-               wp = archive_entry_pathname_w(entry);
-               if (wp != NULL) {
+               if ((wp = archive_entry_pathname_w(entry)) != NULL) {
                        l = wcslen(wp);
-                       if (archive_entry_filetype(entry) == AE_IFREG
-                           && wp[l-1] == L'/')
+                       if (l > 0 && wp[l - 1] == L'/') {
                                archive_entry_set_filetype(entry, AE_IFDIR);
-               } else {
-                       p = archive_entry_pathname(entry);
-                       if (p == NULL)
-                               return (ARCHIVE_FAILED);
+                       }
+               } else if ((p = archive_entry_pathname(entry)) != NULL) {
                        l = strlen(p);
-                       if (archive_entry_filetype(entry) == AE_IFREG
-                           && p[l-1] == '/')
+                       if (l > 0 && p[l - 1] == '/') {
                                archive_entry_set_filetype(entry, AE_IFDIR);
+                       }
                }
        }
        return (r);