From 3f72a959253162df68da346577f89f01cb31109a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 6 Jul 2020 19:38:40 +0400 Subject: [PATCH] uri: make g_uri_parse_params() take an error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should be more future-proof. Signed-off-by: Marc-André Lureau --- fuzzing/fuzz_uri_parse_params.c | 12 ++++++++++-- glib/guri.c | 11 ++++++++--- glib/guri.h | 3 ++- glib/tests/uri.c | 6 +++++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/fuzzing/fuzz_uri_parse_params.c b/fuzzing/fuzz_uri_parse_params.c index 6783c0000..ddae5708a 100644 --- a/fuzzing/fuzz_uri_parse_params.c +++ b/fuzzing/fuzz_uri_parse_params.c @@ -3,6 +3,7 @@ int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) { + GError *error = NULL; GHashTable *parsed_params = NULL; fuzz_set_logging_func (); @@ -10,10 +11,17 @@ LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) if (size > G_MAXSSIZE) 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) - return 0; + { + g_assert (error); + g_clear_error (&error); + return 0; + } + + g_assert_no_error (error); g_hash_table_unref (parsed_params); return 0; diff --git a/glib/guri.c b/glib/guri.c index e34cbd9d9..87da6bb7e 100644 --- a/glib/guri.c +++ b/glib/guri.c @@ -1764,6 +1764,7 @@ str_ascii_case_equal (gconstpointer v1, * anything but ASCII characters. You may pass an empty set, in which case * no splitting will occur. * @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 * 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, gssize length, const gchar *separators, - GUriParamsFlags flags) + GUriParamsFlags flags, + GError **error) { GHashTable *hash; 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 >= -1, 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) { @@ -1835,10 +1838,12 @@ g_uri_parse_params (const gchar *params, if (!attr_end) { g_hash_table_destroy (hash); + g_set_error_literal (error, G_URI_ERROR, G_URI_ERROR_MISC, + _("Missing '=' and parameter value")); return NULL; } 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); return NULL; @@ -1846,7 +1851,7 @@ g_uri_parse_params (const gchar *params, value = attr_end + 1; 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_hash_table_destroy (hash); diff --git a/glib/guri.h b/glib/guri.h index 4ceb04df4..5db6691ba 100644 --- a/glib/guri.h +++ b/glib/guri.h @@ -246,7 +246,8 @@ GLIB_AVAILABLE_IN_2_66 GHashTable *g_uri_parse_params (const gchar *params, gssize length, const gchar *separators, - GUriParamsFlags flags); + GUriParamsFlags flags, + GError **error); /** * G_URI_ERROR: diff --git a/glib/tests/uri.c b/glib/tests/uri.c index c25fd7607..160413b52 100644 --- a/glib/tests/uri.c +++ b/glib/tests/uri.c @@ -1297,6 +1297,7 @@ test_uri_is_valid (void) static void test_uri_parse_params (gconstpointer test_data) { + GError *err = NULL; gboolean use_nul_terminated = GPOINTER_TO_INT (test_data); const struct { @@ -1353,16 +1354,19 @@ test_uri_parse_params (gconstpointer test_data) 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) { g_assert_null (params); + g_assert_error (err, G_URI_ERROR, G_URI_ERROR_MISC); + g_clear_error (&err); } else { gsize j; + g_assert_no_error (err); g_assert_cmpint (g_hash_table_size (params), ==, tests[i].expected_n_params); for (j = 0; j < tests[i].expected_n_params; j += 2)