Fix appending to host-only UNC paths by inserting missing separator (#191)

This commit is contained in:
Steffen Schümann 2026-07-11 16:09:44 +02:00
parent 87157acd6c
commit 4d2f630892
3 changed files with 17 additions and 1 deletions

View File

@ -651,6 +651,8 @@ to the expected behavior.
* Fix for [#203](https://github.com/gulrak/filesystem/issues/203), directory * Fix for [#203](https://github.com/gulrak/filesystem/issues/203), directory
iteration and `proximate()` are available in builds without exception iteration and `proximate()` are available in builds without exception
support, with iteration errors terminating the process. support, with iteration errors terminating the process.
* Fix for [#191](https://github.com/gulrak/filesystem/issues/191), appending
to a host-only UNC path now inserts the missing separator.
* Fix for [#185](https://github.com/gulrak/filesystem/issues/185), * Fix for [#185](https://github.com/gulrak/filesystem/issues/185),
`lexically_normal()` now preserves unresolved parent components in relative `lexically_normal()` now preserves unresolved parent components in relative
paths. paths.

View File

@ -2623,10 +2623,16 @@ GHC_INLINE path& path::operator/=(const path& p)
assign(p); assign(p);
return *this; return *this;
} }
bool isHostOnlyUncPath = false;
#ifdef GHC_OS_WINDOWS
const auto rootNameLength = root_name_length();
isHostOnlyUncPath = rootNameLength == _path.length() && rootNameLength > _prefixLength + 2 &&
_path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator;
#endif
if (p.has_root_directory()) { if (p.has_root_directory()) {
assign(root_name()); assign(root_name());
} }
else if ((!has_root_directory() && is_absolute()) || has_filename()) { else if ((!has_root_directory() && is_absolute()) || has_filename() || isHostOnlyUncPath) {
_path += preferred_separator; _path += preferred_separator;
} }
auto iter = p.begin(); auto iter = p.begin();

View File

@ -490,6 +490,14 @@ TEST_CASE("fs.path.append - path appends", "[filesystem][path][fs.path.append]")
CHECK(fs::path("c:") / "" == "c:"); CHECK(fs::path("c:") / "" == "c:");
CHECK(fs::path("c:foo") / "/bar" == "c:/bar"); CHECK(fs::path("c:foo") / "/bar" == "c:/bar");
CHECK(fs::path("c:foo") / "c:bar" == "c:foo/bar"); CHECK(fs::path("c:foo") / "c:bar" == "c:foo/bar");
CHECK(fs::path(R"(\\server)") / "abc" == R"(\\server\abc)");
CHECK(fs::path(R"(\\server)") / "" == R"(\\server\)");
CHECK(fs::path(R"(\\server\)") / "abc" == R"(\\server\abc)");
CHECK(fs::path(R"(\\server\share)") / "abc" == R"(\\server\share\abc)");
CHECK(fs::path(R"(\\server)") / R"(\abc)" == R"(\\server\abc)");
CHECK(fs::path("c:") / "abc" == "c:abc");
CHECK(fs::path(R"(c:\)") / "abc" == R"(c:\abc)");
CHECK(fs::path(R"(\rooted)") / "abc" == R"(\rooted\abc)");
#else #else
CHECK(fs::path("foo") / "" == "foo/"); CHECK(fs::path("foo") / "" == "foo/");
CHECK(fs::path("foo") / "/bar" == "/bar"); CHECK(fs::path("foo") / "/bar" == "/bar");