]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merged revision(s) 4216 from trunk:
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 30 Jan 2012 06:19:37 +0000 (01:19 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 30 Jan 2012 06:19:37 +0000 (01:19 -0500)
Issue 236.
bsdtar creates invalid 7zip archives if there are no empty files.

SVN-Revision: 4217

libarchive/archive_write_set_format_7zip.c
libarchive/test/test_write_format_7zip.c

index 022b3a42fa9eb9fd5b9f23f84f13cb8131eaa8b6..3f7a45be665f98ea16a186458814d89c39bdf82a 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2011 Michihiro NAKAJIMA
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -727,8 +727,10 @@ _7z_close(struct archive_write *a)
                    zip->total_number_entry - zip->total_number_empty_entry;
 
                /* Connect an empty file list. */
-               *zip->file_list.last = zip->empty_list.first;
-               zip->file_list.last = zip->empty_list.last;
+               if (zip->empty_list.first != NULL) {
+                       *zip->file_list.last = zip->empty_list.first;
+                       zip->file_list.last = zip->empty_list.last;
+               }
                /* Connect a directory file list. */
                ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
                        file_register(zip, (struct file *)n);
index 5015af42bb05fe96b54644ca099bce13a20a9e70..b0f0a68fb6308d80a6394779c157545e16e53da7 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2011 Michihiro NAKAJIMA
+ * Copyright (c) 2011-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -317,6 +317,213 @@ test_basic(const char *compression_type)
        free(buff);
 }
 
