uri: add G_FLAGS_ENCODED_QUERY

A query string may have some '=' characters '%'-encoded that could be
split by g_uri_parse_params() incorrectly. Instead, callers should leave
the query part encoded, and let g_uri_parse_params() do the decoding.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2020-07-02 16:16:27 +04:00
parent 30ad9c6711
commit 7bee36b4ff
3 changed files with 42 additions and 3 deletions

View File

@ -148,7 +148,10 @@
* g_assert_error(err, G_URI_ERROR, G_URI_ERROR_BAD_QUERY);
* ]|
*
* (you should pass %G_URI_FLAGS_ENCODED if you need to handle that case manually).
* You should pass %G_URI_FLAGS_ENCODED or %G_URI_FLAGS_ENCODED_QUERY if you
* need to handle that case manually. In particular, if the query string
* contains '=' characters that are '%'-encoded, you should let
* g_uri_parse_params() do the decoding once of the query.
*
* #GUri is immutable once constructed, and can safely be accessed from
* multiple threads. Its reference counting is atomic.
@ -784,7 +787,8 @@ g_uri_split_internal (const gchar *uri_string,
question = memchr (p, '?', end - p);
if (question)
{
if (!uri_normalize (query, question + 1, end - (question + 1), flags,
if (!uri_normalize (query, question + 1, end - (question + 1),
flags | (flags & G_URI_FLAGS_ENCODED_QUERY ? G_URI_FLAGS_ENCODED : 0),
G_URI_ERROR_BAD_QUERY, error))
goto fail;
end = question;
@ -1399,7 +1403,7 @@ g_uri_join_internal (GUriFlags flags,
if (query)
{
g_string_append_c (str, '?');
if (encoded)
if (encoded || flags & G_URI_FLAGS_ENCODED_QUERY)
g_string_append (str, query);
else
g_string_append_uri_escaped (str, query, QUERY_ALLOWED_CHARS, TRUE);

View File

@ -53,6 +53,8 @@ void g_uri_unref (GUri *uri);
* %G_URI_FLAGS_NON_DNS is also set.) When building a URI, it indicates
* that you have already `%`-encoded the components, and so #GUri
* should not do any encoding itself.
* @G_URI_FLAGS_ENCODED_QUERY: Same as %G_URI_FLAGS_ENCODED, for the query
* field only.
* @G_URI_FLAGS_NONE: No flags set.
*
* Flags that describe a URI.
@ -72,6 +74,7 @@ typedef enum {
G_URI_FLAGS_HAS_AUTH_PARAMS = 1 << 2,
G_URI_FLAGS_ENCODED = 1 << 3,
G_URI_FLAGS_NON_DNS = 1 << 4,
G_URI_FLAGS_ENCODED_QUERY = 1 << 5,
} GUriFlags;
GLIB_AVAILABLE_IN_2_66

View File

@ -1070,6 +1070,38 @@ test_uri_split (void)
g_assert_cmpstr (path, ==, ";oo/");
g_free (path);
g_uri_split ("http://h%01st/path?saisons=%C3%89t%C3%A9%2Bhiver",
G_URI_FLAGS_NONE,
NULL,
NULL,
&host,
NULL,
NULL,
&query,
NULL,
&error);
g_assert_no_error (error);
g_assert_cmpstr (host, ==, "h\001st");
g_assert_cmpstr (query, ==, "saisons=Été+hiver");
g_free (host);
g_free (query);
g_uri_split ("http://h%01st/path?saisons=%C3%89t%C3%A9%2Bhiver",
G_URI_FLAGS_ENCODED_QUERY,
NULL,
NULL,
&host,
NULL,
NULL,
&query,
NULL,
&error);
g_assert_no_error (error);
g_assert_cmpstr (host, ==, "h\001st");
g_assert_cmpstr (query, ==, "saisons=%C3%89t%C3%A9%2Bhiver");
g_free (host);
g_free (query);
g_uri_split_with_user ("scheme://user:pass;auth@host:1234/path?query#fragment",
G_URI_FLAGS_HAS_AUTH_PARAMS|G_URI_FLAGS_HAS_PASSWORD,
NULL,