uri: make g_uri_parse_params() take an error

This should be more future-proof.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2020-07-06 19:38:40 +04:00
parent 7bee36b4ff
commit 3f72a95925
4 changed files with 25 additions and 7 deletions

View File

@ -3,6 +3,7 @@
int int
LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
{ {
GError *error = NULL;
GHashTable *parsed_params = NULL; GHashTable *parsed_params = NULL;
fuzz_set_logging_func (); fuzz_set_logging_func ();
@ -10,10 +11,17 @@ LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
if (size > G_MAXSSIZE) if (size > G_MAXSSIZE)
return 0; return 0;
parsed_params = g_uri_parse_params ((const gchar *) data, (gssize) size, "&", G_URI_PARAMS_NONE); parsed_params = g_uri_parse_params ((const gchar *) data, (gssize) size,
"&", G_URI_PARAMS_NONE, &error);
if (parsed_params == NULL) if (parsed_params == NULL)
return 0; {
g_assert (error);
g_clear_error (&error);
return 0;
}
g_assert_no_error (error);
g_hash_table_unref (parsed_params); g_hash_table_unref (parsed_params);
return 0; return 0;

View File

@ -1764,6 +1764,7 @@ str_ascii_case_equal (gconstpointer v1,
* anything but ASCII characters. You may pass an empty set, in which case * anything but ASCII characters. You may pass an empty set, in which case
* no splitting will occur. * no splitting will occur.
* @flags: flags to modify the way the parameters are handled. * @flags: flags to modify the way the parameters are handled.
* @error: #GError for error reporting, or %NULL to ignore.
* *
* Many URI schemes include one or more attribute/value pairs as part of the URI * Many URI schemes include one or more attribute/value pairs as part of the URI
* value. This method can be used to parse them into a hash table. * value. This method can be used to parse them into a hash table.
@ -1788,7 +1789,8 @@ GHashTable *
g_uri_parse_params (const gchar *params, g_uri_parse_params (const gchar *params,
gssize length, gssize length,
const gchar *separators, const gchar *separators,
GUriParamsFlags flags) GUriParamsFlags flags,
GError **error)
{ {
GHashTable *hash; GHashTable *hash;
const gchar *end, *attr, *attr_end, *value, *value_end, *s; const gchar *end, *attr, *attr_end, *value, *value_end, *s;
@ -1799,6 +1801,7 @@ g_uri_parse_params (const gchar *params,
g_return_val_if_fail (length == 0 || params != NULL, NULL); g_return_val_if_fail (length == 0 || params != NULL, NULL);
g_return_val_if_fail (length >= -1, NULL); g_return_val_if_fail (length >= -1, NULL);
g_return_val_if_fail (separators != NULL, NULL); g_return_val_if_fail (separators != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (flags & G_URI_PARAMS_CASE_INSENSITIVE) if (flags & G_URI_PARAMS_CASE_INSENSITIVE)
{ {
@ -1835,10 +1838,12 @@ g_uri_parse_params (const gchar *params,
if (!attr_end) if (!attr_end)
{ {
g_hash_table_destroy (hash); g_hash_table_destroy (hash);
g_set_error_literal (error, G_URI_ERROR, G_URI_ERROR_MISC,
_("Missing '=' and parameter value"));
return NULL; return NULL;
} }
if (!uri_decode (&decoded_attr, attr, attr_end - attr, if (!uri_decode (&decoded_attr, attr, attr_end - attr,
www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, NULL)) www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, error))
{ {
g_hash_table_destroy (hash); g_hash_table_destroy (hash);
return NULL; return NULL;
@ -1846,7 +1851,7 @@ g_uri_parse_params (const gchar *params,
value = attr_end + 1; value = attr_end + 1;
if (!uri_decode (&decoded_value, value, value_end - value, if (!uri_decode (&decoded_value, value, value_end - value,
www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, NULL)) www_form, G_URI_FLAGS_NONE, G_URI_ERROR_MISC, error))
{ {
g_free (decoded_attr); g_free (decoded_attr);
g_hash_table_destroy (hash); g_hash_table_destroy (hash);

View File

@ -246,7 +246,8 @@ GLIB_AVAILABLE_IN_2_66
GHashTable *g_uri_parse_params (const gchar *params, GHashTable *g_uri_parse_params (const gchar *params,
gssize length, gssize length,
const gchar *separators, const gchar *separators,
GUriParamsFlags flags); GUriParamsFlags flags,
GError **error);
/** /**
* G_URI_ERROR: * G_URI_ERROR:

View File

@ -1297,6 +1297,7 @@ test_uri_is_valid (void)
static void static void
test_uri_parse_params (gconstpointer test_data) test_uri_parse_params (gconstpointer test_data)
{ {
GError *err = NULL;
gboolean use_nul_terminated = GPOINTER_TO_INT (test_data); gboolean use_nul_terminated = GPOINTER_TO_INT (test_data);
const struct const struct
{ {
@ -1353,16 +1354,19 @@ test_uri_parse_params (gconstpointer test_data)
uri = g_memdup (tests[i].uri, uri_len); uri = g_memdup (tests[i].uri, uri_len);
} }
params = g_uri_parse_params (uri, uri_len, tests[i].separators, tests[i].flags); params = g_uri_parse_params (uri, uri_len, tests[i].separators, tests[i].flags, &err);
if (tests[i].expected_n_params < 0) if (tests[i].expected_n_params < 0)
{ {
g_assert_null (params); g_assert_null (params);
g_assert_error (err, G_URI_ERROR, G_URI_ERROR_MISC);
g_clear_error (&err);
} }
else else
{ {
gsize j; gsize j;
g_assert_no_error (err);
g_assert_cmpint (g_hash_table_size (params), ==, tests[i].expected_n_params); g_assert_cmpint (g_hash_table_size (params), ==, tests[i].expected_n_params);
for (j = 0; j < tests[i].expected_n_params; j += 2) for (j = 0; j < tests[i].expected_n_params; j += 2)