]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
The same changes of In the Xar writer, ignore ineffective path names in the Xar archive
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 10 Jul 2011 07:59:58 +0000 (03:59 -0400)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sun, 10 Jul 2011 07:59:58 +0000 (03:59 -0400)
such as "." , "/" or "../" and fix that handling. This is the same as the recent changes of
the ISO9660 writer.

SVN-Revision: 3467

libarchive/archive_write_set_format_xar.c
libarchive/test/test_write_format_xar_empty.c

index deb67cc6db4cb3e59e5a52eea166931e88f6172f..53489e1c3ea1c11ff788f895e5208220c1ba19d9 100644 (file)
@@ -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;
        }
index cad9dbcf5f900539007cf0e89095deaa1dc2ead0..c9e6c4a221f1aa65b624a97c6bf4f3b28ada5a6b 100644 (file)
@@ -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));