Skip to content

Commit

Permalink
Disallow "?" and "." hostnames in UNC paths
Browse files Browse the repository at this point in the history
Because "\\?\" means Win32 file namespace and "\\.\" means Win32 device
namespace.
  • Loading branch information
rmisev committed Nov 25, 2023
1 parent 1e1195a commit 443d7c2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
25 changes: 17 additions & 8 deletions include/upa/url.h
Original file line number Diff line number Diff line change
Expand Up @@ -2967,13 +2967,22 @@ inline bool is_unc_path(const CharT* first, const CharT* last)

++path_components_count;

// Do not accept a Windows drive letter from the first UNC path
// component, because it is not a valid host name
if (path_components_count == 1 &&
pcend - start == 2 &&
detail::is_windows_drive(start[0], start[1]))
return false;

// Check the first UNC path component (hostname)
if (path_components_count == 1) {
switch (pcend - start) {
case 1:
// Do not allow "?" and "." hostnames, because "\\?\" means Win32 file
// namespace and "\\.\" means Win32 device namespace
if (start[0] == '?' || start[0] == '.')
return false;
break;
case 2:
// Do not allow Windows drive letter, because it is not a valid hostname
if (detail::is_windows_drive(start[0], start[1]))
return false;
break;
}
}
if (pcend == last) break;
start = pcend + 1; // skip '\'
}
Expand Down Expand Up @@ -3129,7 +3138,7 @@ inline std::string path_from_file_url(const url& file_url, file_path_format form
} else {
// format == file_path_format::windows
if (is_host) {
// UNC path cannot have "." hostname, because "\\.\" means DOS devices namespace
// UNC path cannot have "." hostname, because "\\.\" means Win32 device namespace
if (hostname == ".")
throw url_error(validation_errc::file_url_unsupported_host, "UNC path cannot have \".\" hostname");
// UNC path
Expand Down
2 changes: 2 additions & 0 deletions test/test-url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,8 @@ TEST_CASE("url_from_file_path") {
CHECK_THROWS_AS(upa::url_from_file_path(std::string{ '\\', '\\', 'h', '\\', 'a', '\0', 'b' }), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\C:\\path"), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\C|\\path"), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\?\\UNC\\?\\name"), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\?\\UNC\\.\\name"), upa::url_error);
// invalid hostname
CHECK_THROWS_AS(upa::url_from_file_path("\\\\a b\\path"), upa::url_error);
// unsupported pathes
Expand Down

0 comments on commit 443d7c2

Please sign in to comment.