From 6acae15f2fc824a32f9a376d2a80356577ad4060 Mon Sep 17 00:00:00 2001 From: Kostiantyn Syrykh <cs.this@gmail.com> Date: Thu, 9 Jan 2025 20:12:22 +0200 Subject: [PATCH] url: parse link-local IPv6 zone identifier Parse URLs like "http://[fe80::1%25eth0]" (ref. RFC 6874). --- src/test/url.c | 3 +++ src/text/url.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/test/url.c b/src/test/url.c index 4c12809afa09..9351ce9ccc3b 100644 --- a/src/test/url.c +++ b/src/test/url.c @@ -277,6 +277,8 @@ int main (void) "/", NULL); test_url_parse("http://[2001:db8::1]", "http", NULL, NULL, "2001:db8::1", 0, NULL, NULL); + test_url_parse("http://[fe80::1%25eth0]", "http", NULL, NULL, "fe80::1%eth0", + 0, NULL, NULL); test_url_parse("http://example.com:", "http", NULL, NULL, "example.com", 0, NULL, NULL); test_url_parse("protocol://john:doe@1.2.3.4:567", "protocol", "john", "doe", "1.2.3.4", 567, NULL, NULL); @@ -321,6 +323,7 @@ int main (void) test_url_parse("http://example.com:-18446744073709551615", NULL, NULL, NULL, NULL, 0, NULL, NULL ); test_url_parse("http://user%/Oath", "http", NULL, NULL, NULL, 0, "/Oath", NULL); + test_url_parse("http://[2001::1%25eth0]", NULL, NULL, NULL, NULL, 0, NULL, NULL); /* URIs to fixup */ test_url_parse("smb://SERVER:445/SHARE/My file.mp3", "smb", NULL, NULL, "SERVER", 445, NULL, NULL); diff --git a/src/text/url.c b/src/text/url.c index 30c61b49552c..250e5be2538b 100644 --- a/src/text/url.c +++ b/src/text/url.c @@ -422,6 +422,11 @@ static bool vlc_uri_component_validate(const char *str, const char *extras) static bool vlc_uri_host_validate(const char *str) { + // Only link-Local IPv6 addresses can have a zone identifier + if (!strncasecmp(str, "fe80:", 5)) { + return vlc_uri_component_validate(str, ":%"); + } + return vlc_uri_component_validate(str, ":"); } @@ -524,7 +529,7 @@ static int vlc_UrlParseInner(vlc_url_t *restrict url, const char *str) if (*cur == '[' && (next = strrchr(cur, ']')) != NULL) { /* Try IPv6 numeral within brackets */ *(next++) = '\0'; - url->psz_host = strdup(cur + 1); + url->psz_host = vlc_uri_decode_duplicate(cur + 1); if (*next == ':') next++; -- GitLab