]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
bzip2: Support large in-memory archives 3050/head
authorTobias Stoeckmann <tobias@stoeckmann.org>
Tue, 19 May 2026 15:24:01 +0000 (17:24 +0200)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Tue, 19 May 2026 15:24:01 +0000 (17:24 +0200)
If an archive has more than UINT_MAX (4 GB) bytes available, the bzip2
filter will enter an endless loop.

Apply same logic of gzip filter from commit
256c71ad4eee22a7dac2f13df1e20d85717cbdf6.

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

index 479237c277922ffe47abd6e92de93c3fff35ddfa..dc9d24d87702ad759fcdb058aa4775a36bd98511 100644 (file)
@@ -28,6 +28,9 @@
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
 #include <stdio.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
@@ -232,6 +235,8 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
 
        /* Try to fill the output buffer. */
        for (;;) {
+               ssize_t max_in;
+
                if (!state->valid) {
                        if (bzip2_reader_bid(self->bidder, self->upstream) == 0) {
                                state->eof = 1;
@@ -286,6 +291,12 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
                        return (ARCHIVE_FATAL);
                }
                state->stream.next_in = (char *)(uintptr_t)read_buf;
+               if (UINT_MAX >= SSIZE_MAX)
+                       max_in = SSIZE_MAX;
+               else
+                       max_in = UINT_MAX;
+               if (ret > max_in)
+                       ret = max_in;
                state->stream.avail_in = (uint32_t)ret;
                /* There is no more data, return whatever we have. */
                if (ret == 0) {