Skip to content

Commit f0e0201

Browse files
committed
Better handle double slashes, more tests
1 parent 77a9822 commit f0e0201

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

lib/path.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ std::string Path::fromNativeSeparators(std::string path)
6060

6161
std::string Path::simplifyPath(std::string originalPath)
6262
{
63+
const bool isUnc = originalPath.size() > 2 && originalPath[0] == '/' && originalPath[1] == '/';
64+
6365
// Remove ./, .//, ./// etc. at the beginning
6466
if (originalPath.size() > 2 && originalPath[0] == '.' &&
6567
originalPath[1] == '/') {
@@ -90,6 +92,14 @@ std::string Path::simplifyPath(std::string originalPath)
9092
if (subPath.length() > 0)
9193
pathParts.push_back(subPath);
9294

95+
// First filter out all double slashes
96+
for (unsigned int i = 1; i < pathParts.size(); ++i) {
97+
if (i > 0 && pathParts[i] == "/" && pathParts[i-1] == "/") {
98+
pathParts.erase(pathParts.begin() + static_cast<int>(i) - 1);
99+
--i;
100+
}
101+
}
102+
93103
for (unsigned int i = 1; i < pathParts.size(); ++i) {
94104
if (i > 1 && pathParts[i-2] != ".." && pathParts[i] == ".." && pathParts.size() > i + 1) {
95105
pathParts.erase(pathParts.begin() + static_cast<int>(i) + 1);
@@ -100,13 +110,17 @@ std::string Path::simplifyPath(std::string originalPath)
100110
} else if (i > 0 && pathParts[i] == ".") {
101111
pathParts.erase(pathParts.begin() + static_cast<int>(i));
102112
i = 0;
103-
// Don't touch leading "//" which means a UNC path
104-
} else if (i > 1 && pathParts[i] == "/" && pathParts[i-1] == "/") {
113+
} else if (i > 0 && pathParts[i] == "/" && pathParts[i-1] == "/") {
105114
pathParts.erase(pathParts.begin() + static_cast<int>(i) - 1);
106115
i = 0;
107116
}
108117
}
109118

119+
if (isUnc) {
120+
// Restore the leading double slash
121+
pathParts.insert(pathParts.begin(), "/");
122+
}
123+
110124
std::ostringstream oss;
111125
for (std::vector<std::string>::size_type i = 0; i < pathParts.size(); ++i) {
112126
oss << pathParts[i];

test/testpath.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,33 @@ class TestPath : public TestFixture {
4040
// Path::simplifyPath()
4141
ASSERT_EQUALS("index.h", Path::simplifyPath("index.h"));
4242
ASSERT_EQUALS("index.h", Path::simplifyPath("./index.h"));
43+
ASSERT_EQUALS("index.h", Path::simplifyPath(".//index.h"));
44+
ASSERT_EQUALS("index.h", Path::simplifyPath(".///index.h"));
4345
ASSERT_EQUALS("/index.h", Path::simplifyPath("/index.h"));
4446
ASSERT_EQUALS("/path/", Path::simplifyPath("/path/"));
4547
ASSERT_EQUALS("/", Path::simplifyPath("/"));
48+
ASSERT_EQUALS("/", Path::simplifyPath("/."));
49+
ASSERT_EQUALS("/", Path::simplifyPath("/./"));
50+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/./index.h"));
51+
ASSERT_EQUALS("/", Path::simplifyPath("/.//"));
52+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/.//index.h"));
4653
ASSERT_EQUALS("../index.h", Path::simplifyPath("../index.h"));
4754
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path/../index.h"));
55+
ASSERT_EQUALS("index.h", Path::simplifyPath("./path/../index.h"));
56+
ASSERT_EQUALS("index.h", Path::simplifyPath("path/../index.h"));
57+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path//../index.h"));
58+
ASSERT_EQUALS("index.h", Path::simplifyPath("./path//../index.h"));
59+
ASSERT_EQUALS("index.h", Path::simplifyPath("path//../index.h"));
60+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path/..//index.h"));
61+
ASSERT_EQUALS("index.h", Path::simplifyPath("./path/..//index.h"));
62+
ASSERT_EQUALS("index.h", Path::simplifyPath("path/..//index.h"));
63+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path//..//index.h"));
64+
ASSERT_EQUALS("index.h", Path::simplifyPath("./path//..//index.h"));
65+
ASSERT_EQUALS("index.h", Path::simplifyPath("path//..//index.h"));
4866
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path/../other/../index.h"));
4967
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path/../other///././../index.h"));
68+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path/../other/././..///index.h"));
69+
ASSERT_EQUALS("/index.h", Path::simplifyPath("/path/../other///././..///index.h"));
5070
ASSERT_EQUALS("../path/index.h", Path::simplifyPath("../path/other/../index.h"));
5171
ASSERT_EQUALS("a/index.h", Path::simplifyPath("a/../a/index.h"));
5272
ASSERT_EQUALS("a/..", Path::simplifyPath("a/.."));

0 commit comments

Comments
 (0)