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);
 
openSUSE Build Service is sponsored by