commit 3e89bf6ba32a8db35967afead04c3a18fc4c072c
parent 6b7be926d19bfb283385b26946577a4ab4bc28bd
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sat, 2 Dec 2017 23:48:46 -0500
path: ignore '.' and do Windows absolute path detection logic when parsing the last segment [p=1919963]
Diffstat:
2 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/src/path.cpp b/src/path.cpp
@@ -46,13 +46,25 @@ static vector<string> Split(const string &input, bool *absolute)
{
vector<string> list;
+ const auto append = [&list, absolute] (const string &part) {
+ if(part.empty() || part == DOT)
+ return;
+
+#ifdef _WIN32
+ if(list.empty() && part.size() == 2 && isalpha(part[0]) && part[1] == ':')
+ *absolute = true;
+#endif
+
+ list.push_back(part);
+ };
+
size_t last = 0, size = input.size();
while(last < size) {
const size_t pos = input.find_first_of("\\/", last);
if(pos == string::npos) {
- list.push_back(input.substr(last));
+ append(input.substr(last));
break;
}
else if(last + pos == 0) {
@@ -63,15 +75,7 @@ static vector<string> Split(const string &input, bool *absolute)
continue;
}
- const string &part = input.substr(last, pos - last);
-
- if(!part.empty() && part != DOT) {
-#ifdef _WIN32
- if(list.empty() && part.size() == 2 && isalpha(part[0]) && part[1] == ':')
- *absolute = true;
-#endif
- list.push_back(part);
- }
+ append(input.substr(last, pos - last));
last = pos + 1;
}
diff --git a/test/path.cpp b/test/path.cpp
@@ -265,24 +265,34 @@ TEST_CASE("remove root path", M) {
REQUIRE(path.removeRoot() == Path("hello/world"));
}
-TEST_CASE("directory traversal", M) {
- SECTION("append (enabled)") {
- REQUIRE(Path("a/./b") == Path("a/b"));
+TEST_CASE("append with directory traversal enabled", M) {
+ SECTION("dot")
+ REQUIRE(Path("a/./b/.") == Path("a/b"));
+
+ SECTION("dotdot")
REQUIRE(Path("a/../b") == Path("b"));
- REQUIRE(Path("../a") == Path("a"));
- }
+}
- SECTION("append (disabled)") {
- Path a;
+TEST_CASE("append with directory traversal disabled", M) {
+ Path a;
+
+ SECTION("dot")
+ a.append("a/./b/.", false);
+
+ SECTION("dotdot")
a.append("a/../b", false);
- REQUIRE(a == Path("a/b"));
- }
- SECTION("concatenate") {
+ REQUIRE(a == Path("a/b"));
+}
+
+TEST_CASE("concatenate with directory traversal", M) {
+ SECTION("path + string") {
// concatenating a std::string to a path, directory traversal is applied
const Path a = Path("a/b/c") + "../../../d/e/f";
REQUIRE(a == Path("d/e/f"));
+ }
+ SECTION("path + path") {
// here, the directory traversal segments are lost before concatenating
const Path b = Path("a/b/c") + Path("../../../d/e/f");
REQUIRE(b == Path("a/b/c/d/e/f"));