[c22e1a4acbd2d996ff19a852585f9434883c30124f6b118eb9152fe4e5ee7994: 5/8] uri: teach g_uri_parse_params() to decode www-form query



commit 30ad9c6711b309db13a8926d9732dcc83e6976b5
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Tue Jun 30 19:35:59 2020 +0400

    uri: teach g_uri_parse_params() to decode www-form query
    
    This is a minor convenience, to avoid caller to do further '+' decoding.
    
    According to the W3C HTML specification, space characters are replaced
    by '+': https://url.spec.whatwg.org/#urlencoded-parsing
    
    Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>

 glib/guri.c      | 19 +++++++++++++------
 glib/guri.h      |  2 ++
 glib/tests/uri.c |  4 ++++
 3 files changed, 19 insertions(+), 6 deletions(-)
---
diff --git a/glib/guri.c b/glib/guri.c
index e5ca12f77..1d7ad57a9 100644
--- a/glib/guri.c
+++ b/glib/guri.c
@@ -237,6 +237,7 @@ uri_decoder (gchar       **out,
              const gchar  *start,
              gsize         length,
              gboolean      just_normalize,
+             gboolean      www_form,
              GUriFlags     flags,
              GUriError     parse_error,
              GError      **error)
@@ -287,6 +288,8 @@ uri_decoder (gchar       **out,
               s += 2;
             }
         }
+      else if (www_form && *s == '+')
+        *d++ = ' ';
       else
         *d++ = *s;
     }
@@ -314,11 +317,12 @@ static gboolean
 uri_decode (gchar       **out,
             const gchar  *start,
             gsize         length,
+            gboolean      www_form,
             GUriFlags     flags,
             GUriError     parse_error,
             GError      **error)
 {
-  return uri_decoder (out, start, length, FALSE, flags,
+  return uri_decoder (out, start, length, FALSE, www_form, flags,
                       parse_error, error) != -1;
 }
 
@@ -330,7 +334,7 @@ uri_normalize (gchar       **out,
                GUriError     parse_error,
                GError      **error)
 {
-  return uri_decoder (out, start, length, TRUE, flags,
+  return uri_decoder (out, start, length, TRUE, FALSE, flags,
                       parse_error, error) != -1;
 }
 
@@ -450,7 +454,7 @@ parse_host (const gchar  *start,
     }
 
   flags &= ~G_URI_FLAGS_ENCODED;
-  if (!uri_decode (&decoded, start, length, flags,
+  if (!uri_decode (&decoded, start, length, FALSE, flags,
                    G_URI_ERROR_BAD_HOST, error))
     return FALSE;
 
@@ -771,7 +775,7 @@ g_uri_split_internal (const gchar  *uri_string,
   end = p + strcspn (p, "#");
   if (*end == '#')
     {
-      if (!uri_decode (fragment, end + 1, strlen (end + 1), flags,
+      if (!uri_decode (fragment, end + 1, strlen (end + 1), FALSE, flags,
                        G_URI_ERROR_BAD_FRAGMENT, error))
         goto fail;
     }
@@ -1786,6 +1790,7 @@ g_uri_parse_params (const gchar     *params,
   const gchar *end, *attr, *attr_end, *value, *value_end, *s;
   gchar *decoded_attr, *decoded_value;
   guint8 sep_table[256]; /* 1 = index is a separator; 0 otherwise */
+  gboolean www_form = flags & G_URI_PARAMS_WWW_FORM;
 
   g_return_val_if_fail (length == 0 || params != NULL, NULL);
   g_return_val_if_fail (length >= -1, NULL);
@@ -1829,7 +1834,7 @@ g_uri_parse_params (const gchar     *params,
           return NULL;
         }
       if (!uri_decode (&decoded_attr, attr, attr_end - attr,
-                       0, G_URI_ERROR_MISC, NULL))
+                       www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, NULL))
         {
           g_hash_table_destroy (hash);
           return NULL;
@@ -1837,7 +1842,7 @@ g_uri_parse_params (const gchar     *params,
 
       value = attr_end + 1;
       if (!uri_decode (&decoded_value, value, value_end - value,
-                       0, G_URI_ERROR_MISC, NULL))
+                       www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, NULL))
         {
           g_free (decoded_attr);
           g_hash_table_destroy (hash);
@@ -2118,6 +2123,7 @@ g_uri_unescape_segment (const gchar *escaped_string,
 
   if (!uri_decode (&unescaped,
                    escaped_string, length,
+                   FALSE,
                    G_URI_FLAGS_PARSE_STRICT,
                    0, NULL))
     return NULL;
@@ -2232,6 +2238,7 @@ g_uri_unescape_bytes (const gchar *escaped_string,
   unescaped_length = uri_decoder (&buf,
                                   escaped_string, length,
                                   FALSE,
+                                  FALSE,
                                   G_URI_FLAGS_PARSE_STRICT|G_URI_FLAGS_ENCODED,
                                   0, NULL);
   if (unescaped_length == -1)
diff --git a/glib/guri.h b/glib/guri.h
index 344f7f9bd..b9f49792e 100644
--- a/glib/guri.h
+++ b/glib/guri.h
@@ -226,6 +226,7 @@ GUriFlags    g_uri_get_flags         (GUri          *uri);
  * GUriParamsFlags:
  * @G_URI_PARAMS_NONE: No flags set.
  * @G_URI_PARAMS_CASE_INSENSITIVE: whether parameter names are case insensitive.
+ * @G_URI_PARAMS_WWW_FORM: replace `+` with space character.
  *
  * Flags modifying the way parameters are handled.
  *
@@ -235,6 +236,7 @@ GLIB_AVAILABLE_TYPE_IN_2_66
 typedef enum {
   G_URI_PARAMS_NONE             = 0,
   G_URI_PARAMS_CASE_INSENSITIVE = 1 << 0,
+  G_URI_PARAMS_WWW_FORM         = 1 << 1,
 } GUriParamsFlags;
 
 GLIB_AVAILABLE_IN_2_66
diff --git a/glib/tests/uri.c b/glib/tests/uri.c
index ee4242de5..fd131a6fb 100644
--- a/glib/tests/uri.c
+++ b/glib/tests/uri.c
@@ -1288,6 +1288,10 @@ test_uri_parse_params (gconstpointer test_data)
       { "=%", "&", G_URI_PARAMS_NONE, 1, { "", "%", NULL, }},
       { "=", "&", G_URI_PARAMS_NONE, 1, { "", "", NULL, }},
       { "foo", "&", G_URI_PARAMS_NONE, -1, { NULL, }},
+      { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_WWW_FORM,
+        2, { "foo", "bar & baz", "saisons", "Été+hiver", NULL, }},
+      { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_NONE,
+        2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, }},
     };
   gsize i;
 


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