From 63ddaa3b7f4d694b06a182695c2d9484e7ef9dea Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Tue, 26 Jan 2021 15:04:09 +0100 Subject: Fix soup_uri_get_path_and_query handling paths with // Closes !165 And add tests for soup_uri_get_path_and_query() --- libsoup/soup-uri-utils.c | 30 +++++++++++++++++++++++++----- tests/uri-parsing-test.c | 26 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/libsoup/soup-uri-utils.c b/libsoup/soup-uri-utils.c index 96807628..0aac9784 100644 --- a/libsoup/soup-uri-utils.c +++ b/libsoup/soup-uri-utils.c @@ -124,16 +124,36 @@ soup_uri_equal (GUri *uri1, GUri *uri2) return TRUE; } +/** + * soup_uri_get_path_and_query: + * @uri: a #GUri + * + * Extracts the `path` and `query` parts from @uri. + * + * Returns: string of combined path and query + **/ char * soup_uri_get_path_and_query (GUri *uri) { + char *path_and_query; + gsize len; + g_return_val_if_fail (uri != NULL, NULL); - return g_uri_join_with_user (SOUP_HTTP_URI_FLAGS, - NULL, NULL, NULL, NULL, NULL, -1, - g_uri_get_path (uri), - g_uri_get_query (uri), - NULL); + /* An empty string is passed instead of NULL for host to prevent critical assertion if path begins with "//" + as per https://tools.ietf.org/html/rfc3986#section-3 */ + path_and_query = g_uri_join_with_user (SOUP_HTTP_URI_FLAGS, + NULL, NULL, NULL, NULL, "", -1, + g_uri_get_path (uri), + g_uri_get_query (uri), + NULL); + + /* The empty host results in starting with `//` which we strip off */ + len = strlen (path_and_query); + memmove (path_and_query, path_and_query + 2, len - 2); + path_and_query[len - 2] = '\0'; + + return path_and_query; } /** diff --git a/tests/uri-parsing-test.c b/tests/uri-parsing-test.c index 8d96ce63..48e3964e 100644 --- a/tests/uri-parsing-test.c +++ b/tests/uri-parsing-test.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ #include "test-utils.h" +#include "soup-uri-utils-private.h" static struct { const char *one, *two; @@ -155,6 +156,30 @@ do_data_uri_tests (void) } } +static struct { + const char *input; + const char *output; +} path_and_query_tests[] = { + { "https://simple/one?two", "/one?two" }, + { "https://double_path//one?two", "//one?two" }, + { "https://empty", "/" }, +}; + +static void +do_path_and_query_tests (void) +{ + for (int i = 0; i < G_N_ELEMENTS (path_and_query_tests); i++) { + GUri *uri = g_uri_parse (path_and_query_tests[i].input, SOUP_HTTP_URI_FLAGS, NULL); + g_assert_nonnull (uri); + + char *path_and_query = soup_uri_get_path_and_query (uri); + g_assert_cmpstr (path_and_query, ==, path_and_query_tests[i].output); + + g_free (path_and_query); + g_uri_unref (uri); + } +} + int main (int argc, char **argv) { @@ -165,6 +190,7 @@ main (int argc, char **argv) g_test_add_func ("/uri/equality", do_equality_tests); g_test_add_func ("/uri/copy", do_copy_tests); g_test_add_func ("/data", do_data_uri_tests); + g_test_add_func ("/path_and_query", do_path_and_query_tests); ret = g_test_run (); -- cgit v1.2.1