File libsoup-CVE-2026-1761.patch of Package libsoup

From cfa9d90d1a5c274233554a264c56551c13d6a6f0 Mon Sep 17 00:00:00 2001
From: Carlos Garcia Campos <cgarcia@igalia.com>
Date: Mon, 19 Jan 2026 15:14:58 +0100
Subject: [PATCH] multipart: check length of bytes read
 soup_filter_input_stream_read_until()

We do make sure the read length is smaller than the buffer length when
the boundary is not found, but we should do the same when the boundary
is found.

Spotted in #YWH-PGM9867-149
Closes #493
---
 libsoup/soup-filter-input-stream.c |  3 +-
 tests/multipart-test.c             | 46 ++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/libsoup/soup-filter-input-stream.c b/libsoup/soup-filter-input-stream.c
index b1e616c7..22541aa0 100644
--- a/libsoup/soup-filter-input-stream.c
+++ b/libsoup/soup-filter-input-stream.c
@@ -337,6 +337,7 @@ soup_filter_input_stream_read_until (SoupFilterInputStream  *fstream,
 	if (eof && !*got_boundary)
 		read_length = MIN (priv->buf->len, length);
 	else
-		read_length = p - buf;
+                read_length = MIN ((gsize)(p - buf), length);
+
 	return read_from_buf (fstream, buffer, read_length);
 }
diff --git a/tests/multipart-test.c b/tests/multipart-test.c
index a39d8aab..7f53898f 100644
--- a/tests/multipart-test.c
+++ b/tests/multipart-test.c
@@ -548,6 +548,51 @@ test_multipart_bounds_bad_2 (void)
 	g_bytes_unref (bytes);
 }
 
+static void
+test_multipart_bounds_bad_3 (void)
+{
+        SoupMessage *msg;
+        SoupMessageHeaders *headers;
+        GInputStream *in;
+        SoupMultipartInputStream *multipart;
+        GError *error = NULL;
+        const char raw_data[] = "\0$--A\r\nContent-Disposition: form-data; name=\"f\"\r\n\r\nXXXXXXXXX\r\n--A--\r\n";
+
+        msg = soup_message_new(SOUP_METHOD_POST, "http://foo/upload");
+        headers = soup_message_get_response_headers (msg);
+        soup_message_headers_replace (headers, "Content-Type", "multipart/form-data; boundary=\"A\"");
+
+        in = g_memory_input_stream_new_from_data (raw_data + 2, sizeof(raw_data) - 2, NULL);
+        multipart = soup_multipart_input_stream_new (msg, in);
+        g_object_unref (in);
+
+        while (TRUE) {
+                in = soup_multipart_input_stream_next_part (multipart, NULL, &error);
+                g_assert_no_error (error);
+                if (!in) {
+                        g_clear_error (&error);
+                        break;
+                }
+
+                char buffer[10];
+                while (TRUE) {
+                        gssize bytes_read;
+
+                        bytes_read = g_input_stream_read (in, buffer, sizeof(buffer), NULL, &error);
+                        g_assert_no_error (error);
+                        if (bytes_read <= 0) {
+                                g_clear_error (&error);
+                                break;
+                        }
+                }
+
+                g_object_unref (in);
+        }
+
+        g_object_unref (multipart);
+        g_object_unref (msg);
+}
+
 static void
 test_multipart_too_large (void)
 {
@@ -617,6 +662,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/multipart/bounds-good", test_multipart_bounds_good);
 	g_test_add_func ("/multipart/bounds-bad", test_multipart_bounds_bad);
 	g_test_add_func ("/multipart/bounds-bad-2", test_multipart_bounds_bad_2);
+        g_test_add_func ("/multipart/bounds-bad-3", test_multipart_bounds_bad_3);
 	g_test_add_func ("/multipart/too-large", test_multipart_too_large);
 
 	ret = g_test_run ();
-- 
2.52.0

openSUSE Build Service is sponsored by