[libcxx-commits] [libcxx] f65ba25 - [libcxx] Sanitize paths before creating symlinks on windows

Martin Storsjö via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 29 03:40:04 PST 2021


Author: Martin Storsjö
Date: 2021-01-29T13:39:30+02:00
New Revision: f65ba25cf37a57dc87db7af389c9dc637ca7dd8c

URL: https://github.com/llvm/llvm-project/commit/f65ba25cf37a57dc87db7af389c9dc637ca7dd8c
DIFF: https://github.com/llvm/llvm-project/commit/f65ba25cf37a57dc87db7af389c9dc637ca7dd8c.diff

LOG: [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

Added: 
    

Modified: 
    libcxx/src/filesystem/posix_compat.h
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h
index 1e70e12cb4d7..0dbae1235a00 100644
--- a/libcxx/src/filesystem/posix_compat.h
+++ b/libcxx/src/filesystem/posix_compat.h
@@ -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))

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
index 47ec916a169b..3b54cff309b7 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp
@@ -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()


        


More information about the libcxx-commits mailing list