Skip to content

Commit

Permalink
Accept UNC path without share-name
Browse files Browse the repository at this point in the history
Windows File Explorer accepts such UNC paths, and Chrome and Firefox
convert them to file URLs.

Example of conversion: `\\host-name` -> `file://host-name/`
  • Loading branch information
rmisev committed Sep 3, 2024
1 parent f8237d5 commit aa55b33
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
2 changes: 2 additions & 0 deletions include/upa/url.h
Original file line number Diff line number Diff line change
Expand Up @@ -3050,6 +3050,8 @@ inline const CharT* is_unc_path(const CharT* first, const CharT* last)
return nullptr;
break;
}
// Accept UNC path with hostname, even if it does not contain share-name
end_of_share_name = pcend;
break;
case 2:
// Check the second UNC path component (share name).
Expand Down
20 changes: 13 additions & 7 deletions test/test-url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,9 @@ TEST_CASE("url_from_file_path") {
// UNC: IPv4 and IPv6 hostnames
CHECK(upa::url_from_file_path("\\\\127.0.0.1\\path", upa::file_path_format::windows).href() == "file://127.0.0.1/path");
CHECK(upa::url_from_file_path("\\\\[::1]\\path", upa::file_path_format::windows).href() == "file://[::1]/path");
// UNC: without share-name
CHECK(upa::url_from_file_path("\\\\h", upa::file_path_format::windows).href() == "file://h/");
CHECK(upa::url_from_file_path("\\\\h\\", upa::file_path_format::windows).href() == "file://h/");
// Win32 file and device namespaces
// https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
// https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
Expand All @@ -686,8 +689,6 @@ TEST_CASE("url_from_file_path") {
CHECK_THROWS_AS(upa::url_from_file_path("C|/path", upa::file_path_format::windows), upa::url_error);
// invalid UNC
CHECK_THROWS_AS(upa::url_from_file_path("\\\\", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\h", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\h\\", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\h\\\\", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\h\\.", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\h\\..", upa::file_path_format::windows), upa::url_error);
Expand Down Expand Up @@ -766,11 +767,16 @@ TEST_CASE("path_from_file_url") {
// UNC: IPv4 and IPv6 hostnames
CHECK(path_from_file_url("file://127.0.0.1/path", upa::file_path_format::windows) == "\\\\127.0.0.1\\path");
CHECK(path_from_file_url("file://[::1]/path", upa::file_path_format::windows) == "\\\\--1.ipv6-literal.net\\path");
// Invalid UNC
CHECK_THROWS_AS(path_from_file_url("file://host", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(path_from_file_url("file://host/", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(path_from_file_url("file:////host/", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(path_from_file_url("file://///host/", upa::file_path_format::windows), upa::url_error);
// UNC: without share-name
CHECK(path_from_file_url("file://host/", upa::file_path_format::windows) == "\\\\host\\");
CHECK(path_from_file_url("file:////host", upa::file_path_format::windows) == "\\\\host");
CHECK(path_from_file_url("file:////host/", upa::file_path_format::windows) == "\\\\host\\");
CHECK(path_from_file_url("file://///host", upa::file_path_format::windows) == "\\\\host");
CHECK(path_from_file_url("file://///host/", upa::file_path_format::windows) == "\\\\host\\");
// Invalid UNC: empty share-name
CHECK_THROWS_AS(path_from_file_url("file://host//", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(path_from_file_url("file:////host//", upa::file_path_format::windows), upa::url_error);
CHECK_THROWS_AS(path_from_file_url("file://///host//", upa::file_path_format::windows), upa::url_error);
// Unsupported "." hostname
CHECK_THROWS_AS(path_from_file_url("file://./name", upa::file_path_format::windows), upa::url_error);
// null character
Expand Down

0 comments on commit aa55b33

Please sign in to comment.