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;