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