From 0d2533ee3aaf50190ebdb6ae983122906f5cc932 Mon Sep 17 00:00:00 2001 From: Mert Can Altin Date: Fri, 13 Jun 2025 22:03:35 +0300 Subject: [PATCH 1/2] fix: reject Windows file paths in can_parse --- include/ada/helpers.h | 16 ++++++++++++++++ src/implementation.cpp | 5 +++++ tests/CMakeLists.txt | 2 ++ tests/basic_tests.cpp | 7 +++++++ tests/helpers_tests.cpp | 23 +++++++++++++++++++++++ 5 files changed, 53 insertions(+) create mode 100644 tests/helpers_tests.cpp diff --git a/include/ada/helpers.h b/include/ada/helpers.h index 6f949b1fd..072ae5830 100644 --- a/include/ada/helpers.h +++ b/include/ada/helpers.h @@ -231,6 +231,22 @@ inline int fast_digit_count(uint32_t x) noexcept { 42949672960, 42949672960}; return int((x + table[int_log2(x)]) >> 32); } + +/** + * Checks if the given input string is a Windows file path. + * A Windows file path starts with a drive letter followed by a colon and a backslash or forward slash. + * Example: "C:\path\file.node" or "D:/folder/file.exe" + * + * @param input The string to check + * @return true if the input is a Windows file path, false otherwise + */ +inline bool is_windows_file_path(std::string_view input) noexcept { + return input.length() >= 3 && + std::isalpha(input[0]) && + input[1] == ':' && + (input[2] == '\\' || input[2] == '/'); +} + } // namespace ada::helpers #endif // ADA_HELPERS_H diff --git a/src/implementation.cpp b/src/implementation.cpp index 1fd6dc534..2596744d0 100644 --- a/src/implementation.cpp +++ b/src/implementation.cpp @@ -6,6 +6,7 @@ #include "ada/parser.h" #include "ada/url.h" #include "ada/url_aggregator.h" +#include "ada/helpers.h" namespace ada { @@ -49,6 +50,10 @@ std::string href_from_file(std::string_view input) { } bool can_parse(std::string_view input, const std::string_view* base_input) { + if (helpers::is_windows_file_path(input)) { + return false; + } + ada::url_aggregator base_aggregator; ada::url_aggregator* base_pointer = nullptr; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ddd365273..eeabff7aa 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -61,6 +61,7 @@ else() add_executable(url_components url_components.cpp) add_executable(basic_tests basic_tests.cpp) add_executable(from_file_tests from_file_tests.cpp) + add_executable(helpers_tests helpers_tests.cpp) add_executable(ada_c ada_c.cpp) add_executable(url_search_params url_search_params.cpp) @@ -71,6 +72,7 @@ else() target_link_libraries(url_components PRIVATE simdjson GTest::gtest_main) target_link_libraries(basic_tests PRIVATE simdjson GTest::gtest_main) target_link_libraries(from_file_tests PRIVATE simdjson GTest::gtest_main) + target_link_libraries(helpers_tests PRIVATE simdjson GTest::gtest_main) target_link_libraries(ada_c PRIVATE simdjson GTest::gtest_main) target_link_libraries(url_search_params PRIVATE simdjson GTest::gtest_main) diff --git a/tests/basic_tests.cpp b/tests/basic_tests.cpp index 307855d19..667fac8cb 100644 --- a/tests/basic_tests.cpp +++ b/tests/basic_tests.cpp @@ -388,6 +388,13 @@ TEST(basic_tests, can_parse) { std::string_view invalid_base = "!!!!!!!1"; ASSERT_FALSE(ada::can_parse("/hello", &invalid_base)); ASSERT_FALSE(ada::can_parse("!!!")); + + ASSERT_FALSE(ada::can_parse("C:\\path\\file.node")); + ASSERT_FALSE(ada::can_parse("D:\\folder\\file.exe")); + ASSERT_FALSE(ada::can_parse("C:/path/file.node")); + ASSERT_TRUE(ada::can_parse("file:///C:/path/file.node")); + ASSERT_TRUE(ada::can_parse("https://example.com")); + SUCCEED(); } diff --git a/tests/helpers_tests.cpp b/tests/helpers_tests.cpp new file mode 100644 index 000000000..fec1ebdd0 --- /dev/null +++ b/tests/helpers_tests.cpp @@ -0,0 +1,23 @@ +#include "ada.h" +#include "gtest/gtest.h" + +TEST(helpers_tests, is_windows_file_path) { + // Valid Windows paths + ASSERT_TRUE(ada::helpers::is_windows_file_path("C:\\path\\file.node")); + ASSERT_TRUE(ada::helpers::is_windows_file_path("D:\\folder\\file.exe")); + ASSERT_TRUE(ada::helpers::is_windows_file_path("C:/path/file.node")); + ASSERT_TRUE(ada::helpers::is_windows_file_path("Z:\\deep\\nested\\path\\file.txt")); + ASSERT_TRUE(ada::helpers::is_windows_file_path("A:\\file")); + + // Invalid paths + ASSERT_FALSE(ada::helpers::is_windows_file_path("")); // Empty string + ASSERT_FALSE(ada::helpers::is_windows_file_path("C")); // Too short + ASSERT_FALSE(ada::helpers::is_windows_file_path("C:")); // Missing slash + ASSERT_FALSE(ada::helpers::is_windows_file_path("file:///C:/path/file.node")); // URL + ASSERT_FALSE(ada::helpers::is_windows_file_path("https://example.com")); // URL + ASSERT_FALSE(ada::helpers::is_windows_file_path("/path/to/file")); // Unix path + ASSERT_FALSE(ada::helpers::is_windows_file_path("relative/path")); // Relative path + ASSERT_FALSE(ada::helpers::is_windows_file_path("1:\\path")); // Invalid drive letter + ASSERT_FALSE(ada::helpers::is_windows_file_path("C|\\path")); // Invalid separator + ASSERT_FALSE(ada::helpers::is_windows_file_path("C:\\")); // Just drive letter and slash +} \ No newline at end of file From 66d487d923593e174499338cb3eaba318f30d01c Mon Sep 17 00:00:00 2001 From: Mert Can Altin Date: Fri, 13 Jun 2025 22:11:55 +0300 Subject: [PATCH 2/2] lint --- include/ada/helpers.h | 11 +++++------ tests/helpers_tests.cpp | 32 ++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/include/ada/helpers.h b/include/ada/helpers.h index 072ae5830..aa3f7bb3a 100644 --- a/include/ada/helpers.h +++ b/include/ada/helpers.h @@ -234,16 +234,15 @@ inline int fast_digit_count(uint32_t x) noexcept { /** * Checks if the given input string is a Windows file path. - * A Windows file path starts with a drive letter followed by a colon and a backslash or forward slash. - * Example: "C:\path\file.node" or "D:/folder/file.exe" - * + * A Windows file path starts with a drive letter followed by a colon and a + * backslash or forward slash. Example: "C:\path\file.node" or + * "D:/folder/file.exe" + * * @param input The string to check * @return true if the input is a Windows file path, false otherwise */ inline bool is_windows_file_path(std::string_view input) noexcept { - return input.length() >= 3 && - std::isalpha(input[0]) && - input[1] == ':' && + return input.length() >= 3 && std::isalpha(input[0]) && input[1] == ':' && (input[2] == '\\' || input[2] == '/'); } diff --git a/tests/helpers_tests.cpp b/tests/helpers_tests.cpp index fec1ebdd0..b7ce67bef 100644 --- a/tests/helpers_tests.cpp +++ b/tests/helpers_tests.cpp @@ -6,18 +6,26 @@ TEST(helpers_tests, is_windows_file_path) { ASSERT_TRUE(ada::helpers::is_windows_file_path("C:\\path\\file.node")); ASSERT_TRUE(ada::helpers::is_windows_file_path("D:\\folder\\file.exe")); ASSERT_TRUE(ada::helpers::is_windows_file_path("C:/path/file.node")); - ASSERT_TRUE(ada::helpers::is_windows_file_path("Z:\\deep\\nested\\path\\file.txt")); + ASSERT_TRUE( + ada::helpers::is_windows_file_path("Z:\\deep\\nested\\path\\file.txt")); ASSERT_TRUE(ada::helpers::is_windows_file_path("A:\\file")); // Invalid paths - ASSERT_FALSE(ada::helpers::is_windows_file_path("")); // Empty string - ASSERT_FALSE(ada::helpers::is_windows_file_path("C")); // Too short - ASSERT_FALSE(ada::helpers::is_windows_file_path("C:")); // Missing slash - ASSERT_FALSE(ada::helpers::is_windows_file_path("file:///C:/path/file.node")); // URL - ASSERT_FALSE(ada::helpers::is_windows_file_path("https://example.com")); // URL - ASSERT_FALSE(ada::helpers::is_windows_file_path("/path/to/file")); // Unix path - ASSERT_FALSE(ada::helpers::is_windows_file_path("relative/path")); // Relative path - ASSERT_FALSE(ada::helpers::is_windows_file_path("1:\\path")); // Invalid drive letter - ASSERT_FALSE(ada::helpers::is_windows_file_path("C|\\path")); // Invalid separator - ASSERT_FALSE(ada::helpers::is_windows_file_path("C:\\")); // Just drive letter and slash -} \ No newline at end of file + ASSERT_FALSE(ada::helpers::is_windows_file_path("")); // Empty string + ASSERT_FALSE(ada::helpers::is_windows_file_path("C")); // Too short + ASSERT_FALSE(ada::helpers::is_windows_file_path("C:")); // Missing slash + ASSERT_FALSE( + ada::helpers::is_windows_file_path("file:///C:/path/file.node")); // URL + ASSERT_FALSE( + ada::helpers::is_windows_file_path("https://example.com")); // URL + ASSERT_FALSE( + ada::helpers::is_windows_file_path("/path/to/file")); // Unix path + ASSERT_FALSE( + ada::helpers::is_windows_file_path("relative/path")); // Relative path + ASSERT_FALSE( + ada::helpers::is_windows_file_path("1:\\path")); // Invalid drive letter + ASSERT_FALSE( + ada::helpers::is_windows_file_path("C|\\path")); // Invalid separator + ASSERT_FALSE(ada::helpers::is_windows_file_path( + "C:\\")); // Just drive letter and slash +} \ No newline at end of file