diff --git a/.github/workflows/ubuntu-debug.yml b/.github/workflows/ubuntu-debug.yml new file mode 100644 index 000000000..aa7bb9955 --- /dev/null +++ b/.github/workflows/ubuntu-debug.yml @@ -0,0 +1,44 @@ +name: Ubuntu 22.04 Debug + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths-ignore: + - '**.md' + - 'docs/**' + push: + branches: + - main + paths-ignore: + - '**.md' + - 'docs/**' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ubuntu-build-debug: + strategy: + fail-fast: false + matrix: + shared: [OFF] + cxx: [g++-12, clang++-15] + runs-on: [ubuntu-22.04] + simdutf: [OFF, ON] + runs-on: ${{matrix.runs-on}} + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - name: Setup Ninja + run: sudo apt-get install ninja-build + - name: Prepare + run: cmake -DCMAKE_BUILD_TYPE=Debug -D ADA_TESTING=ON -D ADA_BENCHMARKS=ON -DBUILD_SHARED_LIBS=${{matrix.shared}} -D ADA_USE_SIMDUTF=${{matrix.simdutf}} -G Ninja -B build + env: + CXX: ${{matrix.cxx}} + - name: Build + run: cmake --build build -j=4 + - name: Test + run: ctest --output-on-failure --test-dir build --timeout 300 diff --git a/src/url_aggregator.cpp b/src/url_aggregator.cpp index cfa68a466..a9a623f51 100644 --- a/src/url_aggregator.cpp +++ b/src/url_aggregator.cpp @@ -647,16 +647,26 @@ bool url_aggregator::set_host_or_hostname(const std::string_view input) { return true; } -bool url_aggregator::set_host(const std::string_view input) { +bool url_aggregator::set_host(std::string_view input) { ada_log("url_aggregator::set_host '", input, "'"); ADA_ASSERT_TRUE(validate()); + std::string tmp_buffer; + if (helpers::overlaps(input, buffer)) { + tmp_buffer = input; + input = tmp_buffer; + } ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); return set_host_or_hostname(input); } -bool url_aggregator::set_hostname(const std::string_view input) { +bool url_aggregator::set_hostname(std::string_view input) { ada_log("url_aggregator::set_hostname '", input, "'"); ADA_ASSERT_TRUE(validate()); + std::string tmp_buffer; + if (helpers::overlaps(input, buffer)) { + tmp_buffer = input; + input = tmp_buffer; + } ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); return set_host_or_hostname(input); } @@ -1227,6 +1237,11 @@ bool url_aggregator::parse_ipv6(std::string_view input) { bool url_aggregator::parse_opaque_host(std::string_view input) { ada_log("parse_opaque_host ", input, " [", input.size(), " bytes]"); ADA_ASSERT_TRUE(validate()); + std::string tmp_buffer; + if (helpers::overlaps(input, buffer)) { + tmp_buffer = input; + input = tmp_buffer; + } ADA_ASSERT_TRUE(!helpers::overlaps(input, buffer)); if (std::ranges::any_of(input, ada::unicode::is_forbidden_host_code_point)) { return is_valid = false; diff --git a/tests/basic_tests.cpp b/tests/basic_tests.cpp index 579a0c5d7..cfe7f1fca 100644 --- a/tests/basic_tests.cpp +++ b/tests/basic_tests.cpp @@ -56,6 +56,16 @@ TYPED_TEST(basic_tests, pluses) { SUCCEED(); } +TYPED_TEST(basic_tests, overlap_test) { + auto url = ada::parse("http://example.com/very_long_path_string"); + ASSERT_TRUE(url); + // This triggers assertion failure in debug mode for url_aggregator + // because get_pathname() returns a view into the buffer, and set_hostname() + // modifies it. + url->set_hostname(url->get_pathname()); + SUCCEED(); +} + TYPED_TEST(basic_tests, set_host_should_return_false_sometimes) { auto r = ada::parse("mailto:a@b.com"); ASSERT_FALSE(r->set_host("something")); diff --git a/tests/wpt/ada_extra_urltestdata.json b/tests/wpt/ada_extra_urltestdata.json index 93cc0870c..0fac86713 100644 --- a/tests/wpt/ada_extra_urltestdata.json +++ b/tests/wpt/ada_extra_urltestdata.json @@ -285,5 +285,20 @@ "pathname": "b/", "search": "", "hash": "" + }, + { + "input": "http://user:pass@1.2.3.4", + "base": "about:blank", + "href": "http://user:pass@1.2.3.4/", + "origin": "http://1.2.3.4", + "protocol": "http:", + "username": "user", + "password": "pass", + "host": "1.2.3.4", + "hostname": "1.2.3.4", + "port": "", + "pathname": "/", + "search": "", + "hash": "" } ]