Blob Blame History Raw
From bb9b157146a62e655fb369b32684398c949fa1b1 Mon Sep 17 00:00:00 2001
From: Tim Kientzle <kientzle@acm.org>
Date: Sat, 21 Feb 2015 09:36:23 -0800
Subject: [PATCH] Issue 407: Tar reader tries to examine last character of an
 empty filename

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 | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index 37399a0..1e78093 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -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);
-- 
2.7.4