]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
test_sparse_basic: do not assume that holes can be read in one go
authorJonas Witschel <diabonas@archlinux.org>
Sun, 21 Nov 2021 09:07:52 +0000 (10:07 +0100)
committerJonas Witschel <diabonas@archlinux.org>
Sun, 21 Nov 2021 09:31:23 +0000 (10:31 +0100)
verify_sparse_file() assumes that every hole will be fully contained in only
one archive_read_data_block(). This is a reasonable assumption if the file is
indeed sparsely encoded in the archive because archive_read_data_block() will
just skip the hole and return the offset of the next data block.

However, if the file is not sparsely encoded in the archive, a hole consists of
a lot of zeroes that need to be read byte by byte. In this case, the archive
contains no information on where this block of zeroes ends and where actual
data begins. Therefore it can happen that a single archive_read_data_block()
contains both zeroes from a hole and actual data.

If this happens, assert(sparse->type == HOLE) fails. This assertion is
reasonable for sparsely encoded files because archive_read_data_block() will
never only read part of a hole (since it does not really "read" a hole at all,
it just returns a higher offset accounting for the size of the hole).

However, we want to start testing files with verify_sparse_file() that are
explicitly not sparsely encoded. In this case, the assertion does not
necessarily hold any more. Therefore we need to account for the case where the
overlapping block consists of data. To make sure the file contents are
correctly encoded in the archive, we need to test the contents of the data
block, like it is already done for blocks completely contained in the data read
by archive_read_data_block().

Note that this modification does not change the way sparsely encoded files are
verified, it just relaxes an edge case that cannot happen with sparsely encoded
files to make it possible to test any kind of file, whether sparsely encoded or
not.

libarchive/test/test_sparse_basic.c

index 43e87df5245183a4119aa600a87604f9283ccdc0..5b6f848242b6026c775b0baafead3ad153e37369 100644 (file)
@@ -364,9 +364,10 @@ verify_sparse_file(struct archive *a, const char *path,
 #if DEBUG
                        fprintf(stderr, "    overlapping hole expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size);
 #endif
-                       /* Must be a hole, overlap must be filled with '\0' */
-                       if (assert(sparse->type == HOLE)) {
+                       if (sparse->type == HOLE) {
                                assertMemoryFilledWith(start, end - start, '\0');
+                       } else if (assert(sparse->type == DATA)) {
+                               assertMemoryFilledWith(start, end - start, ' ');
                        }
                        start = end;
                        expected_offset += sparse->size;
@@ -410,9 +411,10 @@ verify_sparse_file(struct archive *a, const char *path,
 #if DEBUG
                        fprintf(stderr, "    trailing overlap expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size);
 #endif
-                       /* Must be a hole, overlap must be filled with '\0' */
-                       if (assert(sparse->type == HOLE)) {
+                       if (sparse->type == HOLE) {
                                assertMemoryFilledWith(start, end - start, '\0');
+                       } else if (assert(sparse->type == DATA)) {
+                               assertMemoryFilledWith(start, end - start, ' ');
                        }
                }
                last_offset = offset + bytes_read;