+static void
+test_basic2(const char *compression_type)
+{
+       char filedata[64];
+       struct archive_entry *ae;
+       struct archive *a;
+       size_t used;
+       size_t buffsize = 1000;
+       char *buff;
+
+       buff = malloc(buffsize);
+
+       /* Create a new archive in memory. */
+       assert((a = archive_write_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+       if (compression_type != NULL &&
+           ARCHIVE_OK != archive_write_set_format_option(a, "7zip",
+           "compression", compression_type)) {
+               skipping("%s writing not fully supported on this platform",
+                  compression_type);
+               assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+               free(buff);
+               return;
+       }
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_write_open_memory(a, buff, buffsize, &used));
+
+       /*
+        * Write a file to it.
+        */
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_mtime(ae, 1, 100);
+       assertEqualInt(1, archive_entry_mtime(ae));
+       assertEqualInt(100, archive_entry_mtime_nsec(ae));
+       archive_entry_copy_pathname(ae, "file");
+       assertEqualString("file", archive_entry_pathname(ae));
+       archive_entry_set_mode(ae, AE_IFREG | 0755);
+       assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+       archive_entry_set_size(ae, 8);
+
+       assertEqualInt(0, archive_write_header(a, ae));
+       archive_entry_free(ae);
+       assertEqualInt(8, archive_write_data(a, "12345678", 9));
+       assertEqualInt(0, archive_write_data(a, "1", 1));
+
+       /*
+        * Write another file to it.
+        */
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_mtime(ae, 1, 10);
+       assertEqualInt(1, archive_entry_mtime(ae));
+       assertEqualInt(10, archive_entry_mtime_nsec(ae));
+       archive_entry_copy_pathname(ae, "file2");
+       assertEqualString("file2", archive_entry_pathname(ae));
+       archive_entry_set_mode(ae, AE_IFREG | 0755);
+       assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+       archive_entry_set_size(ae, 4);
+
+       assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+       archive_entry_free(ae);
+       assertEqualInt(4, archive_write_data(a, "1234", 5));
+
+       /*
+        * Write a directory to it.
+        */
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_mtime(ae, 11, 100);
+       archive_entry_copy_pathname(ae, "dir");
+       archive_entry_set_mode(ae, AE_IFDIR | 0755);
+       archive_entry_set_size(ae, 512);
+
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+       failure("size should be zero so that applications know not to write");
+       assertEqualInt(0, archive_entry_size(ae));
+       archive_entry_free(ae);
+       assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+       /*
+        * Write a sub directory to it.
+        */
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_mtime(ae, 11, 200);
+       archive_entry_copy_pathname(ae, "dir/subdir");
+       archive_entry_set_mode(ae, AE_IFDIR | 0755);
+       archive_entry_set_size(ae, 512);
+
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+       failure("size should be zero so that applications know not to write");
+       assertEqualInt(0, archive_entry_size(ae));
+       archive_entry_free(ae);
+       assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+       /*
+        * Write a sub sub-directory to it.
+        */
+       assert((ae = archive_entry_new()) != NULL);
+       archive_entry_set_mtime(ae, 11, 300);
+       archive_entry_copy_pathname(ae, "dir/subdir/subdir");
+       archive_entry_set_mode(ae, AE_IFDIR | 0755);
+       archive_entry_set_size(ae, 512);
+
+       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+       failure("size should be zero so that applications know not to write");
+       assertEqualInt(0, archive_entry_size(ae));
+       archive_entry_free(ae);
+       assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+       /* Close out the archive. */
+       assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+
+       /* Verify the initial header. */
+       assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8);
+
+       /*
+        * Now, read the data back.
+        */
+       /* With the test memory reader -- seeking mode. */
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+       assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7));
+
+       /*
+        * Read and verify first file.
+        */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualInt(1, archive_entry_mtime(ae));
+       assertEqualInt(100, archive_entry_mtime_nsec(ae));
+       assertEqualInt(0, archive_entry_atime(ae));
+       assertEqualInt(0, archive_entry_ctime(ae));
+       assertEqualString("file", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+       assertEqualInt(8, archive_entry_size(ae));
+       assertEqualIntA(a, 8,
+           archive_read_data(a, filedata, sizeof(filedata)));
+       assertEqualMem(filedata, "12345678", 8);
+
+
+       /*
+        * Read the second file back.
+        */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualInt(1, archive_entry_mtime(ae));
+       assertEqualInt(0, archive_entry_mtime_nsec(ae));
+       assertEqualInt(0, archive_entry_atime(ae));
+       assertEqualInt(0, archive_entry_ctime(ae));
+       assertEqualString("file2", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+       assertEqualInt(4, archive_entry_size(ae));
+       assertEqualIntA(a, 4,
+           archive_read_data(a, filedata, sizeof(filedata)));
+       assertEqualMem(filedata, "1234", 4);
+
+       /*
+        * Read the sub sub-dir entry back.
+        */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualInt(11, archive_entry_mtime(ae));
+       assertEqualInt(300, archive_entry_mtime_nsec(ae));
+       assertEqualInt(0, archive_entry_atime(ae));
+       assertEqualInt(0, archive_entry_ctime(ae));
+       assertEqualString("dir/subdir/subdir/", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+       assertEqualInt(0, archive_entry_size(ae));
+       assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+       /*
+        * Read the sub dir entry back.
+        */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualInt(11, archive_entry_mtime(ae));
+       assertEqualInt(200, archive_entry_mtime_nsec(ae));
+       assertEqualInt(0, archive_entry_atime(ae));
+       assertEqualInt(0, archive_entry_ctime(ae));
+       assertEqualString("dir/subdir/", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+       assertEqualInt(0, archive_entry_size(ae));
+       assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+       /*
+        * Read the dir entry back.
+        */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualInt(11, archive_entry_mtime(ae));
+       assertEqualInt(100, archive_entry_mtime_nsec(ae));
+       assertEqualInt(0, archive_entry_atime(ae));
+       assertEqualInt(0, archive_entry_ctime(ae));
+       assertEqualString("dir/", archive_entry_pathname(ae));
+       assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
+       assertEqualInt(0, archive_entry_size(ae));
+       assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+       /* Verify the end of the archive. */
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+       /* Verify archive format. */
+       assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+       assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+       assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+       free(buff);
+}
+
 /*
  * Test writing an empty archive.
  */
@@ -599,6 +806,8 @@ DEFINE_TEST(test_write_format_7zip)
        test_basic("lzma2");
        /* Test that making a 7-Zip archive file with PPMd compression. */
        test_basic("ppmd");
+       /* Test that making a 7-Zip archive file without empty files. */
+       test_basic2(NULL);
        /* Test that making an empty 7-Zip archive file. */
        test_empty_archive();
        /* Test that write an empty file. */