]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
archive_read: Handle sparse holes at end of file 2665/head
authorTobias Stoeckmann <tobias@stoeckmann.org>
Tue, 3 Jun 2025 20:00:13 +0000 (22:00 +0200)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Tue, 3 Jun 2025 20:01:15 +0000 (22:01 +0200)
If a sparse hole is located at the end of an entry, then the tar
parser returns ARCHIVE_EOF while updating the offset where 0 bytes of
data will follow.

If archive_read_data encounters such an ARCHIVE_EOF return value, it
has to recheck if the offsets (data offset and output offset) still
match. If they do not match, it has to keep filling 0 bytes.

This changes assumes that it's okay to call archive_read_data_block
again after an EOF. As far as I understood the parsers so far, this
should be okay, since it's always ARCHIVE_EOF afterwards.

Fixes https://github.com/libarchive/libarchive/issues/1194

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
libarchive/archive_read.c

index 50db87017706c565adb2813250ca7dcd5ff5c3e5..ea58c6ed0123c479ab2767799f30fd9a0ac60f30 100644 (file)
@@ -834,7 +834,9 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
                        r = archive_read_data_block(a, &read_buf,
                            &a->read_data_remaining, &a->read_data_offset);
                        a->read_data_block = read_buf;
-                       if (r == ARCHIVE_EOF)
+                       if (r == ARCHIVE_EOF &&
+                           a->read_data_offset == a->read_data_output_offset &&
+                           a->read_data_remaining == 0)
                                return (bytes_read);
                        /*
                         * Error codes are all negative, so the status