summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Griffis <pgriffis@igalia.com>2021-01-26 15:04:09 +0100
committerPatrick Griffis <pgriffis@igalia.com>2021-01-27 12:11:26 -0600
commit63ddaa3b7f4d694b06a182695c2d9484e7ef9dea (patch)
tree9ce4d88922fe9e73c9c7fe33a3f0e5019eec50cf
parent223a22d4e2a6e90d5a5f01382d4828e5efbad958 (diff)
downloadlibsoup-63ddaa3b7f4d694b06a182695c2d9484e7ef9dea.tar.gz
Fix soup_uri_get_path_and_query handling paths with //
Closes !165 And add tests for soup_uri_get_path_and_query()
-rw-r--r--libsoup/soup-uri-utils.c30
-rw-r--r--tests/uri-parsing-test.c26
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 ();