Fix in canonical root path handling.

This commit is contained in:
Steffen Schümann 2019-04-27 09:42:20 +02:00
parent 1cd346d23e
commit f96b65562d
2 changed files with 27 additions and 28 deletions

View File

@ -1258,8 +1258,7 @@ namespace detail {
GHC_INLINE bool startsWith(const std::string& what, const std::string& with)
{
return with.length() <= what.length()
&& equal(with.begin(), with.end(), what.begin());
return with.length() <= what.length() && equal(with.begin(), with.end(), what.begin());
}
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::native_format:
#endif
if(startsWith(p, std::string("\\\\?\\"))) {
if (startsWith(p, std::string("\\\\?\\"))) {
// remove Windows long filename marker
p.erase(0, 4);
if(startsWith(p, std::string("UNC\\"))) {
p.erase(0,2);
if (startsWith(p, std::string("UNC\\"))) {
p.erase(0, 2);
p[0] = '\\';
}
}
@ -2085,9 +2084,9 @@ GHC_INLINE void path::swap(path& rhs) noexcept
GHC_INLINE const path::string_type& path::native() const
{
#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
if(has_root_name() && _path[0] == '/') {
if (has_root_name() && _path[0] == '/') {
_native_cache = "\\\\?\\UNC" + _path.substr(1);
}
else {
@ -2856,7 +2855,10 @@ GHC_INLINE path canonical(const path& p, std::error_code& ec)
result = result.parent_path();
continue;
}
else if ((result/pe).string().length() <= root.string().length()) {
result /= pe;
continue;
}
auto sls = symlink_status(result / pe, ec);
if (ec) {
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 __GNUC__
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;
if (oldAttr == newAttr || SetFileAttributesW(p.wstring().c_str(), newAttr)) {
return;

View File

@ -177,13 +177,11 @@ static void generateFile(const fs::path& pathname, int withSize = -1)
#ifdef GHC_OS_WINDOWS
inline bool isWow64Proc()
{
typedef BOOL (WINAPI *IsWow64Process_t) (HANDLE, PBOOL);
typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL);
BOOL bIsWow64 = FALSE;
auto fnIsWow64Process = (IsWow64Process_t)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
if( NULL != fnIsWow64Process )
{
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
{
if (NULL != fnIsWow64Process) {
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
bIsWow64 = FALSE;
}
}
@ -192,7 +190,7 @@ inline bool isWow64Proc()
static bool is_symlink_creation_supported()
{
bool result = false;
bool result = true;
HKEY key;
REGSAM flags = KEY_READ;
#ifdef _WIN64
@ -207,7 +205,7 @@ static bool is_symlink_creation_supported()
#else
result = false;
#endif
if(result) {
if (result) {
auto err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", 0, flags, &key);
if (err == ERROR_SUCCESS) {
DWORD val = 0, size = sizeof(DWORD);
@ -224,7 +222,7 @@ static bool is_symlink_creation_supported()
result = false;
}
}
if(!result) {
if (!result) {
std::clog << "Warning: Symlink creation not supported." << std::endl;
}
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/dir2/file3"));
}
if(is_symlink_creation_supported()) {
if (is_symlink_creation_supported()) {
TemporaryDirectory t(TempOpt::change_path);
std::error_code ec;
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]")
{
if(is_symlink_creation_supported()) {
if (is_symlink_creation_supported()) {
TemporaryDirectory t;
fs::create_directory(t.path() / "dir1");
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]")
{
if(is_symlink_creation_supported()) {
if (is_symlink_creation_supported()) {
TemporaryDirectory t;
fs::create_directory(t.path() / "dir1");
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]")
{
if(is_symlink_creation_supported()) {
if (is_symlink_creation_supported()) {
TemporaryDirectory t(TempOpt::change_path);
std::error_code ec;
generateFile("foo");
@ -2307,15 +2305,15 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long
TemporaryDirectory t(TempOpt::change_path);
char c = 'A';
fs::path dir = fs::current_path();
for( ; c <= 'Z'; ++c) {
for (; c <= 'Z'; ++c) {
std::string part = std::string(16, c);
dir /= part;
CHECK_NOTHROW(fs::create_directory(dir));
CHECK(fs::exists(dir));
generateFile(dir / "f0");
CHECK(fs::exists(dir / "f0"));
std::string native = dir.native();
if(native.substr(0,4) == "\\\\?\\") {
std::string native = dir.u8string();
if (native.substr(0, 4) == "\\\\?\\") {
break;
}
}
@ -2324,11 +2322,11 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long
TEST_CASE("Windows: UNC path support", "[filesystem][path][fs.path.win.unc]")
{
std::error_code ec;
std::error_code ec;
fs::path p(R"(\\localhost\c$\Windows)");
auto symstat = fs::symlink_status(p, ec);
CHECK(!ec);
auto p2 = fs::canonical(p,ec);
auto p2 = fs::canonical(p, ec);
CHECK(!ec);
CHECK(p2 == p);
}