[libcxx-commits] [libcxx] [libc++] Fix different slashes confuses lexically_proximate and lexically_relative (PR #99780)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 20 12:37:23 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: RichardLuo (RichardLuo0)

<details>
<summary>Changes</summary>

```cpp
#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;
using path = fs::path;

int main() {
  path p("C:/Users/xxx/program/something.json");
  for (const auto &f : p)
    std::cout << f << std::endl;
  std::cout << p << std::endl;
  path p2("C:\\Users\\xxx\\program");
  for (const auto &f : p2)
    std::cout << f << std::endl;
  std::cout << p.lexically_proximate(p2) << std::endl;
  std::cout << p.make_preferred().lexically_proximate(p2) << std::endl;
}
```
The above code produces the following result on Windows:
```
"C:"
"/"
"Users"
"xxx"
"program"
"something.json"
"C:/Users/xxx/program/something.json"
"C:"
"\\"
"Users"
"xxx"
"program"
"/Users\\xxx\\program\\something.json"
"something.json"
```

lexically_proximate thinks that the second folder (the root) is different. However, they are seen as the same thing on windows.
This also raises another issue: lexically_proximate returns an absolute path when it should return a relative one.

I think we have two solutions:
1. As my PR proposed, make PS_InRootDir always return "/". If you look at https://en.cppreference.com/w/cpp/filesystem/path/begin. Their example has the same behavior. It also prevents other potential issues and saves users time in dealing with different slashes for root dir. But I don't know if this is standard or if this causes other issues.
2. Change the implementation of lexically_relative(). Take special care of the PS_InRootDir state.

---
Full diff: https://github.com/llvm/llvm-project/pull/99780.diff


1 Files Affected:

- (modified) libcxx/src/filesystem/path_parser.h (+1-4) 


``````````diff
diff --git a/libcxx/src/filesystem/path_parser.h b/libcxx/src/filesystem/path_parser.h
index 06623696452da..b38df13a3f7df 100644
--- a/libcxx/src/filesystem/path_parser.h
+++ b/libcxx/src/filesystem/path_parser.h
@@ -174,10 +174,7 @@ struct PathParser {
     case PS_AtEnd:
       return PATHSTR("");
     case PS_InRootDir:
-      if (RawEntry[0] == '\\')
-        return PATHSTR("\\");
-      else
-        return PATHSTR("/");
+      return PATHSTR("/");
     case PS_InTrailingSep:
       return PATHSTR("");
     case PS_InRootName:

``````````

</details>


https://github.com/llvm/llvm-project/pull/99780


More information about the libcxx-commits mailing list