From 882c60baf290d0fea333c4ad80c6dfe5d85443a8 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Fri, 3 May 2019 22:34:08 +0200 Subject: [PATCH 1/3] refs #11, successive ".." sequences handeld wrong in lexically_normal() --- include/ghc/filesystem.hpp | 7 ++++++- test/filesystem_test.cpp | 28 ++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 6ffced9..e215e9c 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -2378,13 +2378,18 @@ GHC_INLINE path path::lexically_normal() const path dest; for (const string_type& s : *this) { if (s == ".") { + dest /= ""; continue; } else if (s == ".." && !dest.empty()) { - if (dest == root_path()) { + auto root = root_path(); + if (dest == root) { continue; } else if (*(--dest.end()) != "..") { + if(dest._path.back() == generic_separator) { + dest._path.pop_back(); + } dest.remove_filename(); continue; } diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 55bfb81..83e481c 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -474,7 +474,7 @@ TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.pat CHECK((std::string)fs::u8path("\xc3\xa4\\\xe2\x82\xac") == std::string("\xc3\xa4\\\xe2\x82\xac")); #endif CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").string() == std::string("\xc3\xa4\\\xe2\x82\xac")); - CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").wstring() == std::wstring(L"ä\\€")); + CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").wstring() == std::wstring(L"\u00E4\\\u20AC")); CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u8string() == std::string("\xc3\xa4\\\xe2\x82\xac")); CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u16string() == std::u16string(u"\u00E4\\\u20AC")); CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u32string() == std::u32string(U"\U000000E4\\\U000020AC")); @@ -779,7 +779,8 @@ TEST_CASE("30.10.8.4.11 path generation", "[filesystem][path][fs.path.gen]") CHECK(fs::path("foo/.///bar/../").lexically_normal() == "foo/"); CHECK(fs::path("/foo/../..").lexically_normal() == "/"); CHECK(fs::path("foo/..").lexically_normal() == "."); - + CHECK(fs::path("ab/cd/ef/../../qw").lexically_normal() == "ab/qw"); + // lexically_relative() CHECK(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d"); CHECK(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c"); @@ -1198,6 +1199,29 @@ TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive fs::recursive_directory_iterator rd5; rd5 = rd4; } +/* + if(1) { + fs::path d = ".."; + int maxDepth = 2; + fs::recursive_directory_iterator dit(d); + std::cout << d << std::endl; + for(auto & f : dit) { +#if 1 + if(dit.depth()<=maxDepth) { + std::cout << dit.depth() << ": " << f.path() << std::endl; + } + else { + dit.pop(); + } +#else + std::cout << dit.depth() << ": " << f.path() << std::endl; + if(dit.depth()>maxDepth) { + dit.disable_recursion_pending(); + } +#endif + } + } + */ } TEST_CASE("30.10.15.1 absolute", "[filesystem][operations][fs.op.absolute]") From 263a2d2c5b9f25631513271a6e26a9cb66e8f9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Sch=C3=BCmann?= Date: Fri, 3 May 2019 22:44:01 +0200 Subject: [PATCH 2/3] Work on Windows tests. --- test/filesystem_test.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index e88ffcd..06289b3 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -468,14 +468,15 @@ TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.pat { #ifdef GHC_OS_WINDOWS #ifdef IS_WCHAR_PATH - CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").native() == fs::path::string_type(L"ä\\€")); + CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").native() == fs::path::string_type(L"\u00E4\\\u20AC")); + // CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").string() == std::string("ä\\€")); // MSVCs returns local DBCS encoding #else CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").native() == fs::path::string_type("\xc3\xa4\\\xe2\x82\xac")); + CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").string() == std::string("\xc3\xa4\\\xe2\x82\xac")); CHECK(!::strcmp(fs::u8path("\xc3\xa4\\\xe2\x82\xac").c_str(), "\xc3\xa4\\\xe2\x82\xac")); CHECK((std::string)fs::u8path("\xc3\xa4\\\xe2\x82\xac") == std::string("\xc3\xa4\\\xe2\x82\xac")); #endif - CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").string() == std::string("\xc3\xa4\\\xe2\x82\xac")); - CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").wstring() == std::wstring(L"ä\\€")); + CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").wstring() == std::wstring(L"\u00E4\\\u20AC")); CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u8string() == std::string("\xc3\xa4\\\xe2\x82\xac")); CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u16string() == std::u16string(u"\u00E4\\\u20AC")); CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u32string() == std::u32string(U"\U000000E4\\\U000020AC")); @@ -496,7 +497,9 @@ TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.pat TEST_CASE("30.10.8.4.7 path generic format observers", "[filesystem][path][fs.path.generic.obs]") { #ifdef GHC_OS_WINDOWS +#ifndef IS_WCHAR_PATH CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_string() == std::string("\xc3\xa4/\xe2\x82\xac")); +#endif #ifndef USE_STD_FS auto t = fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_string, TestAllocator>(); CHECK(t.c_str() == std::string("\xc3\xa4/\xe2\x82\xac")); @@ -2336,5 +2339,23 @@ TEST_CASE("Windows: UNC path support", "[filesystem][path][fs.path.win.unc]") auto p2 = fs::canonical(p, ec); CHECK(!ec); CHECK(p2 == p); + + std::vector variants = { + R"(C:\Windows\notepad.exe)", + R"(\\.\C:\Windows\notepad.exe)", + R"(\\?\C:\Windows\notepad.exe)", + R"(\??\C:\Windows\notepad.exe)", + R"(\\?\HarddiskVolume1\Windows\notepad.exe)", + R"(\\?\Harddisk0Partition1\Windows\notepad.exe)", + R"(\\.\GLOBALROOT\Device\HarddiskVolume1\Windows\notepad.exe)", + R"(\\?\GLOBALROOT\Device\Harddisk0\Partition1\Windows\notepad.exe)", + R"(\\?\Volume{e8a4a89d-0000-0000-0000-100000000000}\Windows\notepad.exe)", + R"(\\LOCALHOST\C$\Windows\notepad.exe)", + R"(\\?\UNC\C$\Windows\notepad.exe)", + R"(\\?\GLOBALROOT\Device\Mup\C$\Windows\notepad.exe)", + }; + for (auto p : variants) { + std::cerr << p.string() << " - " << p.root_name() << ", " << p.root_path() << ": " << iterateResult(p) << std::endl; + } } #endif From 43e75c3869b8169ac83d64bfd951f8ac8eab70fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Sch=C3=BCmann?= Date: Fri, 3 May 2019 23:14:05 +0200 Subject: [PATCH 3/3] refs #11, added more tests --- include/ghc/filesystem.hpp | 2 +- test/filesystem_test.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index e215e9c..3831eb2 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -147,7 +147,7 @@ #define LWG_2937_BEHAVIOUR // ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) -#define GHC_FILESYSTEM_VERSION 10100L +#define GHC_FILESYSTEM_VERSION 10101L namespace ghc { namespace filesystem { diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 83e481c..faaa905 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -780,7 +780,13 @@ TEST_CASE("30.10.8.4.11 path generation", "[filesystem][path][fs.path.gen]") CHECK(fs::path("/foo/../..").lexically_normal() == "/"); CHECK(fs::path("foo/..").lexically_normal() == "."); CHECK(fs::path("ab/cd/ef/../../qw").lexically_normal() == "ab/qw"); - + CHECK(fs::path("a/b/../../../c").lexically_normal() == "../c"); +#ifdef GHC_OS_WINDOWS + CHECK(fs::path("\\/\\///\\/").lexically_normal() == "/"); + CHECK(fs::path("a/b/..\\//..///\\/../c\\\\/").lexically_normal() == "../c/"); + CHECK(fs::path("..a/b/..\\//..///\\/../c\\\\/").lexically_normal() == "../c/"); +#endif + // lexically_relative() CHECK(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d"); CHECK(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c");