Skip to content

Commit 86eeee0

Browse files
committed
fixed handling of mixed slashes in Path::join() [skip ci]
1 parent e03f9af commit 86eeee0

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

lib/path.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,13 @@ bool Path::exists(const std::string &path, bool* isdir)
449449
return type == S_IFREG;
450450
}
451451

452-
std::string Path::join(const std::string& path1, const std::string& path2) {
452+
std::string Path::join(std::string path1, std::string path2)
453+
{
454+
path1 = fromNativeSeparators(std::move(path1));
455+
path2 = fromNativeSeparators(std::move(path2));
453456
if (path1.empty() || path2.empty())
454457
return path1 + path2;
458+
// this matches the behavior of std::filesystem::path::operator/=() and os.path.join()
455459
if (path2.front() == '/')
456460
return path2;
457461
return ((path1.back() == '/') ? path1 : (path1 + "/")) + path2;

lib/path.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,11 @@ class CPPCHECKLIB Path {
201201
static bool exists(const std::string &path, bool* isdir = nullptr);
202202

203203
/**
204-
* join 2 paths with '/' separators
204+
* @brief join 2 paths with '/' separators
205+
* if path2 is an absolute path path1 will be dismissed.
206+
* @return the joined path with normalized slashes
205207
*/
206-
static std::string join(const std::string& path1, const std::string& path2);
208+
static std::string join(std::string path1, std::string path2);
207209
};
208210

209211
/// @}

test/testpath.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,36 @@ class TestPath : public TestFixture {
172172
}
173173

174174
void join() const {
175+
ASSERT_EQUALS("", Path::join("", ""));
176+
ASSERT_EQUALS("b", Path::join("", "b"));
177+
ASSERT_EQUALS("/b", Path::join("", "/b"));
178+
ASSERT_EQUALS("/b", Path::join("", "\\b"));
179+
175180
ASSERT_EQUALS("a", Path::join("a", ""));
176-
ASSERT_EQUALS("a", Path::join("", "a"));
177181
ASSERT_EQUALS("a/b", Path::join("a", "b"));
178-
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
179182
ASSERT_EQUALS("/b", Path::join("a", "/b"));
183+
ASSERT_EQUALS("/b", Path::join("a", "\\b"));
184+
185+
ASSERT_EQUALS("a/", Path::join("a/", ""));
186+
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
187+
ASSERT_EQUALS("/b", Path::join("a/", "/b"));
188+
ASSERT_EQUALS("/b", Path::join("a/", "\\b"));
189+
190+
ASSERT_EQUALS("a/", Path::join("a\\", ""));
191+
ASSERT_EQUALS("a/b", Path::join("a\\", "b"));
192+
ASSERT_EQUALS("/b", Path::join("a\\", "/b"));
193+
ASSERT_EQUALS("/b", Path::join("a\\", "\\b"));
194+
195+
// TODO: how to absolute Windows path in path2?
196+
//ASSERT_EQUALS("", Path::join("a", "s:/b"));
197+
198+
//ASSERT_EQUALS("", Path::join("S:\\a", "S:/b"));
199+
//ASSERT_EQUALS("", Path::join("S:\\a", "S:\\b"));
200+
//ASSERT_EQUALS("", Path::join("S:\\a", "/b"));
201+
202+
//ASSERT_EQUALS("", Path::join("S:/a", "S:/b"));
203+
//ASSERT_EQUALS("", Path::join("S:/a", "S:\\b"));
204+
//ASSERT_EQUALS("", Path::join("S:/a", "/b"));
180205
}
181206

182207
void isDirectory() const {

0 commit comments

Comments
 (0)