diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c index f12f93585..a93bafa36 100644 --- a/gio/gnetworkaddress.c +++ b/gio/gnetworkaddress.c @@ -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, diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h index ed0feb823..dd8a277a5 100644 --- a/gio/gnetworkingprivate.h +++ b/gio/gnetworkingprivate.h @@ -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, diff --git a/gio/gnetworkservice.c b/gio/gnetworkservice.c index 92225f137..2b8571e9b 100644 --- a/gio/gnetworkservice.c +++ b/gio/gnetworkservice.c @@ -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, diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c index ecf04d110..d3de4940c 100644 --- a/gio/gproxyaddressenumerator.c +++ b/gio/gproxyaddressenumerator.c @@ -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 diff --git a/gio/gproxyresolver.c b/gio/gproxyresolver.c index bd9528dd0..f72ad2a72 100644 --- a/gio/gproxyresolver.c +++ b/gio/gproxyresolver.c @@ -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)); diff --git a/gio/gsimpleproxyresolver.c b/gio/gsimpleproxyresolver.c index f33d49f8c..58368ea4e 100644 --- a/gio/gsimpleproxyresolver.c +++ b/gio/gsimpleproxyresolver.c @@ -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); diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c index 848e37b0b..2b7e83ccf 100644 --- a/gio/gsocketaddress.c +++ b/gio/gsocketaddress.c @@ -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, diff --git a/glib/guri.c b/glib/guri.c index 9dfebcf07..92c6128df 100644 --- a/glib/guri.c +++ b/glib/guri.c @@ -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 */ diff --git a/glib/guri.h b/glib/guri.h index da0bc9bc4..e2bc04b31 100644 --- a/glib/guri.h +++ b/glib/guri.h @@ -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); diff --git a/glib/tests/uri.c b/glib/tests/uri.c index 74ad24d98..121749d76 100644 --- a/glib/tests/uri.c +++ b/glib/tests/uri.c @@ -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);