diff options
-rw-r--r-- | libsoup/soup-message-client-io.c | 2 | ||||
-rw-r--r-- | libsoup/soup-uri.c | 21 | ||||
-rw-r--r-- | tests/uri-parsing.c | 8 |
3 files changed, 27 insertions, 4 deletions
diff --git a/libsoup/soup-message-client-io.c b/libsoup/soup-message-client-io.c index 0d3df282..1d96729d 100644 --- a/libsoup/soup-message-client-io.c +++ b/libsoup/soup-message-client-io.c @@ -83,7 +83,7 @@ get_request_headers (SoupMessage *msg, GString *header, const char *name, *value; if (strchr (uri->host, ':')) - uri_host = g_strdup_printf ("[%s]", uri->host); + uri_host = g_strdup_printf ("[%.*s]", (int) strcspn (uri->host, "%"), uri->host); else if (g_hostname_is_non_ascii (uri->host)) uri_host = g_hostname_to_ascii (uri->host); else diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c index 16098f69..6e3d220b 100644 --- a/libsoup/soup-uri.c +++ b/libsoup/soup-uri.c @@ -308,6 +308,8 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string) /* Find host and port. */ if (*uri_string == '[') { + const char *pct; + uri_string++; hostend = strchr (uri_string, ']'); if (!hostend || hostend > path) { @@ -318,13 +320,18 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string) colon = hostend + 1; else colon = NULL; + + pct = memchr (uri_string, '%', hostend - uri_string); + if (!pct || (pct[1] == '2' && pct[2] == '5')) + uri->host = uri_decoded_copy (uri_string, hostend - uri_string, NULL); + else + uri->host = g_strndup (uri_string, hostend - uri_string); } else { colon = memchr (uri_string, ':', path - uri_string); hostend = colon ? colon : path; + uri->host = uri_decoded_copy (uri_string, hostend - uri_string, NULL); } - uri->host = uri_decoded_copy (uri_string, hostend - uri_string, NULL); - if (colon && colon != path - 1) { char *portend; uri->port = strtoul (colon + 1, &portend, 10); @@ -513,8 +520,16 @@ soup_uri_to_string_internal (SoupURI *uri, gboolean just_path_and_query, g_string_append_c (str, '@'); } if (strchr (uri->host, ':')) { + const char *pct; + g_string_append_c (str, '['); - g_string_append (str, uri->host); + pct = strchr (uri->host, '%'); + if (pct) { + g_string_append_printf (str, "%.*s%%25%s", + (int) (pct - uri->host), + uri->host, pct + 1); + } else + g_string_append (str, uri->host); g_string_append_c (str, ']'); } else append_uri_encoded (str, uri->host, ":/"); diff --git a/tests/uri-parsing.c b/tests/uri-parsing.c index d1bba4e1..b4f495b6 100644 --- a/tests/uri-parsing.c +++ b/tests/uri-parsing.c @@ -144,6 +144,14 @@ static struct { { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } }, { "+http://host/path", NULL, { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL } }, + + /* IPv6 scope ID parsing (both correct and incorrect) */ + { "http://[fe80::dead:beef%em1]/", "http://[fe80::dead:beef%25em1]/", + { "http", NULL, NULL, "fe80::dead:beef%em1", 80, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%25em1]/", "http://[fe80::dead:beef%25em1]/", + { "http", NULL, NULL, "fe80::dead:beef%em1", 80, "/", NULL, NULL } }, + { "http://[fe80::dead:beef%10]/", "http://[fe80::dead:beef%2510]/", + { "http", NULL, NULL, "fe80::dead:beef%10", 80, "/", NULL, NULL } } }; static int num_abs_tests = G_N_ELEMENTS(abs_tests); |