<filesystem>: `weakly_canonical` fails for UNC path with `\\?\UNC` prefix
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
Describe the bug
std::filesystem::weakly_canonical fails for UNC path with \\?\UNC prefix.
Command-line test case
C:\Users\manx\stuff>type weakly_canonical.cpp
#include <filesystem>
#include <iostream>
int main() {
try {
std::wcout << std::filesystem::weakly_canonical(L"\\\\?\\UNC\\server\\share\\dir\\name.ext").wstring() << std::endl;
} catch (const std::exception & e) {
std::wcout << std::flush;
std::cerr << e.what() << std::endl;
}
return 0;
}
C:\Users\manx\stuff>cl /std:c++20 /permissive- /EHsc /O2 /W4 weakly_canonical.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.32.31332 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
weakly_canonical.cpp
Microsoft (R) Incremental Linker Version 14.32.31332.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:weakly_canonical.exe
weakly_canonical.obj
C:\Users\manx\stuff>weakly_canonical.exe
weakly_canonical: Incorrect function.: "\\?\UNC\server\share\dir\name.ext"
C:\Users\manx\stuff>
(https://godbolt.org/z/v83fbPfrW)
Expected behavior
weakly_canonical does work for plain UNC paths without \\?\UNC prefix, so I think it should also work for prefixed ones:
#include <filesystem>
#include <iostream>
void show(std::filesystem::path p) {
std::wcout << L"path: " << p.wstring() << std::endl;
std::wcout << L" absolute: " << std::filesystem::absolute(p).wstring() << std::endl;
std::wcout << L" canonical: " << std::filesystem::weakly_canonical(p).wstring() << std::endl;
std::wcout << L" root name " << p.root_name().wstring() << std::endl;
std::wcout << L" root directory " << p.root_directory().wstring() << std::endl;
std::wcout << L" relative path " << p.relative_path().wstring() << std::endl;
}
int main() {
try {
show(std::filesystem::current_path());
show(L"C:\\dir\\name.ext");
show(L"\\\\.\\C:\\dir\\name.ext");
show(L"\\\\?\\C:\\dir\\name.ext");
show(L"\\\\server\\share\\dir\\name.ext");
show(L"\\\\?\\UNC\\server\\share\\dir\\name.ext");
} catch (const std::exception & e) {
std::wcout << std::flush;
std::cerr << e.what() << std::endl;
}
return 0;
}
(https://godbolt.org/z/rEdMvWs7h)
https://github.com/microsoft/STL/blob/7f04137880e1c3df5125c1baf808f16f399dee2e/stl/inc/filesystem#L420 talks about this prefix, so I would assume std::filesystem to be aware of it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the filesystem implementation at stl/inc/filesystem#L420 and reproduce the command-line example on Windows using the prefixed UNC path. Compare its handling with plain UNC paths and the other prefixes shown in the second example. Done means weakly_canonical accepts the \?\UNC path without the reported error and returns the expected canonical form.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100