diff -up libsoup-2.62.2/libsoup/soup-headers.c.cve-2024-52530 libsoup-2.62.2/libsoup/soup-headers.c --- libsoup-2.62.2/libsoup/soup-headers.c.cve-2024-52530 2018-03-23 14:44:54.000000000 +0100 +++ libsoup-2.62.2/libsoup/soup-headers.c 2024-11-12 10:23:16.693272087 +0100 @@ -50,13 +50,14 @@ soup_headers_parse (const char *str, int * ignorable trailing whitespace. */ + /* No '\0's are allowed */ + if (memchr (str, '\0', len)) + return FALSE; + /* Skip over the Request-Line / Status-Line */ headers_start = memchr (str, '\n', len); if (!headers_start) return FALSE; - /* No '\0's in the Request-Line / Status-Line */ - if (memchr (str, '\0', headers_start - str)) - return FALSE; /* We work on a copy of the headers, which we can write '\0's * into, so that we don't have to individually g_strndup and @@ -68,14 +69,6 @@ soup_headers_parse (const char *str, int headers_copy[copy_len] = '\0'; value_end = headers_copy; - /* There shouldn't be any '\0's in the headers already, but - * this is the web we're talking about. - */ - while ((p = memchr (headers_copy, '\0', copy_len))) { - memmove (p, p + 1, copy_len - (p - headers_copy)); - copy_len--; - } - while (*(value_end + 1)) { name = value_end + 1; name_end = strchr (name, ':'); diff -up libsoup-2.62.2/tests/header-parsing.c.cve-2024-52530 libsoup-2.62.2/tests/header-parsing.c --- libsoup-2.62.2/tests/header-parsing.c.cve-2024-52530 2024-11-12 10:25:26.452447520 +0100 +++ libsoup-2.62.2/tests/header-parsing.c 2024-11-12 10:28:05.738158891 +0100 @@ -358,24 +358,6 @@ static struct RequestTest { } }, - { "NUL in header name", "760832", - "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36, - SOUP_STATUS_OK, - "GET", "/", SOUP_HTTP_1_1, - { { "Host", "example.com" }, - { NULL } - } - }, - - { "NUL in header value", "760832", - "GET / HTTP/1.1\r\nHost: example\x00" "com\r\n", 35, - SOUP_STATUS_OK, - "GET", "/", SOUP_HTTP_1_1, - { { "Host", "examplecom" }, - { NULL } - } - }, - /************************/ /*** INVALID REQUESTS ***/ /************************/ @@ -448,6 +430,21 @@ static struct RequestTest { SOUP_STATUS_EXPECTATION_FAILED, NULL, NULL, -1, { { NULL } } + }, + + // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377 + { "NUL in header name", NULL, + "GET / HTTP/1.1\r\nHost\x00: example.com\r\n", 36, + SOUP_STATUS_BAD_REQUEST, + NULL, NULL, -1, + { { NULL } } + }, + + { "NUL in header value", NULL, + "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28, + SOUP_STATUS_BAD_REQUEST, + NULL, NULL, -1, + { { NULL } } } }; static const int num_reqtests = G_N_ELEMENTS (reqtests); @@ -620,22 +617,6 @@ static struct ResponseTest { { NULL } } }, - { "NUL in header name", "760832", - "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28, - SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK", - { { "Foo", "bar" }, - { NULL } - } - }, - - { "NUL in header value", "760832", - "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28, - SOUP_HTTP_1_1, SOUP_STATUS_OK, "OK", - { { "Foo", "bar" }, - { NULL } - } - }, - /********************************/ /*** VALID CONTINUE RESPONSES ***/ /********************************/ @@ -768,6 +749,19 @@ static struct ResponseTest { { { NULL } } }, + + // https://gitlab.gnome.org/GNOME/libsoup/-/issues/377 + { "NUL in header name", NULL, + "HTTP/1.1 200 OK\r\nF\x00oo: bar\r\n", 28, + -1, 0, NULL, + { { NULL } } + }, + + { "NUL in header value", "760832", + "HTTP/1.1 200 OK\r\nFoo: b\x00" "ar\r\n", 28, + -1, 0, NULL, + { { NULL } } + }, }; static const int num_resptests = G_N_ELEMENTS (resptests);