]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
7zip: propagate skip_stream's actual error code in read_data_skip
authorTim Kientzle <kientzle@acm.org>
Mon, 4 May 2026 03:42:22 +0000 (20:42 -0700)
committerTim Kientzle <kientzle@acm.org>
Tue, 5 May 2026 20:39:27 +0000 (13:39 -0700)
archive_read_format_7zip_read_data_skip used to coerce any negative
skip_stream() return into ARCHIVE_FATAL.  That is wrong in principle:
ARCHIVE_FAILED can legitimately propagate up from setup_decode_folder()
through read_stream() and skip_stream(), and the wrapper should not
upgrade it.

In the current encryption-partially test case this is empirically a
no-op because skip_stream() still returns ARCHIVE_FATAL via a second,
deeper code path through extract_pack_stream().  An inline TODO comment
flags that asymmetry for a follow-up audit.

libarchive/archive_read_support_format_7zip.c

index ea303efb6ce57dcf784960a7c980c8b782a269d4..b922fb7fe5fe3364d6efb78b5c5e5eb27266cbfd 100644 (file)
@@ -1189,8 +1189,19 @@ archive_read_format_7zip_read_data_skip(struct archive_read *a)
         * compressed data much more quickly.
         */
        bytes_skipped = skip_stream(a, (size_t)zip->entry_bytes_remaining);
+       /*
+        * TODO: when archive_read_data() fails on an encrypted entry with
+        * ARCHIVE_FAILED, the implicit skip from the next
+        * archive_read_next_header() lands here.  Empirically, skip_stream()
+        * still returns ARCHIVE_FATAL via extract_pack_stream() on its second
+        * call (after setup_decode_folder() returned ARCHIVE_FAILED on the
+        * first), so the FAILED-from-data / FATAL-from-skip asymmetry persists.
+        * Audit extract_pack_stream() / read_stream() to see whether the second
+        * call should also surface ARCHIVE_FAILED so the caller can move on
+        * to entries in subsequent folders.
+        */
        if (bytes_skipped < 0)
-               return (ARCHIVE_FATAL);
+               return ((int)bytes_skipped);
        zip->entry_bytes_remaining = 0;
 
        /* This entry is finished and done. */