[libcxx] Sanitize paths before creating symlinks on windows

The MS STL does even more cleanup (corresponding to lexically_normal
I think), but this seems to be the very minimum needed for making the
symlinks work when the target path contains non-native paths.

Differential Revision: https://reviews.llvm.org/D91145
This commit is contained in:
Martin Storsjö 2020-11-09 15:20:18 +02:00
parent efec3cc652
commit f65ba25cf3
2 changed files with 23 additions and 0 deletions

View File

@ -202,6 +202,9 @@ int mkdir(const wchar_t *path, int permissions) {
int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
bool is_dir) {
path dest(oldname);
dest.make_preferred();
oldname = dest.c_str();
DWORD flags = is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
if (CreateSymbolicLinkW(newname, oldname,
flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))

View File

@ -71,5 +71,25 @@ TEST_CASE(create_symlink_basic)
}
}
TEST_CASE(create_symlink_dest_cleanup)
{
scoped_test_env env;
const path dir = env.create_dir("dir");
const path file = env.create_file("file", 42);
const path sym = dir / "link";
// The target path has to be normalized to backslashes before creating
// the link on windows, otherwise the link isn't dereferencable.
const path sym_target = "../file";
path sym_target_normalized = sym_target;
sym_target_normalized.make_preferred();
std::error_code ec;
fs::create_symlink(sym_target, sym, ec);
TEST_REQUIRE(!ec);
TEST_CHECK(equivalent(sym, file, ec));
const path ret = fs::read_symlink(sym, ec);
TEST_CHECK(!ec);
TEST_CHECK(ret.native() == sym_target_normalized.native());
}
TEST_SUITE_END()