urlapi: fix an issue parsing file URLs

Fixes #21743
Closes #21764
This commit is contained in:
tiymat 2026-05-27 00:44:31 -02:30 committed by Daniel Stenberg
parent e2ca8408c4
commit f1959ae962
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 16 additions and 2 deletions

View file

@ -876,13 +876,19 @@ UNITTEST CURLUcode parse_file(const char *url, size_t urllen, CURLU *u,
path = &url[5];
pathlen = urllen - 5;
/* RFC 8089: file-hier-part = ( "//" auth-path ) / local-path, where
local-path also starts with a "/". So reject anything that doesn't
start with at least one "/" */
if(path[0] != '/')
return CURLUE_BAD_FILE_URL;
/* Extra handling URLs with an authority component (i.e. that start with
* "file://")
*
* We allow omitted hostname (e.g. file:/<path>) -- valid according to
* RFC 8089, but not the (current) WHAT-WG URL spec.
*/
if(path[0] == '/' && path[1] == '/') {
if(path[1] == '/') {
/* swallow the two slashes */
const char *ptr = &path[2];

View file

@ -886,7 +886,11 @@ static const struct urltestcase get_url_list[] = {
{"file:///.", "file:///", 0, 0, CURLUE_OK},
{"file:///./", "file:///", 0, 0, CURLUE_OK},
{"file:///a", "file:///a", 0, 0, CURLUE_OK},
{"file:./", "file://", 0, 0, CURLUE_OK},
{"file:./", "", 0, 0, CURLUE_BAD_FILE_URL},
{"file:foo", "", 0, 0, CURLUE_BAD_FILE_URL},
{"file:foo/bar", "", 0, 0, CURLUE_BAD_FILE_URL},
{"file:?q", "", 0, 0, CURLUE_BAD_FILE_URL},
{"file:#f", "", 0, 0, CURLUE_BAD_FILE_URL},
{"http://example.com/hello/../here",
"http://example.com/hello/../here",
CURLU_PATH_AS_IS, 0, CURLUE_OK},

View file

@ -267,6 +267,10 @@ static CURLcode test_unit1675(const char *arg)
{"file:///etc/hosts", "/etc/hosts", TRUE},
{"file://localhost/etc/hosts", "/etc/hosts", TRUE},
{"file://apple/etc/hosts", "/etc/hosts", FALSE},
{"file:foo", NULL, FALSE},
{"file:./", NULL, FALSE},
{"file:?q", NULL, FALSE},
{"file:#f", NULL, FALSE},
#ifdef _WIN32
{"file:///c:/windows/system32", "c:/windows/system32", TRUE},
{"file://localhost/c:/windows/system32", "c:/windows/system32", TRUE},