From: Michihiro NAKAJIMA Date: Sun, 10 Jul 2011 07:59:58 +0000 (-0400) Subject: The same changes of In the Xar writer, ignore ineffective path names in the Xar archive X-Git-Tag: v3.0.0a~247 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43891c8226c479d0d000727cb485e46f706d85ab;p=thirdparty%2Flibarchive.git The same changes of In the Xar writer, ignore ineffective path names in the Xar archive such as "." , "/" or "../" and fix that handling. This is the same as the recent changes of the ISO9660 writer. SVN-Revision: 3467 --- diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c index deb67cc6d..53489e1c3 100644 --- a/libarchive/archive_write_set_format_xar.c +++ b/libarchive/archive_write_set_format_xar.c @@ -531,6 +531,16 @@ xar_write_header(struct archive_write *a, struct archive_entry *entry) if (r2 < ARCHIVE_WARN) return (r2); + /* + * Ignore a path which looks like the top of directory name + * since we have already made the root directory of an Xar archive. + */ + if (archive_strlen(&(file->parentdir)) == 0 && + archive_strlen(&(file->basename)) == 0) { + file_free(file); + return (r2); + } + /* Add entry into tree */ file_entry = file->entry; r = file_tree(a, &file); @@ -2027,22 +2037,24 @@ file_gen_utility_names(struct archive_write *a, struct file *file) */ cleanup_backslash(p, len); - if (p[0] == '/') { - p++; - len--; - } /* - * Remove leading '../' and './' elements + * Remove leading '/', '../' and './' elements */ while (*p) { - if (p[0] != '.') + if (p[0] == '/') { + p++; + len--; + } else if (p[0] != '.') break; - if (p[1] == '.' && p[2] == '/') { + else if (p[1] == '.' && p[2] == '/') { p += 3; len -= 3; - } else if (p[1] == '/') { + } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) { p += 2; len -= 2; + } else if (p[1] == '\0') { + p++; + len--; } else break; } diff --git a/libarchive/test/test_write_format_xar_empty.c b/libarchive/test/test_write_format_xar_empty.c index cad9dbcf5..c9e6c4a22 100644 --- a/libarchive/test/test_write_format_xar_empty.c +++ b/libarchive/test/test_write_format_xar_empty.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010 Michihiro NAKAJIMA + * Copyright (c) 2010-2011 Michihiro NAKAJIMA * Copyright (c) 2008 Anselm Strauss * All rights reserved. * @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); DEFINE_TEST(test_write_format_xar_empty) { struct archive *a; + struct archive_entry *ae; char buff[256]; size_t used; @@ -50,6 +51,66 @@ DEFINE_TEST(test_write_format_xar_empty) assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); + /* Add "." entry which must be ignored. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 0); + archive_entry_set_ctime(ae, 4, 0); + archive_entry_set_mtime(ae, 5, 0); + archive_entry_copy_pathname(ae, "."); + archive_entry_set_mode(ae, S_IFDIR | 0755); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Add ".." entry which must be ignored. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 0); + archive_entry_set_ctime(ae, 4, 0); + archive_entry_set_mtime(ae, 5, 0); + archive_entry_copy_pathname(ae, ".."); + archive_entry_set_mode(ae, S_IFDIR | 0755); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Add "/" entry which must be ignored. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 0); + archive_entry_set_ctime(ae, 4, 0); + archive_entry_set_mtime(ae, 5, 0); + archive_entry_copy_pathname(ae, "/"); + archive_entry_set_mode(ae, S_IFDIR | 0755); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Add "../" entry which must be ignored. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 0); + archive_entry_set_ctime(ae, 4, 0); + archive_entry_set_mtime(ae, 5, 0); + archive_entry_copy_pathname(ae, "../"); + archive_entry_set_mode(ae, S_IFDIR | 0755); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Add "../../." entry which must be ignored. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 0); + archive_entry_set_ctime(ae, 4, 0); + archive_entry_set_mtime(ae, 5, 0); + archive_entry_copy_pathname(ae, "../../."); + archive_entry_set_mode(ae, S_IFDIR | 0755); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Add "..//.././" entry which must be ignored. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 0); + archive_entry_set_ctime(ae, 4, 0); + archive_entry_set_mtime(ae, 5, 0); + archive_entry_copy_pathname(ae, "..//.././"); + archive_entry_set_mode(ae, S_IFDIR | 0755); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + /* Close out the archive without writing anything. */ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a));