gsturi: Ensure file:// URIs retain //

Add the // back after the scheme for file URIs so 'file:///path/to/file'
doesn't become 'file:/path/to/file' in gst_uri_to_string()

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6969>
This commit is contained in:
Jan Schmidt 2024-05-29 16:33:48 +03:00 committed by GStreamer Marge Bot
parent bff24e5ab7
commit 7bd51afd04
2 changed files with 72 additions and 38 deletions

View file

@ -2028,8 +2028,9 @@ gst_uri_to_string_with_keys (const GstUri * uri, const GList * keys)
g_string_append_printf (uri_str, "%s:", uri->scheme); g_string_append_printf (uri_str, "%s:", uri->scheme);
if (uri->userinfo != NULL || uri->host != NULL || if (uri->userinfo != NULL || uri->host != NULL ||
uri->port != GST_URI_NO_PORT) uri->port != GST_URI_NO_PORT || !g_strcmp0 (uri->scheme, "file")) {
g_string_append (uri_str, "//"); g_string_append (uri_str, "//");
}
if (uri->userinfo != NULL) { if (uri->userinfo != NULL) {
escaped = _gst_uri_escape_userinfo (uri->userinfo); escaped = _gst_uri_escape_userinfo (uri->userinfo);

View file

@ -227,129 +227,131 @@ struct URITest
struct QueryValue query[10]; struct QueryValue query[10];
const gchar *fragment; const gchar *fragment;
} uri; } uri;
gboolean check_to_str; // TRUE if this URI should reconstruct the original URI exactly
}; };
#define COMMON_URI_TESTS \ #define COMMON_URI_TESTS \
/* VALID URIS. PARSING AND PRINTING OF THESE SHOULD NOT CHANGE */ \ /* VALID URIS. PARSING AND PRINTING OF THESE SHOULD NOT CHANGE */ \
/* scheme/path */ \ /* scheme/path */ \
{"scheme:", \ {"scheme:", \
{"scheme", NULL, NULL, GST_URI_NO_PORT, NULL, {{NULL, NULL}}, NULL}}, \ {"scheme", NULL, NULL, GST_URI_NO_PORT, NULL, {{NULL, NULL}}, NULL}, TRUE }, \
{"scheme:path", \ {"scheme:path", \
{"scheme", NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}}, \ {"scheme", NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}, TRUE }, \
{"path", \ {"path", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}}, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}, TRUE }, \
{"/path", \ {"/path", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "/path", {{NULL, NULL}}, NULL}}, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "/path", {{NULL, NULL}}, NULL}, TRUE }, \
/* hostname/port */ \ /* hostname/port */ \
{"scheme://hostname/path", \ {"scheme://hostname/path", \
{"scheme", NULL, "hostname", GST_URI_NO_PORT, "/path", {{NULL, NULL}}, \ {"scheme", NULL, "hostname", GST_URI_NO_PORT, "/path", {{NULL, NULL}}, \
NULL}}, \ NULL}, TRUE }, \
{"scheme://hostname:123/path", \ {"scheme://hostname:123/path", \
{"scheme", NULL, "hostname", 123, "/path", {{NULL, NULL}}, NULL}}, \ {"scheme", NULL, "hostname", 123, "/path", {{NULL, NULL}}, NULL}, TRUE }, \
/* ipv6 hostname/port */ \ /* ipv6 hostname/port */ \
{"scheme://[01:23:45:67:89:ab:cd:ef]/path", \ {"scheme://[01:23:45:67:89:ab:cd:ef]/path", \
{"scheme", NULL, "01:23:45:67:89:ab:cd:ef", GST_URI_NO_PORT, "/path", \ {"scheme", NULL, "01:23:45:67:89:ab:cd:ef", GST_URI_NO_PORT, "/path", \
{{NULL, NULL}}, NULL}}, \ {{NULL, NULL}}, NULL}, TRUE }, \
{"scheme://[01:23:45:67:89:ab:cd:ef]:123/path", \ {"scheme://[01:23:45:67:89:ab:cd:ef]:123/path", \
{"scheme", NULL, "01:23:45:67:89:ab:cd:ef", 123, "/path", {{NULL, \ {"scheme", NULL, "01:23:45:67:89:ab:cd:ef", 123, "/path", {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
/* query/fragment */ \ /* query/fragment */ \
{"path?query", \ {"path?query", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
{"path?query=value", \ {"path?query=value", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", "value"}, {NULL, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", "value"}, {NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
{"path?query#fragment", \ {"path?query#fragment", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
{"path?query=value#fragment", \ {"path?query=value#fragment", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", "value"}, {NULL, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", "value"}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
{"scheme:path?query#fragment", \ {"scheme:path?query#fragment", \
{"scheme", NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL, \ {"scheme", NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
/* full */ \ /* full */ \
{"scheme://hostname:123/path?query#fragment", \ {"scheme://hostname:123/path?query#fragment", \
{"scheme", NULL, "hostname", 123, "/path", {{"query", NULL}, {NULL, \ {"scheme", NULL, "hostname", 123, "/path", {{"query", NULL}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
{"scheme://hostname:123/path?query=value#fragment", \ {"scheme://hostname:123/path?query=value#fragment", \
{"scheme", NULL, "hostname", 123, "/path", {{"query", "value"}, {NULL, \ {"scheme", NULL, "hostname", 123, "/path", {{"query", "value"}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
{"scheme://hostname:123?query", \ {"scheme://hostname:123?query", \
{"scheme", NULL, "hostname", 123, NULL, {{"query", NULL}, {NULL, \ {"scheme", NULL, "hostname", 123, NULL, {{"query", NULL}, {NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
{"scheme://hostname:123?query=value", \ {"scheme://hostname:123?query=value", \
{"scheme", NULL, "hostname", 123, NULL, {{"query", "value"}, {NULL, \ {"scheme", NULL, "hostname", 123, NULL, {{"query", "value"}, {NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
{"scheme://hostname:123?query#fragment", \ {"scheme://hostname:123?query#fragment", \
{"scheme", NULL, "hostname", 123, NULL, {{"query", NULL}, {NULL, \ {"scheme", NULL, "hostname", 123, NULL, {{"query", NULL}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
{"scheme://hostname:123?query=value#fragment", \ {"scheme://hostname:123?query=value#fragment", \
{"scheme", NULL, "hostname", 123, NULL, {{"query", "value"}, {NULL, \ {"scheme", NULL, "hostname", 123, NULL, {{"query", "value"}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, TRUE }, \
/* user/pass */ \ /* user/pass */ \
{"scheme://userinfo@hostname", \ {"scheme://userinfo@hostname", \
{"scheme", "userinfo", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \ {"scheme", "userinfo", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
{"scheme://userinfo@hostname:123/path?query#fragment", \ {"scheme://userinfo@hostname:123/path?query#fragment", \
{"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL}, \ {"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL}, \
{NULL, NULL}}, "fragment"}}, \ {NULL, NULL}}, "fragment"}, TRUE }, \
{"scheme://user:pass@hostname", \ {"scheme://user:pass@hostname", \
{"scheme", "user:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \ {"scheme", "user:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, TRUE }, \
{"scheme://user:pass@hostname:123/path?query#fragment", \ {"scheme://user:pass@hostname:123/path?query#fragment", \
{"scheme", "user:pass", "hostname", 123, "/path", {{"query", NULL}, \ {"scheme", "user:pass", "hostname", 123, "/path", {{"query", NULL}, \
{NULL, NULL}}, "fragment"}}, \ {NULL, NULL}}, "fragment"}, TRUE }, \
/* FUNNY URIS. PARSING AND PRINTING OF THESE MAY CHANGE */ \ /* FUNNY URIS. PARSING AND PRINTING OF THESE MAY CHANGE */ \
{"scheme:hostname:123/path?query#fragment", \ {"scheme:hostname:123/path?query#fragment", \
{"scheme", NULL, NULL, GST_URI_NO_PORT, "hostname:123/path", {{"query", \ {"scheme", NULL, NULL, GST_URI_NO_PORT, "hostname:123/path", {{"query", \
NULL}, {NULL, NULL}}, "fragment"}}, \ NULL}, {NULL, NULL}}, "fragment"}, FALSE }, \
{"scheme://:pass@hostname:123/path?query#fragment", \ {"scheme://:pass@hostname:123/path?query#fragment", \
{"scheme", ":pass", "hostname", 123, "/path", {{"query", NULL}, {NULL, \ {"scheme", ":pass", "hostname", 123, "/path", {{"query", NULL}, {NULL, \
NULL}}, "fragment"}}, \ NULL}}, "fragment"}, FALSE }, \
/* Skip initial white space */ \ /* Skip initial white space */ \
{" \f\n\r\t\vscheme:", \ {" \f\n\r\t\vscheme:", \
{"scheme", NULL, NULL, GST_URI_NO_PORT, NULL, {{NULL, NULL}}, NULL}}, \ {"scheme", NULL, NULL, GST_URI_NO_PORT, NULL, {{NULL, NULL}}, NULL}, FALSE }, \
{" \f\n\r\t\vpath", \ {" \f\n\r\t\vpath", \
{NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}}, \ {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}, FALSE }, \
/* file URI */ \ /* file URI */ \
{"file://host/home/joe/foo.txt", \ {"file://host/home/joe/foo.txt", \
{"file", NULL, "host", GST_URI_NO_PORT, "/home/joe/foo.txt", {{NULL, \ {"file", NULL, "host", GST_URI_NO_PORT, "/home/joe/foo.txt", {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, FALSE }, \
{"file:///home/joe/foo.txt", \ {"file:///home/joe/foo.txt", \
{"file", NULL, NULL, GST_URI_NO_PORT, "/home/joe/foo.txt", {{NULL, \ {"file", NULL, NULL, GST_URI_NO_PORT, "/home/joe/foo.txt", {{NULL, \
NULL}}, NULL}}, NULL}}, NULL}, TRUE },
#define UNESCAPED_URI_TESTS \ #define UNESCAPED_URI_TESTS \
/* Test cases for gst_uri_from_string */ \ /* Test cases for gst_uri_from_string */ \
{"scheme://user%20info@hostname", \ {"scheme://user%20info@hostname", \
{"scheme", "user info", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \ {"scheme", "user info", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, FALSE }, \
{"scheme://userinfo@hostname:123/path?query#frag%23ment", \ {"scheme://userinfo@hostname:123/path?query#frag%23ment", \
{"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL}, \ {"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL}, \
{NULL, NULL}}, "frag#ment"}}, \ {NULL, NULL}}, "frag#ment"}, FALSE }, \
{"scheme://us%3Aer:pass@hostname", \ {"scheme://us%3Aer:pass@hostname", \
{"scheme", "us:er:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \ {"scheme", "us:er:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, FALSE }, \
{"scheme://us%3Aer:pa%3Ass@hostname:123/path?query#frag%23ment", \ {"scheme://us%3Aer:pa%3Ass@hostname:123/path?query#frag%23ment", \
{"scheme", "us:er:pa:ss", "hostname", 123, "/path", {{"query", NULL}, \ {"scheme", "us:er:pa:ss", "hostname", 123, "/path", {{"query", NULL}, \
{NULL, NULL}}, "frag#ment"}}, {NULL, NULL}}, "frag#ment"}, FALSE },
#define ESCAPED_URI_TESTS \ #define ESCAPED_URI_TESTS \
/* Test cases for gst_uri_from_string_escaped */ \ /* Test cases for gst_uri_from_string_escaped */ \
{"scheme://user%20info@hostname", \ {"scheme://user%20info@hostname", \
{"scheme", "user%20info", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \ {"scheme", "user%20info", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, FALSE }, \
{"scheme://userinfo@hostname:123/path?query#frag%23ment", \ {"scheme://userinfo@hostname:123/path?query#frag%23ment", \
{"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL}, \ {"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL}, \
{NULL, NULL}}, "frag%23ment"}}, \ {NULL, NULL}}, "frag%23ment"}, FALSE }, \
{"scheme://us%3Aer:pass@hostname", \ {"scheme://us%3Aer:pass@hostname", \
{"scheme", "us%3Aer:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \ {"scheme", "us%3Aer:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL, \
NULL}}, NULL}}, \ NULL}}, NULL}, FALSE }, \
{"scheme://us%3Aer:pa%3Ass@hostname:123/path?query#frag%23ment", \ {"scheme://us%3Aer:pa%3Ass@hostname:123/path?query#frag%23ment", \
{"scheme", "us%3Aer:pa%3Ass", "hostname", 123, "/path", {{"query", NULL}, \ {"scheme", "us%3Aer:pa%3Ass", "hostname", 123, "/path", {{"query", NULL}, \
{NULL, NULL}}, "frag%23ment"}}, {NULL, NULL}}, "frag%23ment"}, FALSE },
static const struct URITest tests[] = { static const struct URITest tests[] = {
@ -1227,6 +1229,36 @@ GST_START_TEST (test_url_unescape_equals_in_http_query)
GST_END_TEST; GST_END_TEST;
GST_START_TEST (test_url_to_string)
{
GstUri *uri;
guint i;
for (i = 0; i < G_N_ELEMENTS (tests); i++) {
if (!tests[i].check_to_str) {
continue;
}
GST_DEBUG ("Testing URI '%s'", tests[i].str);
uri = gst_uri_from_string (tests[i].str);
fail_unless (uri != NULL);
/* Test that these URIs reconstruct to the original string */
GList *keys = gst_uri_get_query_keys (uri);
gchar *out_uri = gst_uri_to_string_with_keys (uri, keys);
fail_unless (out_uri != NULL);
fail_unless_equals_string (out_uri, tests[i].str);
g_list_free (keys);
g_free (out_uri);
gst_uri_unref (uri);
}
}
GST_END_TEST;
static Suite * static Suite *
gst_uri_suite (void) gst_uri_suite (void)
{ {
@ -1256,6 +1288,7 @@ gst_uri_suite (void)
tcase_add_test (tc_chain, test_url_get_set); tcase_add_test (tc_chain, test_url_get_set);
tcase_add_test (tc_chain, test_url_get_media_fragment_table); tcase_add_test (tc_chain, test_url_get_media_fragment_table);
tcase_add_test (tc_chain, test_url_unescape_equals_in_http_query); tcase_add_test (tc_chain, test_url_unescape_equals_in_http_query);
tcase_add_test (tc_chain, test_url_to_string);
return s; return s;
} }