]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix the bug which the patch for issue 249 made, which bug is that
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 20 Mar 2012 04:14:40 +0000 (13:14 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Tue, 20 Mar 2012 04:54:01 +0000 (13:54 +0900)
sometimes sumcheck error hppens when listing a CAB file whose
compression type is none.
 - Do not consume extra bytes when the compression type is none.
 - Improve test_read_format_cab to just read file names, not read
   file contents such as "bsdtar tf".

libarchive/archive_read_support_format_cab.c
libarchive/test/test_read_format_cab.c

index ac400465c9db577699606cac6f2761ed7195db89..bc866a375b7d3f653696774d17e4205967f71822 100644 (file)
@@ -1358,46 +1358,25 @@ cab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail)
        struct cab *cab = (struct cab *)(a->format->data);
        struct cfdata *cfdata;
        const void *d;
-       int64_t skipped_bytes;
 
        cfdata = cab->entry_cfdata;
 
-       if (cfdata->uncompressed_avail == 0 &&
-               cfdata->read_offset > 0) {
-               /* we've already skipped some bytes before really read. */
-               skipped_bytes = cfdata->read_offset;
-               cfdata->read_offset = 0;
-               cfdata->uncompressed_bytes_remaining += skipped_bytes;
-       } else
-               skipped_bytes = 0;
-       do {
-               /*
-                * Note: '1' here is a performance optimization.
-                * Recall that the decompression layer returns a count of
-                * available bytes; asking for more than that forces the
-                * decompressor to combine reads by copying data.
-                */
-               d = __archive_read_ahead(a, 1, avail);
-               if (*avail <= 0) {
-                       *avail = truncated_error(a);
-                       return (NULL);
-               }
-               if (*avail > cfdata->uncompressed_bytes_remaining)
-                       *avail = cfdata->uncompressed_bytes_remaining;
-               cfdata->uncompressed_avail = cfdata->uncompressed_size;
-               cfdata->unconsumed = *avail;
-               cfdata->sum_ptr = d;
-               if (skipped_bytes > 0) {
-                       skipped_bytes =
-                           cab_minimum_consume_cfdata(a, skipped_bytes);
-                       if (skipped_bytes < 0) {
-                               *avail = ARCHIVE_FATAL;
-                               return (NULL);
-                       }
-                       continue;
-               }
-       } while (0);
-
+       /*
+        * Note: '1' here is a performance optimization.
+        * Recall that the decompression layer returns a count of
+        * available bytes; asking for more than that forces the
+        * decompressor to combine reads by copying data.
+        */
+       d = __archive_read_ahead(a, 1, avail);
+       if (*avail <= 0) {
+               *avail = truncated_error(a);
+               return (NULL);
+       }
+       if (*avail > cfdata->uncompressed_bytes_remaining)
+               *avail = cfdata->uncompressed_bytes_remaining;
+       cfdata->uncompressed_avail = cfdata->uncompressed_size;
+       cfdata->unconsumed = *avail;
+       cfdata->sum_ptr = d;
        return (d);
 }
 
@@ -1992,6 +1971,11 @@ archive_read_format_cab_read_data_skip(struct archive_read *a)
        if (bytes_skipped < 0)
                return (ARCHIVE_FATAL);
 
+       /* If the compression type is none(uncompressed), we've already
+        * consumed data as much as the current entry size. */
+       if (cab->entry_cffolder->comptype == COMPTYPE_NONE)
+               cab->entry_cfdata->unconsumed = 0;
+
        /* This entry is finished and done. */
        cab->end_of_entry_cleanup = cab->end_of_entry = 1;
        return (ARCHIVE_OK);
index 8e7d55f84402498dfbdf36a4548a94f78e12b723..54dd633f284977216aea562e6923bce7510d9a93 100644 (file)
@@ -324,16 +324,66 @@ verify2(const char *refname, enum comp_type comp)
        assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 }
 
+/*
+ * Skip all file like 'bsdtar tvf foo.cab'.
+ */
+static void
+verify3(const char *refname, enum comp_type comp)
+{
+       struct archive_entry *ae;
+       struct archive *a;
+       char zero[128];
+
+       memset(zero, 0, sizeof(zero));
+       extract_reference_file(refname);
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_open_filename(a, refname, 10240));
+
+       /* Verify regular empty. */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       if (comp != STORE) {
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       }
+       /* Verify regular file1. */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+       /* Verify regular file2. */
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+
+       /* End of archive. */
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+       if (comp != STORE) {
+               assertEqualInt(4, archive_file_count(a));
+       } else {
+               assertEqualInt(3, archive_file_count(a));
+       }
+
+       /* Verify archive format. */
+       assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a));
+       assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a));
+
+       /* Close the archive. */
+       assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
 DEFINE_TEST(test_read_format_cab)
 {
        /* Verify Cabinet file in no compression. */
        verify("test_read_format_cab_1.cab", STORE);
        verify2("test_read_format_cab_1.cab", STORE);
+       verify3("test_read_format_cab_1.cab", STORE);
        /* Verify Cabinet file in MSZIP. */
        verify("test_read_format_cab_2.cab", MSZIP);
        verify2("test_read_format_cab_2.cab", MSZIP);
+       verify3("test_read_format_cab_2.cab", MSZIP);
        /* Verify Cabinet file in LZX. */
        verify("test_read_format_cab_3.cab", LZX);
        verify2("test_read_format_cab_3.cab", LZX);
+       verify3("test_read_format_cab_3.cab", LZX);
 }