mirror of
https://git.mirrors.martin98.com/https://github.com/gulrak/filesystem
synced 2025-07-21 23:54:26 +08:00
Fix in canonical root path handling.
This commit is contained in:
parent
1cd346d23e
commit
f96b65562d
@ -1258,8 +1258,7 @@ namespace detail {
|
|||||||
|
|
||||||
GHC_INLINE bool startsWith(const std::string& what, const std::string& with)
|
GHC_INLINE bool startsWith(const std::string& what, const std::string& with)
|
||||||
{
|
{
|
||||||
return with.length() <= what.length()
|
return with.length() <= what.length() && equal(with.begin(), with.end(), what.begin());
|
||||||
&& equal(with.begin(), with.end(), what.begin());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GHC_INLINE void postprocess_path_with_format(path::string_type& p, path::format fmt)
|
GHC_INLINE void postprocess_path_with_format(path::string_type& p, path::format fmt)
|
||||||
@ -1276,11 +1275,11 @@ GHC_INLINE void postprocess_path_with_format(path::string_type& p, path::format
|
|||||||
case path::auto_format:
|
case path::auto_format:
|
||||||
case path::native_format:
|
case path::native_format:
|
||||||
#endif
|
#endif
|
||||||
if(startsWith(p, std::string("\\\\?\\"))) {
|
if (startsWith(p, std::string("\\\\?\\"))) {
|
||||||
// remove Windows long filename marker
|
// remove Windows long filename marker
|
||||||
p.erase(0, 4);
|
p.erase(0, 4);
|
||||||
if(startsWith(p, std::string("UNC\\"))) {
|
if (startsWith(p, std::string("UNC\\"))) {
|
||||||
p.erase(0,2);
|
p.erase(0, 2);
|
||||||
p[0] = '\\';
|
p[0] = '\\';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2085,9 +2084,9 @@ GHC_INLINE void path::swap(path& rhs) noexcept
|
|||||||
GHC_INLINE const path::string_type& path::native() const
|
GHC_INLINE const path::string_type& path::native() const
|
||||||
{
|
{
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
if(is_absolute() && _path.length() > MAX_PATH-10) {
|
if (is_absolute() && _path.length() > MAX_PATH - 10) {
|
||||||
// expand long Windows filenames with marker
|
// expand long Windows filenames with marker
|
||||||
if(has_root_name() && _path[0] == '/') {
|
if (has_root_name() && _path[0] == '/') {
|
||||||
_native_cache = "\\\\?\\UNC" + _path.substr(1);
|
_native_cache = "\\\\?\\UNC" + _path.substr(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2856,7 +2855,10 @@ GHC_INLINE path canonical(const path& p, std::error_code& ec)
|
|||||||
result = result.parent_path();
|
result = result.parent_path();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if ((result/pe).string().length() <= root.string().length()) {
|
||||||
|
result /= pe;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto sls = symlink_status(result / pe, ec);
|
auto sls = symlink_status(result / pe, ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
return path();
|
return path();
|
||||||
@ -3708,8 +3710,7 @@ GHC_INLINE void permissions(const path& p, perms prms, perm_options opts, std::e
|
|||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
# ifdef __GNUC__
|
# ifdef __GNUC__
|
||||||
auto oldAttr = GetFileAttributesW(p.wstring().c_str());
|
auto oldAttr = GetFileAttributesW(p.wstring().c_str());
|
||||||
if (oldAttr != INVALID_FILE_ATTRIBUTES)
|
if (oldAttr != INVALID_FILE_ATTRIBUTES) {
|
||||||
{
|
|
||||||
DWORD newAttr = ((prms & perms::owner_write) == perms::owner_write) ? oldAttr & ~FILE_ATTRIBUTE_READONLY : oldAttr | FILE_ATTRIBUTE_READONLY;
|
DWORD newAttr = ((prms & perms::owner_write) == perms::owner_write) ? oldAttr & ~FILE_ATTRIBUTE_READONLY : oldAttr | FILE_ATTRIBUTE_READONLY;
|
||||||
if (oldAttr == newAttr || SetFileAttributesW(p.wstring().c_str(), newAttr)) {
|
if (oldAttr == newAttr || SetFileAttributesW(p.wstring().c_str(), newAttr)) {
|
||||||
return;
|
return;
|
||||||
|
@ -177,13 +177,11 @@ static void generateFile(const fs::path& pathname, int withSize = -1)
|
|||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
inline bool isWow64Proc()
|
inline bool isWow64Proc()
|
||||||
{
|
{
|
||||||
typedef BOOL (WINAPI *IsWow64Process_t) (HANDLE, PBOOL);
|
typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL);
|
||||||
BOOL bIsWow64 = FALSE;
|
BOOL bIsWow64 = FALSE;
|
||||||
auto fnIsWow64Process = (IsWow64Process_t)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
|
auto fnIsWow64Process = (IsWow64Process_t)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
|
||||||
if( NULL != fnIsWow64Process )
|
if (NULL != fnIsWow64Process) {
|
||||||
{
|
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
|
||||||
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
|
|
||||||
{
|
|
||||||
bIsWow64 = FALSE;
|
bIsWow64 = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +190,7 @@ inline bool isWow64Proc()
|
|||||||
|
|
||||||
static bool is_symlink_creation_supported()
|
static bool is_symlink_creation_supported()
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = true;
|
||||||
HKEY key;
|
HKEY key;
|
||||||
REGSAM flags = KEY_READ;
|
REGSAM flags = KEY_READ;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
@ -207,7 +205,7 @@ static bool is_symlink_creation_supported()
|
|||||||
#else
|
#else
|
||||||
result = false;
|
result = false;
|
||||||
#endif
|
#endif
|
||||||
if(result) {
|
if (result) {
|
||||||
auto err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", 0, flags, &key);
|
auto err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", 0, flags, &key);
|
||||||
if (err == ERROR_SUCCESS) {
|
if (err == ERROR_SUCCESS) {
|
||||||
DWORD val = 0, size = sizeof(DWORD);
|
DWORD val = 0, size = sizeof(DWORD);
|
||||||
@ -224,7 +222,7 @@ static bool is_symlink_creation_supported()
|
|||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!result) {
|
if (!result) {
|
||||||
std::clog << "Warning: Symlink creation not supported." << std::endl;
|
std::clog << "Warning: Symlink creation not supported." << std::endl;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -1274,7 +1272,7 @@ TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]")
|
|||||||
CHECK(fs::exists("dir4/file2"));
|
CHECK(fs::exists("dir4/file2"));
|
||||||
CHECK(fs::exists("dir4/dir2/file3"));
|
CHECK(fs::exists("dir4/dir2/file3"));
|
||||||
}
|
}
|
||||||
if(is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::create_directory("dir1");
|
fs::create_directory("dir1");
|
||||||
@ -1455,7 +1453,7 @@ TEST_CASE("30.10.15.7 create_directory", "[filesystem][operations][fs.op.create_
|
|||||||
|
|
||||||
TEST_CASE("30.10.15.8 create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]")
|
TEST_CASE("30.10.15.8 create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]")
|
||||||
{
|
{
|
||||||
if(is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
fs::create_directory(t.path() / "dir1");
|
fs::create_directory(t.path() / "dir1");
|
||||||
generateFile(t.path() / "dir1/test1");
|
generateFile(t.path() / "dir1/test1");
|
||||||
@ -1491,7 +1489,7 @@ TEST_CASE("30.10.15.9 create_hard_link", "[filesystem][operations][fs.op.create_
|
|||||||
|
|
||||||
TEST_CASE("30.10.15.10 create_symlink", "[filesystem][operations][fs.op.create_symlink]")
|
TEST_CASE("30.10.15.10 create_symlink", "[filesystem][operations][fs.op.create_symlink]")
|
||||||
{
|
{
|
||||||
if(is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t;
|
TemporaryDirectory t;
|
||||||
fs::create_directory(t.path() / "dir1");
|
fs::create_directory(t.path() / "dir1");
|
||||||
generateFile(t.path() / "dir1/test1");
|
generateFile(t.path() / "dir1/test1");
|
||||||
@ -2066,7 +2064,7 @@ TEST_CASE("30.10.15.27 proximate", "[filesystem][operations][fs.op.proximate]")
|
|||||||
|
|
||||||
TEST_CASE("30.10.15.28 read_symlink", "[filesystem][operations][fs.op.read_symlink]")
|
TEST_CASE("30.10.15.28 read_symlink", "[filesystem][operations][fs.op.read_symlink]")
|
||||||
{
|
{
|
||||||
if(is_symlink_creation_supported()) {
|
if (is_symlink_creation_supported()) {
|
||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
generateFile("foo");
|
generateFile("foo");
|
||||||
@ -2307,15 +2305,15 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long
|
|||||||
TemporaryDirectory t(TempOpt::change_path);
|
TemporaryDirectory t(TempOpt::change_path);
|
||||||
char c = 'A';
|
char c = 'A';
|
||||||
fs::path dir = fs::current_path();
|
fs::path dir = fs::current_path();
|
||||||
for( ; c <= 'Z'; ++c) {
|
for (; c <= 'Z'; ++c) {
|
||||||
std::string part = std::string(16, c);
|
std::string part = std::string(16, c);
|
||||||
dir /= part;
|
dir /= part;
|
||||||
CHECK_NOTHROW(fs::create_directory(dir));
|
CHECK_NOTHROW(fs::create_directory(dir));
|
||||||
CHECK(fs::exists(dir));
|
CHECK(fs::exists(dir));
|
||||||
generateFile(dir / "f0");
|
generateFile(dir / "f0");
|
||||||
CHECK(fs::exists(dir / "f0"));
|
CHECK(fs::exists(dir / "f0"));
|
||||||
std::string native = dir.native();
|
std::string native = dir.u8string();
|
||||||
if(native.substr(0,4) == "\\\\?\\") {
|
if (native.substr(0, 4) == "\\\\?\\") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2328,7 +2326,7 @@ TEST_CASE("Windows: UNC path support", "[filesystem][path][fs.path.win.unc]")
|
|||||||
fs::path p(R"(\\localhost\c$\Windows)");
|
fs::path p(R"(\\localhost\c$\Windows)");
|
||||||
auto symstat = fs::symlink_status(p, ec);
|
auto symstat = fs::symlink_status(p, ec);
|
||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
auto p2 = fs::canonical(p,ec);
|
auto p2 = fs::canonical(p, ec);
|
||||||
CHECK(!ec);
|
CHECK(!ec);
|
||||||
CHECK(p2 == p);
|
CHECK(p2 == p);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user