uri: fix regression in g_uri_unescape_segment/string

The previous implementation of g_uri_unescape_segment() allowed non-utf8
decoded characters. uri_decoder() allows it too with FLAGS_ENCODED (I
think it's abusing a bit the user-facing flags for some internal
decoding behaviour)

However, it didn't allow \0 in the decoded string. Let's have an extra
check for that, outside of uri_decoder().

Fixes: d83d68d64c
Reported-by: Matthias Clasen <mclasen@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2020-07-08 17:47:30 +04:00
parent ea395e3fdd
commit 22fe3b0224
2 changed files with 18 additions and 6 deletions

View File

@ -2116,6 +2116,9 @@ g_uri_get_flags (GUri *uri)
* want to avoid for instance having a slash being expanded in an
* escaped path element, which might confuse pathname handling.
*
* Note: `NUL` byte is not accepted in the output, in contrast to
* g_uri_unescape_bytes().
*
* Returns: an unescaped version of @escaped_string or %NULL on error.
* The returned string should be freed when no longer needed. As a
* special case if %NULL is given for @escaped_string, this function
@ -2130,6 +2133,7 @@ g_uri_unescape_segment (const gchar *escaped_string,
{
gchar *unescaped;
gsize length;
gssize decoded_len;
if (!escaped_string)
return NULL;
@ -2139,14 +2143,21 @@ g_uri_unescape_segment (const gchar *escaped_string,
else
length = strlen (escaped_string);
if (!uri_decode (&unescaped,
illegal_characters,
escaped_string, length,
FALSE,
G_URI_FLAGS_PARSE_STRICT,
0, NULL))
decoded_len = uri_decoder (&unescaped,
illegal_characters,
escaped_string, length,
FALSE, FALSE,
G_URI_FLAGS_PARSE_STRICT|G_URI_FLAGS_ENCODED,
0, NULL);
if (decoded_len < 0)
return NULL;
if (memchr (unescaped, '\0', decoded_len))
{
g_free (unescaped);
return NULL;
}
return unescaped;
}

View File

@ -348,6 +348,7 @@ test_uri_unescape_string (void)
{ "%0", NULL, NULL },
{ "%ra", NULL, NULL },
{ "%2r", NULL, NULL },
{ "Timm B\344der", NULL, "Timm B\344der" },
{ NULL, NULL, NULL }, /* actually a valid test, not a delimiter */
};
gsize i;