Merge branch 'ossfuzz-23816-uri-parsing' into 'master'

guri: Fix URI scope parsing

See merge request GNOME/glib!1669
This commit is contained in:
Philip Withnall 2020-10-01 10:14:45 +00:00
commit 5464c4d292
3 changed files with 208 additions and 131 deletions

View File

@ -40,10 +40,10 @@ static ParseTest uri_tests[] = {
{ "ftp://[fec0::abcd]/start", "ftp", "fec0::abcd", 8080, -1 },
{ "ftp://[fec0::abcd]:999/start", "ftp", "fec0::abcd", 999, -1 },
{ "ftp://joe%x-@ftp.gnome.org:2020/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
{ "http://[fec0::abcd%em1]/start", "http", "fec0::abcd%em1", 8080, -1 },
{ "http://[fec0::abcd%em1]/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
{ "http://[fec0::abcd%25em1]/start", "http", "fec0::abcd%em1", 8080, -1 },
{ "http://[fec0::abcd%10]/start", "http", "fec0::abcd%10", 8080, -1 },
{ "http://[fec0::abcd%25em%31]/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
{ "http://[fec0::abcd%10]/start", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
{ "http://[fec0::abcd%25em%31]/start", "http", "fec0::abcd%em1", 8080, -1 },
{ "ftp://ftp.gnome.org/start?foo=bar@baz", "ftp", "ftp.gnome.org", 8080, -1 }
};
@ -80,6 +80,7 @@ static ParseTest host_tests[] =
{ "[2001:db8::1]", NULL, "2001:db8::1", 1234, -1 },
{ "[2001:db8::1]:888", NULL, "2001:db8::1", 888, -1 },
{ "[2001:db8::1%em1]", NULL, "2001:db8::1%em1", 1234, -1 },
{ "[2001:db8::1%25em1]", NULL, "2001:db8::1%25em1", 1234, -1 },
{ "[hostname", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
{ "[hostnam]e", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
{ "hostname:", NULL, NULL, 0, G_IO_ERROR_INVALID_ARGUMENT },
@ -337,10 +338,9 @@ test_uri_scope_id (void)
SCOPE_ID_TEST_PORT);
addr = g_network_address_parse_uri (uri, 0, &error);
g_free (uri);
g_assert_no_error (error);
test_scope_id (addr);
g_object_unref (addr);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_assert_null (addr);
g_clear_error (&error);
uri = g_strdup_printf ("http://[%s%%25%s]:%d/foo",
SCOPE_ID_TEST_ADDR,

View File

@ -442,6 +442,100 @@ _uri_encoder (GString *out,
}
}
/* Parse the IP-literal construction from RFC 6874 (which extends RFC 3986 to
* support IPv6 zone identifiers.
*
* Currently, IP versions beyond 6 (i.e. the IPvFuture rule) are unsupported.
* Theres no point supporting them until (a) they exist and (b) the rest of the
* stack (notably, sockets) supports them.
*
* Rules:
*
* IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]"
*
* ZoneID = 1*( unreserved / pct-encoded )
*
* IPv6addrz = IPv6address "%25" ZoneID
*
* If %G_URI_FLAGS_PARSE_RELAXED is specified, this function also accepts:
*
* IPv6addrz = IPv6address "%" ZoneID
*/
static gboolean
parse_ip_literal (const gchar *start,
gsize length,
GUriFlags flags,
gchar **out,
GError **error)
{
gchar *pct, *zone_id = NULL;
gchar *addr = NULL;
gsize addr_length = 0;
gsize zone_id_length = 0;
gchar *decoded_zone_id = NULL;
if (start[length - 1] != ']')
goto bad_ipv6_literal;
/* Drop the square brackets */
addr = g_strndup (start + 1, length - 2);
addr_length = length - 2;
/* If there's an IPv6 scope ID, split out the zone. */
pct = strchr (addr, '%');
if (pct != NULL)
{
*pct = '\0';
if (addr_length - (pct - addr) >= 4 &&
*(pct + 1) == '2' && *(pct + 2) == '5')
{
zone_id = pct + 3;
zone_id_length = addr_length - (zone_id - addr);
}
else if (flags & G_URI_FLAGS_PARSE_RELAXED &&
addr_length - (pct - addr) >= 2)
{
zone_id = pct + 1;
zone_id_length = addr_length - (zone_id - addr);
}
else
goto bad_ipv6_literal;
g_assert (zone_id_length >= 1);
}
/* addr must be an IPv6 address */
if (!g_hostname_is_ip_address (addr) || !strchr (addr, ':'))
goto bad_ipv6_literal;
/* Zone ID must be valid. It can contain %-encoded characters. */
if (zone_id != NULL &&
!uri_decode (&decoded_zone_id, NULL, zone_id, zone_id_length, FALSE,
flags, G_URI_ERROR_BAD_HOST, NULL))
goto bad_ipv6_literal;
/* Success */
if (out != NULL && decoded_zone_id != NULL)
*out = g_strconcat (addr, "%", decoded_zone_id, NULL);
else if (out != NULL)
*out = g_steal_pointer (&addr);
g_free (addr);
g_free (decoded_zone_id);
return TRUE;
bad_ipv6_literal:
g_free (addr);
g_free (decoded_zone_id);
g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
_("Invalid IPv6 address %.*s in URI"),
(gint)length, start);
return FALSE;
}
static gboolean
parse_host (const gchar *start,
gsize length,
@ -449,43 +543,13 @@ parse_host (const gchar *start,
gchar **out,
GError **error)
{
gchar *decoded, *host, *pct;
gchar *decoded = NULL, *host;
gchar *addr = NULL;
if (*start == '[')
{
if (start[length - 1] != ']')
{
bad_ipv6_literal:
g_free (addr);
g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
_("Invalid IPv6 address %.*s in URI"),
(gint)length, start);
return FALSE;
}
addr = g_strndup (start + 1, length - 2);
/* If there's an IPv6 scope id, ignore it for the moment. */
pct = strchr (addr, '%');
if (pct)
*pct = '\0';
/* addr must be an IPv6 address */
if (!g_hostname_is_ip_address (addr) || !strchr (addr, ':'))
goto bad_ipv6_literal;
if (pct)
{
*pct = '%';
if (strchr (pct + 1, '%'))
goto bad_ipv6_literal;
/* If the '%' is encoded as '%25' (which it should be), decode it */
if (pct[1] == '2' && pct[2] == '5' && pct[3])
memmove (pct + 1, pct + 3, strlen (pct + 3) + 1);
}
host = addr;
if (!parse_ip_literal (start, length, flags, &host, error))
return FALSE;
goto ok;
}
@ -505,7 +569,7 @@ parse_host (const gchar *start,
if (!uri_normalize (&decoded, start, length, flags,
G_URI_ERROR_BAD_HOST, error))
return FALSE;
host = decoded;
host = g_steal_pointer (&decoded);
goto ok;
}
@ -527,18 +591,16 @@ parse_host (const gchar *start,
}
if (g_hostname_is_non_ascii (decoded))
{
host = g_hostname_to_ascii (decoded);
g_free (decoded);
}
host = g_hostname_to_ascii (decoded);
else
host = decoded;
host = g_steal_pointer (&decoded);
ok:
if (out)
*out = host;
else
g_free (host);
*out = g_steal_pointer (&host);
g_free (host);
g_free (decoded);
return TRUE;
}

View File

@ -518,232 +518,247 @@ typedef struct {
} UriParts;
typedef struct {
/* Inputs */
const gchar *orig;
GUriFlags flags;
const UriParts parts;
/* Outputs */
gboolean expected_success;
GUriError expected_error_code; /* unused if @expected_success is true */
const UriParts expected_parts; /* unused if @expected_success is false */
} UriAbsoluteTest;
static const UriAbsoluteTest absolute_tests[] = {
{ "foo:", G_URI_FLAGS_NONE,
{ "foo:", G_URI_FLAGS_NONE, TRUE, 0,
{ "foo", NULL, NULL, -1, "", NULL, NULL }
},
{ "file:/dev/null", G_URI_FLAGS_NONE,
{ "file:/dev/null", G_URI_FLAGS_NONE, TRUE, 0,
{ "file", NULL, NULL, -1, "/dev/null", NULL, NULL }
},
{ "file:///dev/null", G_URI_FLAGS_NONE,
{ "file:///dev/null", G_URI_FLAGS_NONE, TRUE, 0,
{ "file", NULL, "", -1, "/dev/null", NULL, NULL }
},
{ "ftp://user@host/path", G_URI_FLAGS_NONE,
{ "ftp://user@host/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "ftp", "user", "host", -1, "/path", NULL, NULL }
},
{ "ftp://user@host:9999/path", G_URI_FLAGS_NONE,
{ "ftp://user@host:9999/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "ftp", "user", "host", 9999, "/path", NULL, NULL }
},
{ "ftp://user:password@host/path", G_URI_FLAGS_NONE,
{ "ftp://user:password@host/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "ftp", "user:password", "host", -1, "/path", NULL, NULL }
},
{ "ftp://user:password@host:9999/path", G_URI_FLAGS_NONE,
{ "ftp://user:password@host:9999/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "ftp", "user:password", "host", 9999, "/path", NULL, NULL }
},
{ "ftp://user:password@host", G_URI_FLAGS_NONE,
{ "ftp://user:password@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "ftp", "user:password", "host", -1, "", NULL, NULL }
},
{ "http://us%65r@host", G_URI_FLAGS_NONE,
{ "http://us%65r@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", "user", "host", -1, "", NULL, NULL }
},
{ "http://us%40r@host", G_URI_FLAGS_NONE,
{ "http://us%40r@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", "us@r", "host", -1, "", NULL, NULL }
},
{ "http://us%3ar@host", G_URI_FLAGS_NONE,
{ "http://us%3ar@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", "us:r", "host", -1, "", NULL, NULL }
},
{ "http://us%2fr@host", G_URI_FLAGS_NONE,
{ "http://us%2fr@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", "us/r", "host", -1, "", NULL, NULL }
},
{ "http://us%3fr@host", G_URI_FLAGS_NONE,
{ "http://us%3fr@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", "us?r", "host", -1, "", NULL, NULL }
},
{ "http://host?query", G_URI_FLAGS_NONE,
{ "http://host?query", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "host", -1, "", "query", NULL }
},
{ "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue&param=value", G_URI_FLAGS_NONE,
{ "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue&param=value", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "host", -1, "/path", "query=http://host/path?childparam=childvalue&param=value", NULL }
},
{ "http://control-chars/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", G_URI_FLAGS_NONE,
{ "http://control-chars/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "control-chars", -1, "/\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F", NULL, NULL }
},
{ "http://space/%20", G_URI_FLAGS_NONE,
{ "http://space/%20", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "space", -1, "/ ", NULL, NULL }
},
{ "http://delims/%3C%3E%23%25%22", G_URI_FLAGS_NONE,
{ "http://delims/%3C%3E%23%25%22", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "delims", -1, "/<>#%\"", NULL, NULL }
},
{ "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60", G_URI_FLAGS_NONE,
{ "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "unwise-chars", -1, "/{}|\\^[]`", NULL, NULL }
},
/* From RFC 2732 */
{ "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html", G_URI_FLAGS_NONE,
{ "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80, "/index.html", NULL, NULL }
},
{ "http://[1080:0:0:0:8:800:200C:417A]/index.html", G_URI_FLAGS_NONE,
{ "http://[1080:0:0:0:8:800:200C:417A]/index.html", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "1080:0:0:0:8:800:200C:417A", -1, "/index.html", NULL, NULL }
},
{ "http://[3ffe:2a00:100:7031::1]", G_URI_FLAGS_NONE,
{ "http://[3ffe:2a00:100:7031::1]", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "3ffe:2a00:100:7031::1", -1, "", NULL, NULL }
},
{ "http://[1080::8:800:200C:417A]/foo", G_URI_FLAGS_NONE,
{ "http://[1080::8:800:200C:417A]/foo", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "1080::8:800:200C:417A", -1, "/foo", NULL, NULL }
},
{ "http://[::192.9.5.5]/ipng", G_URI_FLAGS_NONE,
{ "http://[::192.9.5.5]/ipng", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "::192.9.5.5", -1, "/ipng", NULL, NULL }
},
{ "http://[::FFFF:129.144.52.38]:80/index.html", G_URI_FLAGS_NONE,
{ "http://[::FFFF:129.144.52.38]:80/index.html", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "::FFFF:129.144.52.38", 80, "/index.html", NULL, NULL }
},
{ "http://[2010:836B:4179::836B:4179]", G_URI_FLAGS_NONE,
{ "http://[2010:836B:4179::836B:4179]", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "2010:836B:4179::836B:4179", -1, "", NULL, NULL }
},
/* some problematic URIs that are handled differently in libsoup */
{ "http://host/path with spaces", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path with spaces", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path with spaces", NULL, NULL }
},
{ " http://host/path", G_URI_FLAGS_PARSE_RELAXED,
{ " http://host/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path", NULL, NULL }
},
{ "http://host/path ", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path", NULL, NULL }
},
{ "http://host ", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "", NULL, NULL }
},
{ "http://host:999 ", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host:999 ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", 999, "", NULL, NULL }
},
{ "http://host/pa\nth", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/pa\nth", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path", NULL, NULL }
},
{ "http:\r\n//host/path", G_URI_FLAGS_PARSE_RELAXED,
{ "http:\r\n//host/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path", NULL, NULL }
},
{ "http://\thost/path", G_URI_FLAGS_PARSE_RELAXED,
{ "http://\thost/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path", NULL, NULL }
},
/* Bug 594405; 0-length is different from not-present */
{ "http://host/path?", G_URI_FLAGS_NONE,
{ "http://host/path?", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "host", -1, "/path", "", NULL }
},
{ "http://host/path#", G_URI_FLAGS_NONE,
{ "http://host/path#", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "host", -1, "/path", NULL, "" },
},
/* Bug 590524; ignore bad %-encoding */
{ "http://host/path%", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path%", NULL, NULL }
},
{ "http://h%ost/path", G_URI_FLAGS_PARSE_RELAXED,
{ "http://h%ost/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "h%ost", -1, "/path", NULL, NULL }
},
{ "http://host/path%%", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path%%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path%%", NULL, NULL }
},
{ "http://host/path%%%", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path%%%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path%%%", NULL, NULL }
},
{ "http://host/path%/x/", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path%/x/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path%/x/", NULL, NULL }
},
{ "http://host/path%0x/", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path%0x/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path%0x/", NULL, NULL }
},
{ "http://host/path%ax", G_URI_FLAGS_PARSE_RELAXED,
{ "http://host/path%ax", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "host", -1, "/path%ax", NULL, NULL }
},
/* GUri doesn't %-encode non-ASCII characters */
{ "http://host/p\xc3\xa4th/", G_URI_FLAGS_NONE,
{ "http://host/p\xc3\xa4th/", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "host", -1, "/p\xc3\xa4th/", NULL, NULL }
},
{ "HTTP:////////////////", G_URI_FLAGS_NONE,
{ "HTTP:////////////////", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "", -1, "//////////////", NULL, NULL }
},
{ "http://@host", G_URI_FLAGS_NONE,
{ "http://@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", "", "host", -1, "", NULL, NULL }
},
{ "http://:@host", G_URI_FLAGS_NONE,
{ "http://:@host", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", ":", "host", -1, "", NULL, NULL }
},
{ "scheme://foo%3Abar._webdav._tcp.local", G_URI_FLAGS_NONE,
{ "scheme://foo%3Abar._webdav._tcp.local", G_URI_FLAGS_NONE, TRUE, 0,
{ "scheme", NULL, "foo:bar._webdav._tcp.local", -1, "", NULL, NULL}
},
/* IPv6 scope ID parsing (both correct and incorrect) */
{ "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_NONE,
{ "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL }
},
{ "http://[fe80::dead:beef%25em1]/", G_URI_FLAGS_NONE,
{ "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL }
},
{ "http://[fe80::dead:beef%10]/", G_URI_FLAGS_NONE,
{ "http", NULL, "fe80::dead:beef%10", -1, "/", NULL, NULL }
},
/* ".." past top */
{ "http://example.com/..", G_URI_FLAGS_NONE,
{ "http://example.com/..", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "example.com", -1, "/..", NULL, NULL }
},
/* scheme parsing */
{ "foo0://host/path", G_URI_FLAGS_NONE,
{ "foo0://host/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "foo0", NULL, "host", -1, "/path", NULL, NULL } },
{ "f0.o://host/path", G_URI_FLAGS_NONE,
{ "f0.o://host/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "f0.o", NULL, "host", -1, "/path", NULL, NULL } },
{ "http++://host/path", G_URI_FLAGS_NONE,
{ "http++://host/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "http++", NULL, "host", -1, "/path", NULL, NULL } },
{ "http-ish://host/path", G_URI_FLAGS_NONE,
{ "http-ish://host/path", G_URI_FLAGS_NONE, TRUE, 0,
{ "http-ish", NULL, "host", -1, "/path", NULL, NULL } },
/* IPv6 scope ID parsing (both correct and incorrect) */
{ "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_NONE,
{ "http://[fe80::dead:beef%]/", G_URI_FLAGS_PARSE_RELAXED, FALSE, G_URI_ERROR_BAD_HOST,
{ NULL, NULL, NULL, -1, NULL, NULL, NULL } },
{ "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%25em1]/", G_URI_FLAGS_NONE,
{ "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
{ NULL, NULL, NULL, -1, NULL, NULL, NULL } },
{ "http://[fe80::dead:beef%25em1]/", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%10]/", G_URI_FLAGS_NONE,
{ "http://[fe80::dead:beef%25em1%20]/", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "fe80::dead:beef%em1 ", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%25em%31]/", G_URI_FLAGS_NONE, TRUE, 0,
{ "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%10]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "fe80::dead:beef%10", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%25]/", G_URI_FLAGS_NONE,
{ "http://[fe80::dead:beef%10]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
{ NULL, NULL, NULL, -1, NULL, NULL, NULL } },
{ "http://[fe80::dead:beef%25]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
{ "http", NULL, "fe80::dead:beef%25", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%25]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
{ NULL, NULL, NULL, -1, NULL, NULL, NULL } },
{ "http://[192.168.0.1%25em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
{ NULL, NULL, NULL, -1, NULL, NULL, NULL } },
};
static int num_absolute_tests = G_N_ELEMENTS (absolute_tests);
static void
test_uri_parsing_absolute (void)
{
int i;
gsize i;
for (i = 0; i < num_absolute_tests; i++)
for (i = 0; i < G_N_ELEMENTS (absolute_tests); i++)
{
const UriAbsoluteTest *test = &absolute_tests[i];
GError *error = NULL;
GUri *uri;
g_test_message ("Test %d: %s", i, test->orig);
g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, test->orig);
uri = g_uri_parse (test->orig, test->flags, &error);
g_assert_no_error (error);
if (test->expected_success)
{
g_assert_no_error (error);
g_assert_cmpstr (g_uri_get_scheme (uri), ==, test->parts.scheme);
g_assert_cmpstr (g_uri_get_userinfo (uri), ==, test->parts.userinfo);
g_assert_cmpstr (g_uri_get_host (uri), ==, test->parts.host);
g_assert_cmpint (g_uri_get_port (uri), ==, test->parts.port);
g_assert_cmpstr (g_uri_get_path (uri), ==, test->parts.path);
g_assert_cmpstr (g_uri_get_query (uri), ==, test->parts.query);
g_assert_cmpstr (g_uri_get_fragment (uri), ==, test->parts.fragment);
g_assert_cmpstr (g_uri_get_scheme (uri), ==, test->expected_parts.scheme);
g_assert_cmpstr (g_uri_get_userinfo (uri), ==, test->expected_parts.userinfo);
g_assert_cmpstr (g_uri_get_host (uri), ==, test->expected_parts.host);
g_assert_cmpint (g_uri_get_port (uri), ==, test->expected_parts.port);
g_assert_cmpstr (g_uri_get_path (uri), ==, test->expected_parts.path);
g_assert_cmpstr (g_uri_get_query (uri), ==, test->expected_parts.query);
g_assert_cmpstr (g_uri_get_fragment (uri), ==, test->expected_parts.fragment);
}
else
{
g_assert_error (error, G_URI_ERROR, test->expected_error_code);
g_assert_null (uri);
}
g_uri_unref (uri);
g_clear_pointer (&uri, g_uri_unref);
g_clear_error (&error);
}
}