From ca8cfcf2464773b079f5e89ba08256ebf279a7bb Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 10 Sep 2025 10:49:55 +0200 Subject: [PATCH 1/5] exposed `isAbsolutePath()` and merged implementations --- simplecpp.cpp | 21 +++++++++------------ simplecpp.h | 3 +++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 320836be..536deb47 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -2438,21 +2438,18 @@ namespace simplecpp { return windowsPath; } #endif -} + bool isAbsolutePath(const std::string &path) + { #ifdef SIMPLECPP_WINDOWS -static bool isAbsolutePath(const std::string &path) -{ - if (path.length() >= 3 && path[0] > 0 && std::isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) - return true; - return path.length() > 1U && (path[0] == '/' || path[0] == '\\'); -} + if (path.length() >= 3 && path[0] > 0 && std::isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) + return true; + return path.length() > 1U && (path[0] == '/' || path[0] == '\\'); #else -static bool isAbsolutePath(const std::string &path) -{ - return path.length() > 1U && path[0] == '/'; -} + return path.length() > 1U && path[0] == '/'; #endif + } +} namespace simplecpp { /** @@ -3013,7 +3010,7 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path) static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader) { - if (isAbsolutePath(header)) + if (simplecpp::isAbsolutePath(header)) return openHeaderDirect(f, simplecpp::simplifyPath(header)); // prefer first to search the header relatively to source file if found, when not a system header diff --git a/simplecpp.h b/simplecpp.h index c6c3b515..b461de47 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -556,6 +556,9 @@ namespace simplecpp { /** Returns the __cplusplus value for a given standard */ SIMPLECPP_LIB std::string getCppStdString(const std::string &std); SIMPLECPP_LIB std::string getCppStdString(cppstd_t std); + + /** Checks if given path is absolute */ + SIMPLECPP_LIB bool isAbsolutePath(const std::string &path); } #undef SIMPLECPP_TOKENLIST_ALLOW_PTR From 78c5078305affdd5a2c066281b2576f251841d7a Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 10 Sep 2025 10:55:17 +0200 Subject: [PATCH 2/5] test.cpp: added filename to assertion failure message allows some IDEs to show clickable links to location --- test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.cpp b/test.cpp index b9869b5b..56e18a31 100644 --- a/test.cpp +++ b/test.cpp @@ -45,7 +45,7 @@ static int assertEquals(const std::string &expected, const std::string &actual, if (expected != actual) { numberOfFailedAssertions++; std::cerr << "------ assertion failed ---------" << std::endl; - std::cerr << "line " << line << std::endl; + std::cerr << "line test.cpp:" << line << std::endl; std::cerr << "expected:" << pprint(expected) << std::endl; std::cerr << "actual:" << pprint(actual) << std::endl; } From 4252db90959245988a8c135ca4aa698296df8b30 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 10 Sep 2025 10:55:49 +0200 Subject: [PATCH 3/5] test.cpp: added `isAbsolutePath()` tests from Cppcheck --- test.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test.cpp b/test.cpp index 56e18a31..0451489b 100644 --- a/test.cpp +++ b/test.cpp @@ -3246,6 +3246,26 @@ static void safe_api() #endif } +static void isAbsolutePath() { +#ifdef _WIN32 + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:\\foo\\bar")); + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:/foo/bar")); + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\\\foo\\bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo\\bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo.cpp")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo\\bar.cpp")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("bar.cpp")); + //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO +#else + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/foo/bar")); + //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/")); // TODO + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); +#endif +} + // crashes detected by fuzzer static void fuzz_crash() { @@ -3525,6 +3545,8 @@ int main(int argc, char **argv) TEST_CASE(safe_api); + TEST_CASE(isAbsolutePath); + TEST_CASE(fuzz_crash); TEST_CASE(leak); From 2bf7805c0a2be933f3eed99f7258673d900f6605 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 10 Sep 2025 11:00:42 +0200 Subject: [PATCH 4/5] test.cpp: added more `isAbsolutePath()` tests --- test.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test.cpp b/test.cpp index 0451489b..76700482 100644 --- a/test.cpp +++ b/test.cpp @@ -3251,6 +3251,7 @@ static void isAbsolutePath() { ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:\\foo\\bar")); ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:/foo/bar")); ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\\\foo\\bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo\\bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); @@ -3258,11 +3259,23 @@ static void isAbsolutePath() { ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo\\bar.cpp")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("bar.cpp")); //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:\\foo\\bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:/foo/bar")); + //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\foo\\bar")); // TODO + //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\")); // TODO + //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("//")); // TODO + //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/foo/bar")); // TODO + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/")); #else ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/foo/bar")); //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/")); // TODO + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("//host/foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:\\foo\\bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:/foo/bar")); + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\foo\\bar")); #endif } From becddebfe4517dbfa82dd83ca274b4c895202060 Mon Sep 17 00:00:00 2001 From: firewave Date: Wed, 10 Sep 2025 11:06:57 +0200 Subject: [PATCH 5/5] improved `isAbsolutePath()` implementation --- simplecpp.cpp | 14 +++++++++++--- test.cpp | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 536deb47..08c3a503 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -2442,11 +2442,19 @@ namespace simplecpp { bool isAbsolutePath(const std::string &path) { #ifdef SIMPLECPP_WINDOWS - if (path.length() >= 3 && path[0] > 0 && std::isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) + // C:\\path\\file + // C:/path/file + if (path.length() >= 3 && std::isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) return true; - return path.length() > 1U && (path[0] == '/' || path[0] == '\\'); + + // \\host\path\file + // //host/path/file + if (path.length() >= 2 && (path[0] == '\\' || path[0] == '/') && (path[1] == '\\' || path[1] == '/')) + return true; + + return false; #else - return path.length() > 1U && path[0] == '/'; + return !path.empty() && path[0] == '/'; #endif } } diff --git a/test.cpp b/test.cpp index 76700482..2f56ae9b 100644 --- a/test.cpp +++ b/test.cpp @@ -3261,14 +3261,14 @@ static void isAbsolutePath() { //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:\\foo\\bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:/foo/bar")); - //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\foo\\bar")); // TODO + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\foo\\bar")); //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\")); // TODO //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("//")); // TODO - //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/foo/bar")); // TODO + ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/")); #else ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/foo/bar")); - //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/")); // TODO + ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/")); ASSERT_EQUALS(true, simplecpp::isAbsolutePath("//host/foo/bar")); ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar"));