File libsoup-CVE-2026-1467.patch of Package libsoup.42977
Index: libsoup-2.68.4/libsoup/soup-uri.c
===================================================================
--- libsoup-2.68.4.orig/libsoup/soup-uri.c
+++ libsoup-2.68.4/libsoup/soup-uri.c
@@ -1354,6 +1354,68 @@ soup_uri_is_http (SoupURI *uri, char **a
return FALSE;
}
+static gboolean
+is_valid_character_for_host (char c)
+{
+ static const char forbidden_chars[] = { '\t', '\n', '\r', ' ', '#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|' };
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (forbidden_chars); ++i) {
+ if (c == forbidden_chars[i])
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+is_host_valid (const char* host)
+{
+ int i;
+ gboolean is_valid;
+ char *ascii_host = NULL;
+
+ if (!host || !host[0])
+ return FALSE;
+
+ if (g_hostname_is_non_ascii (host)) {
+
+
+ ascii_host = g_hostname_to_ascii (host);
+ if (!ascii_host)
+ return FALSE;
+
+ host = ascii_host;
+ }
+
+ if ((g_ascii_isdigit (host[0]) || strchr (host, ':')) && g_hostname_is_ip_address (host)) {
+ g_free (ascii_host);
+ return TRUE;
+ }
+
+ is_valid = TRUE;
+ for (i = 0; host[i] && is_valid; i++)
+ is_valid = is_valid_character_for_host (host[i]);
+
+ g_free (ascii_host);
+
+ return is_valid;
+}
+
+gboolean
+soup_uri_is_valid (SoupURI *uri)
+{
+ if (!uri)
+ return FALSE;
+
+ if (!is_host_valid (soup_uri_get_host (uri)))
+ return FALSE;
+
+ /* FIXME: validate other URI components? */
+
+ return TRUE;
+}
+
gboolean
soup_uri_is_https (SoupURI *uri, char **aliases)
{
Index: libsoup-2.68.4/libsoup/soup-uri.h
===================================================================
--- libsoup-2.68.4.orig/libsoup/soup-uri.h
+++ libsoup-2.68.4/libsoup/soup-uri.h
@@ -134,6 +134,9 @@ SOUP_AVAILABLE_IN_2_28
gboolean soup_uri_host_equal (gconstpointer v1,
gconstpointer v2);
+SOUP_AVAILABLE_IN_2_68
+gboolean soup_uri_is_valid (SoupURI *uri);
+
#define SOUP_URI_IS_VALID(uri) ((uri) && (uri)->scheme && (uri)->path)
#define SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host && (uri)->path)
Index: libsoup-2.68.4/libsoup/soup-auth.c
===================================================================
--- libsoup-2.68.4.orig/libsoup/soup-auth.c
+++ libsoup-2.68.4/libsoup/soup-auth.c
@@ -535,7 +535,7 @@ GSList *
soup_auth_get_protection_space (SoupAuth *auth, SoupURI *source_uri)
{
g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL);
- g_return_val_if_fail (source_uri != NULL, NULL);
+ g_return_val_if_fail (soup_uri_is_valid (source_uri), NULL);
return SOUP_AUTH_GET_CLASS (auth)->get_protection_space (auth, source_uri);
}
Index: libsoup-2.68.4/libsoup/soup-message.c
===================================================================
--- libsoup-2.68.4.orig/libsoup/soup-message.c
+++ libsoup-2.68.4/libsoup/soup-message.c
@@ -1001,7 +1001,7 @@ soup_message_new (const char *method, co
uri = soup_uri_new (uri_string);
if (!uri)
return NULL;
- if (!uri->host) {
+ if (!soup_uri_is_valid (uri)) {
soup_uri_free (uri);
return NULL;
}
@@ -1023,6 +1023,8 @@ soup_message_new (const char *method, co
SoupMessage *
soup_message_new_from_uri (const char *method, SoupURI *uri)
{
+ g_return_val_if_fail (soup_uri_is_valid (uri), NULL);
+
return g_object_new (SOUP_TYPE_MESSAGE,
SOUP_MESSAGE_METHOD, method,
SOUP_MESSAGE_URI, uri,
@@ -1632,6 +1634,7 @@ soup_message_set_uri (SoupMessage *msg,
{
SoupMessagePrivate *priv;
+ g_return_if_fail (soup_uri_is_valid (uri));
g_return_if_fail (SOUP_IS_MESSAGE (msg));
priv = soup_message_get_instance_private (msg);