[glib: 1/2] uri: fix g_uri_unescape_string() regression



commit 4433a46e0690ebaa6404265bccb440986210da97
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Tue Jul 14 12:10:51 2020 +0400

    uri: fix g_uri_unescape_string() regression
    
    The illegal character set used to be applied only to the decoded
    characters.
    
    Fixes: https://gitlab.gnome.org/GNOME/glib/-/issues/2160
    
    Fixes: d83d68d64c40 ("guri: new URI parsing and generating functions")
    Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>

 glib/guri.c      | 37 ++++++++++++++++++-------------------
 glib/tests/uri.c |  2 ++
 2 files changed, 20 insertions(+), 19 deletions(-)
---
diff --git a/glib/guri.c b/glib/guri.c
index 87da6bb7e..e4fbc003d 100644
--- a/glib/guri.c
+++ b/glib/guri.c
@@ -237,6 +237,7 @@ g_uri_char_is_unreserved (gchar ch)
 
 static gssize
 uri_decoder (gchar       **out,
+             const gchar  *illegal_chars,
              const gchar  *start,
              gsize         length,
              gboolean      just_normalize,
@@ -280,6 +281,13 @@ uri_decoder (gchar       **out,
             }
 
           c = HEXCHAR (s);
+          if (illegal_chars && strchr (illegal_chars, c))
+            {
+              g_set_error_literal (error, G_URI_ERROR, parse_error,
+                                   _("Illegal character in URI"));
+              g_free (decoded);
+              return -1;
+            }
           if (just_normalize && !g_uri_char_is_unreserved (c))
             {
               /* Leave the % sequence there. */
@@ -318,6 +326,7 @@ uri_decoder (gchar       **out,
 
 static gboolean
 uri_decode (gchar       **out,
+            const gchar  *illegal_chars,
             const gchar  *start,
             gsize         length,
             gboolean      www_form,
@@ -325,7 +334,7 @@ uri_decode (gchar       **out,
             GUriError     parse_error,
             GError      **error)
 {
-  return uri_decoder (out, start, length, FALSE, www_form, flags,
+  return uri_decoder (out, illegal_chars, start, length, FALSE, www_form, flags,
                       parse_error, error) != -1;
 }
 
@@ -337,7 +346,7 @@ uri_normalize (gchar       **out,
                GUriError     parse_error,
                GError      **error)
 {
-  return uri_decoder (out, start, length, TRUE, FALSE, flags,
+  return uri_decoder (out, NULL, start, length, TRUE, FALSE, flags,
                       parse_error, error) != -1;
 }
 
@@ -457,7 +466,7 @@ parse_host (const gchar  *start,
     }
 
   flags &= ~G_URI_FLAGS_ENCODED;
-  if (!uri_decode (&decoded, start, length, FALSE, flags,
+  if (!uri_decode (&decoded, NULL, start, length, FALSE, flags,
                    G_URI_ERROR_BAD_HOST, error))
     return FALSE;
 
@@ -778,7 +787,7 @@ g_uri_split_internal (const gchar  *uri_string,
   end = p + strcspn (p, "#");
   if (*end == '#')
     {
-      if (!uri_decode (fragment, end + 1, strlen (end + 1), FALSE, flags,
+      if (!uri_decode (fragment, NULL, end + 1, strlen (end + 1), FALSE, flags,
                        G_URI_ERROR_BAD_FRAGMENT, error))
         goto fail;
     }
@@ -1842,7 +1851,7 @@ g_uri_parse_params (const gchar     *params,
                                _("Missing '=' and parameter value"));
           return NULL;
         }
-      if (!uri_decode (&decoded_attr, attr, attr_end - attr,
+      if (!uri_decode (&decoded_attr, NULL, attr, attr_end - attr,
                        www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, error))
         {
           g_hash_table_destroy (hash);
@@ -1850,7 +1859,7 @@ g_uri_parse_params (const gchar     *params,
         }
 
       value = attr_end + 1;
-      if (!uri_decode (&decoded_value, value, value_end - value,
+      if (!uri_decode (&decoded_value, NULL, value, value_end - value,
                        www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, error))
         {
           g_free (decoded_attr);
@@ -2119,7 +2128,7 @@ g_uri_unescape_segment (const gchar *escaped_string,
                         const gchar *escaped_string_end,
                         const gchar *illegal_characters)
 {
-  gchar *unescaped, *p;
+  gchar *unescaped;
   gsize length;
 
   if (!escaped_string)
@@ -2131,24 +2140,13 @@ g_uri_unescape_segment (const gchar *escaped_string,
     length = strlen (escaped_string);
 
   if (!uri_decode (&unescaped,
+                   illegal_characters,
                    escaped_string, length,
                    FALSE,
                    G_URI_FLAGS_PARSE_STRICT,
                    0, NULL))
     return NULL;
 
-  if (illegal_characters)
-    {
-      for (p = unescaped; *p; p++)
-        {
-          if (strchr (illegal_characters, *p))
-            {
-              g_free (unescaped);
-              return NULL;
-            }
-        }
-    }
-
   return unescaped;
 }
 
@@ -2245,6 +2243,7 @@ g_uri_unescape_bytes (const gchar *escaped_string,
     length = strlen (escaped_string);
 
   unescaped_length = uri_decoder (&buf,
+                                  NULL,
                                   escaped_string, length,
                                   FALSE,
                                   FALSE,
diff --git a/glib/tests/uri.c b/glib/tests/uri.c
index 160413b52..6927b8904 100644
--- a/glib/tests/uri.c
+++ b/glib/tests/uri.c
@@ -343,6 +343,8 @@ test_uri_unescape_string (void)
       { "%2Babc %4F", NULL, "+abc O" },
       { "%2Babc %4F", "+", NULL },
       { "%00abc %4F", "+/", NULL },
+      { "/cursors/none.png", "/", "/cursors/none.png" },
+      { "/cursors%2fbad-subdir/none.png", "/", NULL },
       { "%0", NULL, NULL },
       { "%ra", NULL, NULL },
       { "%2r", NULL, NULL },


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