[c22e1a4acbd2d996ff19a852585f9434883c30124f6b118eb9152fe4e5ee7994: 6/8] uri: add G_FLAGS_ENCODED_QUERY



commit 7bee36b4fff561c623ff74d49de57631b974a8ce
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Thu Jul 2 16:16:27 2020 +0400

    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>

 glib/guri.c      | 10 +++++++---
 glib/guri.h      |  3 +++
 glib/tests/uri.c | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 3 deletions(-)
---
diff --git a/glib/guri.c b/glib/guri.c
index 1d7ad57a9..e34cbd9d9 100644
--- a/glib/guri.c
+++ b/glib/guri.c
@@ -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);
diff --git a/glib/guri.h b/glib/guri.h
index b9f49792e..4ceb04df4 100644
--- a/glib/guri.h
+++ b/glib/guri.h
@@ -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
diff --git a/glib/tests/uri.c b/glib/tests/uri.c
index fd131a6fb..c25fd7607 100644
--- a/glib/tests/uri.c
+++ b/glib/tests/uri.c
@@ -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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]