Merge branch 'guri-gio' into 'master'

Replace _g_uri_parse_authority() with GUri

Closes #2156

See merge request GNOME/glib!1567
This commit is contained in:
Philip Withnall 2020-08-05 16:06:02 +00:00
commit df8dc7fc38
10 changed files with 108 additions and 402 deletions

View File

@ -518,292 +518,6 @@ g_network_address_parse (const gchar *host_and_port,
return connectable;
}
/* Allowed characters outside alphanumeric for unreserved. */
#define G_URI_OTHER_UNRESERVED "-._~"
/* This or something equivalent will eventually go into glib/guri.h */
gboolean
_g_uri_parse_authority (const char *uri,
char **host,
guint16 *port,
char **userinfo,
GError **error)
{
char *ascii_uri, *tmp_str;
const char *start, *p, *at, *delim;
char c;
g_return_val_if_fail (uri != NULL, FALSE);
if (host)
*host = NULL;
if (port)
*port = 0;
if (userinfo)
*userinfo = NULL;
/* Catch broken URIs early by trying to convert to ASCII. */
ascii_uri = g_hostname_to_ascii (uri);
if (!ascii_uri)
goto error;
/* From RFC 3986 Decodes:
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
* hier-part = "//" authority path-abempty
* path-abempty = *( "/" segment )
* authority = [ userinfo "@" ] host [ ":" port ]
*/
/* Check we have a valid scheme */
tmp_str = g_uri_parse_scheme (ascii_uri);
if (tmp_str == NULL)
goto error;
g_free (tmp_str);
/* Decode hier-part:
* hier-part = "//" authority path-abempty
*/
p = ascii_uri;
start = strstr (p, "//");
if (start == NULL)
goto error;
start += 2;
/* check if the @ sign is part of the authority before attempting to
* decode the userinfo */
delim = strpbrk (start, "/?#[]");
at = strchr (start, '@');
if (at && delim && at > delim)
at = NULL;
if (at != NULL)
{
/* Decode userinfo:
* userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* pct-encoded = "%" HEXDIG HEXDIG
*/
p = start;
while (1)
{
c = *p++;
if (c == '@')
break;
/* pct-encoded */
if (c == '%')
{
if (!(g_ascii_isxdigit (p[0]) ||
g_ascii_isxdigit (p[1])))
goto error;
p++;
continue;
}
/* unreserved / sub-delims / : */
if (!(g_ascii_isalnum (c) ||
strchr (G_URI_OTHER_UNRESERVED, c) ||
strchr (G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, c) ||
c == ':'))
goto error;
}
if (userinfo)
*userinfo = g_strndup (start, p - start - 1);
start = p;
}
else
{
p = start;
}
/* decode host:
* host = IP-literal / IPv4address / reg-name
* reg-name = *( unreserved / pct-encoded / sub-delims )
*/
/* If IPv6 or IPvFuture */
if (*p == '[')
{
gboolean has_scope_id = FALSE, has_bad_scope_id = FALSE;
start++;
p++;
while (1)
{
c = *p++;
if (c == ']')
break;
if (c == '%' && !has_scope_id)
{
has_scope_id = TRUE;
if (p[0] != '2' || p[1] != '5')
has_bad_scope_id = TRUE;
continue;
}
/* unreserved / sub-delims */
if (!(g_ascii_isalnum (c) ||
strchr (G_URI_OTHER_UNRESERVED, c) ||
strchr (G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, c) ||
c == ':' ||
c == '.'))
goto error;
}
if (host)
{
if (has_bad_scope_id)
*host = g_strndup (start, p - start - 1);
else
*host = g_uri_unescape_segment (start, p - 1, NULL);
}
c = *p++;
}
else
{
while (1)
{
c = *p++;
if (c == ':' ||
c == '/' ||
c == '?' ||
c == '#' ||
c == '\0')
break;
/* pct-encoded */
if (c == '%')
{
if (!(g_ascii_isxdigit (p[0]) ||
g_ascii_isxdigit (p[1])))
goto error;
p++;
continue;
}
/* unreserved / sub-delims */
if (!(g_ascii_isalnum (c) ||
strchr (G_URI_OTHER_UNRESERVED, c) ||
strchr (G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, c)))
goto error;
}
if (host)
*host = g_uri_unescape_segment (start, p - 1, NULL);
}
if (c == ':')
{
/* Decode port:
* port = *DIGIT
*/
guint tmp = 0;
while (1)
{
c = *p++;
if (c == '/' ||
c == '?' ||
c == '#' ||
c == '\0')
break;
if (!g_ascii_isdigit (c))
goto error;
tmp = (tmp * 10) + (c - '0');
if (tmp > 65535)
goto error;
}
if (port)
*port = (guint16) tmp;
}
g_free (ascii_uri);
return TRUE;
error:
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Invalid URI %s", uri);
if (host && *host)
{
g_free (*host);
*host = NULL;
}
if (userinfo && *userinfo)
{
g_free (*userinfo);
*userinfo = NULL;
}
g_free (ascii_uri);
return FALSE;
}
gchar *
_g_uri_from_authority (const gchar *protocol,
const gchar *host,
guint port,
const gchar *userinfo)
{
GString *uri;
uri = g_string_new (protocol);
g_string_append (uri, "://");
if (userinfo)
{
g_string_append_uri_escaped (uri, userinfo, G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE);
g_string_append_c (uri, '@');
}
if (g_hostname_is_non_ascii (host))
{
gchar *ace_encoded = g_hostname_to_ascii (host);
if (!ace_encoded)
{
g_string_free (uri, TRUE);
return NULL;
}
g_string_append (uri, ace_encoded);
g_free (ace_encoded);
}
else if (strchr (host, ':'))
g_string_append_printf (uri, "[%s]", host);
else
g_string_append (uri, host);
if (port != 0)
g_string_append_printf (uri, ":%u", port);
return g_string_free (uri, FALSE);
}
/**
* g_network_address_parse_uri:
* @uri: the hostname and optionally a port
@ -827,25 +541,27 @@ g_network_address_parse_uri (const gchar *uri,
guint16 default_port,
GError **error)
{
GSocketConnectable *conn;
gchar *scheme;
gchar *hostname;
guint16 port;
GSocketConnectable *conn = NULL;
gchar *scheme = NULL;
gchar *hostname = NULL;
gint port;
if (!_g_uri_parse_authority (uri, &hostname, &port, NULL, error))
return NULL;
if (!g_uri_split_network (uri, G_URI_FLAGS_PARSE_STRICT,
&scheme, &hostname, &port, NULL))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Invalid URI %s", uri);
return NULL;
}
if (port == 0)
if (port <= 0)
port = default_port;
scheme = g_uri_parse_scheme (uri);
conn = g_object_new (G_TYPE_NETWORK_ADDRESS,
"hostname", hostname,
"port", port,
"port", (guint) port,
"scheme", scheme,
NULL);
g_free (scheme);
g_free (hostname);
@ -1459,10 +1175,14 @@ g_network_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
GSocketAddressEnumerator *proxy_enum;
gchar *uri;
uri = _g_uri_from_authority (self->priv->scheme ? self->priv->scheme : "none",
self->priv->hostname,
self->priv->port,
NULL);
uri = g_uri_join (G_URI_FLAGS_NONE,
self->priv->scheme ? self->priv->scheme : "none",
NULL,
self->priv->hostname,
self->priv->port,
"",
NULL,
NULL);
proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
"connectable", connectable,

View File

@ -23,16 +23,6 @@
G_BEGIN_DECLS
gboolean _g_uri_parse_authority (const char *uri,
char **host,
guint16 *port,
char **userinfo,
GError **error);
gchar * _g_uri_from_authority (const gchar *protocol,
const gchar *host,
guint port,
const gchar *userinfo);
guint64 g_resolver_get_serial (GResolver *resolver);
gint g_socket (gint domain,

View File

@ -465,10 +465,14 @@ g_network_service_address_enumerator_next (GSocketAddressEnumerator *enumerator
continue;
}
uri = _g_uri_from_authority (g_network_service_get_scheme (srv_enum->srv),
hostname,
g_srv_target_get_port (target),
NULL);
uri = g_uri_join (G_URI_FLAGS_NONE,
g_network_service_get_scheme (srv_enum->srv),
NULL,
hostname,
g_srv_target_get_port (target),
"",
NULL,
NULL);
g_free (hostname);
addr = g_network_address_parse_uri (uri,

View File

@ -93,39 +93,14 @@ G_DEFINE_TYPE_WITH_PRIVATE (GProxyAddressEnumerator, g_proxy_address_enumerator,
static void
save_userinfo (GProxyAddressEnumeratorPrivate *priv,
const gchar *proxy)
const gchar *proxy)
{
gchar *userinfo;
g_clear_pointer (&priv->proxy_username, g_free);
g_clear_pointer (&priv->proxy_password, g_free);
if (priv->proxy_username)
{
g_free (priv->proxy_username);
priv->proxy_username = NULL;
}
if (priv->proxy_password)
{
g_free (priv->proxy_password);
priv->proxy_password = NULL;
}
if (_g_uri_parse_authority (proxy, NULL, NULL, &userinfo, NULL))
{
if (userinfo)
{
gchar **split = g_strsplit (userinfo, ":", 2);
if (split[0] != NULL)
{
priv->proxy_username = g_uri_unescape_string (split[0], NULL);
if (split[1] != NULL)
priv->proxy_password = g_uri_unescape_string (split[1], NULL);
}
g_strfreev (split);
g_free (userinfo);
}
}
g_uri_split_with_user (proxy, G_URI_FLAGS_HAS_PASSWORD, NULL,
&priv->proxy_username, &priv->proxy_password,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}
static void

View File

@ -29,6 +29,7 @@
#include "gcancellable.h"
#include "gtask.h"
#include "giomodule.h"
#include "gioerror.h"
#include "giomodule-priv.h"
#include "gnetworkingprivate.h"
@ -147,8 +148,12 @@ g_proxy_resolver_lookup (GProxyResolver *resolver,
g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
g_return_val_if_fail (uri != NULL, NULL);
if (!_g_uri_parse_authority (uri, NULL, NULL, NULL, error))
return NULL;
if (!g_uri_is_valid (uri, G_URI_FLAGS_PARSE_STRICT, NULL))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Invalid URI %s", uri);
return NULL;
}
iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
@ -181,8 +186,10 @@ g_proxy_resolver_lookup_async (GProxyResolver *resolver,
g_return_if_fail (G_IS_PROXY_RESOLVER (resolver));
g_return_if_fail (uri != NULL);
if (!_g_uri_parse_authority (uri, NULL, NULL, NULL, &error))
if (!g_uri_is_valid (uri, G_URI_FLAGS_PARSE_STRICT, NULL))
{
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Invalid URI %s", uri);
g_task_report_error (resolver, callback, user_data,
g_proxy_resolver_lookup_async,
g_steal_pointer (&error));

View File

@ -327,10 +327,11 @@ g_simple_proxy_resolver_lookup (GProxyResolver *proxy_resolver,
if (priv->ignore_ips || priv->ignore_domains)
{
gchar *host = NULL;
gushort port;
gint port;
if (_g_uri_parse_authority (uri, &host, &port, NULL, NULL) &&
ignore_host (resolver, host, port))
if (g_uri_split_network (uri, G_URI_FLAGS_PARSE_STRICT, NULL,
&host, &port, NULL) &&
ignore_host (resolver, host, port > 0 ? port : 0))
proxy = "direct://";
g_free (host);

View File

@ -398,7 +398,7 @@ g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable)
g_object_get (connectable, "address", &addr, "port", &port, NULL);
ip = g_inet_address_to_string (addr);
uri = _g_uri_from_authority ("none", ip, port, NULL);
uri = g_uri_join (G_URI_FLAGS_NONE, "none", NULL, ip, port, "", NULL, NULL);
addr_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
"connectable", connectable,

View File

@ -33,6 +33,11 @@
* The #GUri type and related functions can be used to parse URIs into
* their components, and build valid URIs from individual components.
*
* Note that #GUri scope is to help manipulate URIs in various applications,
* following the RFC 3986. In particular, it doesn't intend to cover web browser
* needs, and doesn't implement the WHATWG URL standard. No APIs are provided to
* help prevent homograph attacks.
*
* ## Parsing URIs
*
* The most minimalist APIs for parsing URIs are g_uri_split() and
@ -834,8 +839,8 @@ g_uri_split_internal (const gchar *uri_string,
/**
* g_uri_split:
* @uri_string: a string containing a relative or absolute URI
* @flags: flags for parsing @uri_string
* @uri_ref: a string containing a relative or absolute URI
* @flags: flags for parsing @uri_ref
* @scheme: (out) (nullable) (optional) (transfer full): on return, contains
* the scheme (converted to lowercase), or %NULL
* @userinfo: (out) (nullable) (optional) (transfer full): on return, contains
@ -852,14 +857,14 @@ g_uri_split_internal (const gchar *uri_string,
* the fragment, or %NULL
* @error: #GError for error reporting, or %NULL to ignore.
*
* Parses @uri_string (which can be an absolute or relative URI)
* Parses @uri_ref (which can be an absolute or relative URI)
* according to @flags, and returns the pieces. Any component that
* doesn't appear in @uri_string will be returned as %NULL (but note
* doesn't appear in @uri_ref will be returned as %NULL (but note
* that all URIs always have a path component, though it may be the
* empty string).
*
* If @flags contains %G_URI_FLAGS_ENCODED, then `%`-encoded characters in
* @uri_string will remain encoded in the output strings. (If not,
* @uri_ref will remain encoded in the output strings. (If not,
* then all such characters will be decoded.) Note that decoding will
* only work if the URI components are ASCII or UTF-8, so you will
* need to use %G_URI_FLAGS_ENCODED if they are not.
@ -869,13 +874,13 @@ g_uri_split_internal (const gchar *uri_string,
* since it always returns only the full userinfo; use
* g_uri_split_with_user() if you want it split up.
*
* Returns: (skip): %TRUE if @uri_string parsed successfully, %FALSE
* Returns: (skip): %TRUE if @uri_ref parsed successfully, %FALSE
* on error.
*
* Since: 2.66
*/
gboolean
g_uri_split (const gchar *uri_string,
g_uri_split (const gchar *uri_ref,
GUriFlags flags,
gchar **scheme,
gchar **userinfo,
@ -886,10 +891,10 @@ g_uri_split (const gchar *uri_string,
gchar **fragment,
GError **error)
{
g_return_val_if_fail (uri_string != NULL, FALSE);
g_return_val_if_fail (uri_ref != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return g_uri_split_internal (uri_string, flags,
return g_uri_split_internal (uri_ref, flags,
scheme, userinfo, NULL, NULL, NULL,
host, port, path, query, fragment,
error);
@ -897,8 +902,8 @@ g_uri_split (const gchar *uri_string,
/**
* g_uri_split_with_user:
* @uri_string: a string containing a relative or absolute URI
* @flags: flags for parsing @uri_string
* @uri_ref: a string containing a relative or absolute URI
* @flags: flags for parsing @uri_ref
* @scheme: (out) (nullable) (optional) (transfer full): on return, contains
* the scheme (converted to lowercase), or %NULL
* @user: (out) (nullable) (optional) (transfer full): on return, contains
@ -919,9 +924,9 @@ g_uri_split (const gchar *uri_string,
* the fragment, or %NULL
* @error: #GError for error reporting, or %NULL to ignore.
*
* Parses @uri_string (which can be an absolute or relative URI)
* Parses @uri_ref (which can be an absolute or relative URI)
* according to @flags, and returns the pieces. Any component that
* doesn't appear in @uri_string will be returned as %NULL (but note
* doesn't appear in @uri_ref will be returned as %NULL (but note
* that all URIs always have a path component, though it may be the
* empty string).
*
@ -931,13 +936,13 @@ g_uri_split (const gchar *uri_string,
* @auth_params will only be parsed out if @flags contains
* %G_URI_FLAGS_HAS_AUTH_PARAMS.
*
* Returns: (skip): %TRUE if @uri_string parsed successfully, %FALSE
* Returns: (skip): %TRUE if @uri_ref parsed successfully, %FALSE
* on error.
*
* Since: 2.66
*/
gboolean
g_uri_split_with_user (const gchar *uri_string,
g_uri_split_with_user (const gchar *uri_ref,
GUriFlags flags,
gchar **scheme,
gchar **user,
@ -950,10 +955,10 @@ g_uri_split_with_user (const gchar *uri_string,
gchar **fragment,
GError **error)
{
g_return_val_if_fail (uri_string != NULL, FALSE);
g_return_val_if_fail (uri_ref != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return g_uri_split_internal (uri_string, flags,
return g_uri_split_internal (uri_ref, flags,
scheme, NULL, user, password, auth_params,
host, port, path, query, fragment,
error);
@ -962,7 +967,7 @@ g_uri_split_with_user (const gchar *uri_string,
/**
* g_uri_split_network:
* @uri_string: a string containing a relative or absolute URI
* @uri_string: a string containing an absolute URI
* @flags: flags for parsing @uri_string
* @scheme: (out) (nullable) (optional) (transfer full): on return, contains
* the scheme (converted to lowercase), or %NULL
@ -1036,12 +1041,12 @@ g_uri_split_network (const gchar *uri_string,
/**
* g_uri_is_valid:
* @uri_string: a string containing a relative or absolute URI
* @uri_string: a string containing an absolute URI
* @flags: flags for parsing @uri_string
* @error: #GError for error reporting, or %NULL to ignore.
*
* Parses @uri_string (which can be an absolute or relative URI)
* according to @flags, to determine whether it is valid.
* Parses @uri_string according to @flags, to determine whether it is valid
* absolute URI.
*
* See g_uri_split(), and the definition of #GUriFlags, for more
* information on the effect of @flags.
@ -1058,10 +1063,7 @@ g_uri_is_valid (const gchar *uri_string,
g_return_val_if_fail (uri_string != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return g_uri_split_internal (uri_string, flags,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
error);
return g_uri_split_network (uri_string, flags, NULL, NULL, NULL, error);
}
@ -1153,12 +1155,12 @@ g_uri_parse (const gchar *uri_string,
/**
* g_uri_parse_relative:
* @base_uri: (nullable): a base URI
* @uri_string: a string representing a relative or absolute URI
* @flags: flags describing how to parse @uri_string
* @base_uri: (nullable): a base absolute URI
* @uri_ref: a string representing a relative or absolute URI
* @flags: flags describing how to parse @uri_ref
* @error: #GError for error reporting, or %NULL to ignore.
*
* Parses @uri_string according to @flags and, if it is a relative
* Parses @uri_ref according to @flags and, if it is a relative
* URI, resolves it relative to @base_uri. If the result is not a
* valid absolute URI, it will be discarded, and an error returned.
*
@ -1168,20 +1170,22 @@ g_uri_parse (const gchar *uri_string,
*/
GUri *
g_uri_parse_relative (GUri *base_uri,
const gchar *uri_string,
const gchar *uri_ref,
GUriFlags flags,
GError **error)
{
GUri *uri = NULL;
g_return_val_if_fail (uri_string != NULL, NULL);
g_return_val_if_fail (uri_ref != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
g_return_val_if_fail (base_uri == NULL || base_uri->scheme != NULL, NULL);
/* Use GUri struct to construct the return value: there is no guarantee it is
* actually correct within the function body. */
uri = g_atomic_rc_box_new0 (GUri);
uri->flags = flags;
if (!g_uri_split_internal (uri_string, flags,
if (!g_uri_split_internal (uri_ref, flags,
&uri->scheme, &uri->userinfo,
&uri->user, &uri->password, &uri->auth_params,
&uri->host, &uri->port,
@ -1264,16 +1268,16 @@ g_uri_parse_relative (GUri *base_uri,
/**
* g_uri_resolve_relative:
* @base_uri_string: (nullable): a string representing a base URI
* @uri_string: a string representing a relative or absolute URI
* @flags: flags describing how to parse @uri_string
* @uri_ref: a string representing a relative or absolute URI
* @flags: flags describing how to parse @uri_ref
* @error: #GError for error reporting, or %NULL to ignore.
*
* Parses @uri_string according to @flags and, if it is a relative
* Parses @uri_ref according to @flags and, if it is a relative
* URI, resolves it relative to @base_uri_string. If the result is not
* a valid absolute URI, it will be discarded, and an error returned.
*
* (If @base_uri_string is %NULL, this just returns @uri_string, or
* %NULL if @uri_string is invalid or not absolute.)
* (If @base_uri_string is %NULL, this just returns @uri_ref, or
* %NULL if @uri_ref is invalid or not absolute.)
*
* Return value: the resolved URI string.
*
@ -1281,14 +1285,14 @@ g_uri_parse_relative (GUri *base_uri,
*/
gchar *
g_uri_resolve_relative (const gchar *base_uri_string,
const gchar *uri_string,
const gchar *uri_ref,
GUriFlags flags,
GError **error)
{
GUri *base_uri, *resolved_uri;
gchar *resolved_uri_string;
g_return_val_if_fail (uri_string != NULL, NULL);
g_return_val_if_fail (uri_ref != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
flags |= G_URI_FLAGS_ENCODED;
@ -1302,7 +1306,7 @@ g_uri_resolve_relative (const gchar *base_uri_string,
else
base_uri = NULL;
resolved_uri = g_uri_parse_relative (base_uri, uri_string, flags, error);
resolved_uri = g_uri_parse_relative (base_uri, uri_ref, flags, error);
if (base_uri)
g_uri_unref (base_uri);
if (!resolved_uri)
@ -1447,13 +1451,13 @@ g_uri_join_internal (GUriFlags flags,
* @fragment: (nullable): the fragment, or %NULL
*
* Joins the given components together according to @flags to create
* a complete URI string. At least @scheme must be specified, and
* an absolute URI string. At least @scheme must be specified, and
* @path may not be %NULL (though it may be "").
*
* See also g_uri_join_with_user(), which allows specifying the
* components of the "userinfo" separately.
*
* Return value: a URI string
* Return value: an absolute URI string
*
* Since: 2.66
*/
@ -1497,13 +1501,13 @@ g_uri_join (GUriFlags flags,
* @fragment: (nullable): the fragment, or %NULL
*
* Joins the given components together according to @flags to create
* a complete URI string. At least @scheme must be specified, and
* an absolute URI string. At least @scheme must be specified, and
* @path may not be %NULL (though it may be "").
*
* In constrast to g_uri_join(), this allows specifying the components
* of the "userinfo" separately.
*
* Return value: a URI string
* Return value: an absolute URI string
*
* Since: 2.66
*/

View File

@ -83,7 +83,7 @@ typedef enum {
} GUriFlags;
GLIB_AVAILABLE_IN_2_66
gboolean g_uri_split (const gchar *uri_string,
gboolean g_uri_split (const gchar *uri_ref,
GUriFlags flags,
gchar **scheme,
gchar **userinfo,
@ -94,7 +94,7 @@ gboolean g_uri_split (const gchar *uri_string,
gchar **fragment,
GError **error);
GLIB_AVAILABLE_IN_2_66
gboolean g_uri_split_with_user (const gchar *uri_string,
gboolean g_uri_split_with_user (const gchar *uri_ref,
GUriFlags flags,
gchar **scheme,
gchar **user,
@ -146,13 +146,13 @@ GUri * g_uri_parse (const gchar *uri_string,
GError **error);
GLIB_AVAILABLE_IN_2_66
GUri * g_uri_parse_relative (GUri *base_uri,
const gchar *uri_string,
const gchar *uri_ref,
GUriFlags flags,
GError **error);
GLIB_AVAILABLE_IN_2_66
gchar * g_uri_resolve_relative (const gchar *base_uri_string,
const gchar *uri_string,
const gchar *uri_ref,
GUriFlags flags,
GError **error);

View File

@ -706,6 +706,8 @@ static const UriAbsoluteTest absolute_tests[] = {
{ "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%10]/",
{ "http", NULL, "fe80::dead:beef%10", -1, "/", NULL, NULL } },
{ "http://[fe80::dead:beef%25]/",
{ "http", NULL, "fe80::dead:beef%25", -1, "/", NULL, NULL } },
};
static int num_absolute_tests = G_N_ELEMENTS (absolute_tests);
@ -1309,12 +1311,15 @@ test_uri_is_valid (void)
g_assert_true (g_uri_is_valid ("http://\xc3\x89XAMPLE.COM/", G_URI_FLAGS_NONE, NULL));
g_assert_true (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_NONE, NULL));
g_assert_true (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_PARSE_STRICT, NULL));
g_assert_false (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_PARSE_STRICT, &error));
g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME);
g_clear_error (&error);
g_assert_false (g_uri_is_valid ("http://[::192.9.5.5/ipng", G_URI_FLAGS_NONE, &error));
g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
g_clear_error (&error);
g_assert_true (g_uri_is_valid ("http://[fe80::dead:beef%25wef]/", G_URI_FLAGS_NONE, NULL));
g_assert_false (g_uri_is_valid ("http://[fe80::dead:beef%wef%]/", G_URI_FLAGS_NONE, &error));
g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
g_clear_error (&error);