From a9777a3300b45e15eb512e3cd1aa3bcd49422854 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Tue, 25 Mar 2025 16:41:46 +1300 Subject: [PATCH] LibURL: Make port state override return failure more for URLPattern Corresponds to URL spec change: https://github.com/whatwg/url/commit/cc8b776b Note that the new test failure being introduced here is an unrelated WPT test change bundled in the resources test file update that I am not convinced is correct. --- Libraries/LibURL/Parser.cpp | 16 +++--- .../wpt-import/urlpattern/urlpattern.any.txt | 18 ++++--- .../resources/urlpatterntestdata.json | 49 +++++++++++++++++-- 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/Libraries/LibURL/Parser.cpp b/Libraries/LibURL/Parser.cpp index d6cf64ca8fc..13c14819765 100644 --- a/Libraries/LibURL/Parser.cpp +++ b/Libraries/LibURL/Parser.cpp @@ -1239,15 +1239,15 @@ Optional Parser::basic_parse(StringView raw_input, Optional bas } // 2. Otherwise, if one of the following is true: - // * c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#) - // * url is special and c is U+005C (\) - // * state override is given + // * c is the EOF code point, U+002F (/), U+003F (?), or U+0023 (#); + // * url is special and c is U+005C (\); or + // * state override is given, else if ((code_point == end_of_file || code_point == '/' || code_point == '?' || code_point == '#') || (url->is_special() && code_point == '\\') || state_override.has_value()) { // then: - // 1. If buffer is not the empty string, then: + // 1. If buffer is not the empty string: if (!buffer.is_empty()) { // 1. Let port be the mathematical integer value that is represented by buffer in radix-10 using ASCII digits for digits with values 0 through 9. auto port = buffer.string_view().to_number(); @@ -1267,11 +1267,15 @@ Optional Parser::basic_parse(StringView raw_input, Optional bas // 4. Set buffer to the empty string. buffer.clear(); + + // 5. If state override is given, then return. + if (state_override.has_value()) + return *url; } - // 2. If state override is given, then return. + // 2. If state override is given, then return failure. if (state_override.has_value()) - return *url; + return {}; // 3. Set state to path start state and decrease pointer by 1. state = State::PathStart; diff --git a/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt b/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt index 0aa4e5e7cd7..c43bb150237 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt @@ -1,9 +1,9 @@ Harness status: OK -Found 350 tests +Found 354 tests -340 Pass -10 Fail +346 Pass +8 Fail Pass Loading data... Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/ba"}] @@ -170,12 +170,16 @@ Pass Pattern: [{"pathname":": Pass Pattern: [{"port":""}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http","port":"80"}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http","port":"80{20}?"}] Inputs: [{"protocol":"http","port":"80"}] -Pass Pattern: [{"protocol":"http","port":"80 "}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"protocol":"http","port":"80 "}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http","port":"100000"}] Inputs: [{"protocol":"http","port":"100000"}] Pass Pattern: [{"port":"80"}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http{s}?","port":"80"}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"port":"80"}] Inputs: [{"port":"80"}] -Fail Pattern: [{"port":"(.*)"}] Inputs: [{"port":"invalid80"}] +Pass Pattern: [{"port":"80"}] Inputs: [{"port":"8\t0"}] +Pass Pattern: [{"port":"80"}] Inputs: [{"port":"80x"}] +Pass Pattern: [{"port":"80"}] Inputs: [{"port":"80?x"}] +Pass Pattern: [{"port":"80"}] Inputs: [{"port":"80\\x"}] +Pass Pattern: [{"port":"(.*)"}] Inputs: [{"port":"invalid80"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/./bar"}] Pass Pattern: [{"pathname":"/foo/baz"}] Inputs: [{"pathname":"/foo/bar/../baz"}] Pass Pattern: [{"pathname":"/caf%C3%A9"}] Inputs: [{"pathname":"/café"}] @@ -236,7 +240,7 @@ Pass Pattern: ["https://example.com/"] Inputs: ["https://example.com:8080/"] Pass Pattern: ["data:foobar"] Inputs: ["data:foobar"] Pass Pattern: ["data\\:foobar"] Inputs: ["data:foobar"] Pass Pattern: ["https://{sub.}?example.com/foo"] Inputs: ["https://example.com/foo"] -Fail Pattern: ["https://{sub.}?example{.com/}foo"] Inputs: ["https://example.com/foo"] +Pass Pattern: ["https://{sub.}?example{.com/}foo"] Inputs: ["https://example.com/foo"] Pass Pattern: ["{https://}example.com/foo"] Inputs: ["https://example.com/foo"] Pass Pattern: ["https://(sub.)?example.com/foo"] Inputs: ["https://example.com/foo"] Pass Pattern: ["https://(sub.)?example(.com/)foo"] Inputs: ["https://example.com/foo"] @@ -293,7 +297,7 @@ Pass Pattern: [{"hostname":"bad hostname"}] Inputs: undefined Pass Pattern: [{"hostname":"bad#hostname"}] Inputs: [{"hostname":"bad"}] Fail Pattern: [{"hostname":"bad%hostname"}] Inputs: undefined Pass Pattern: [{"hostname":"bad/hostname"}] Inputs: [{"hostname":"bad"}] -Fail Pattern: [{"hostname":"bad\\:hostname"}] Inputs: undefined +Pass Pattern: [{"hostname":"bad\\:hostname"}] Inputs: undefined Pass Pattern: [{"hostname":"badhostname"}] Inputs: undefined Pass Pattern: [{"hostname":"bad?hostname"}] Inputs: undefined diff --git a/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json b/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json index f92ab76b71d..a613b6a74b5 100644 --- a/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json +++ b/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json @@ -1202,10 +1202,11 @@ { "pattern": [{ "protocol": "http", "port": "80 " }], "inputs": [{ "protocol": "http", "port": "80" }], - "exactly_empty_components": ["port"], - "expected_match": { - "protocol": { "input": "http", "groups": {} } - } + "expected_obj": { + "protocol": "http", + "port": "80" + }, + "expected_match": null }, { "pattern": [{ "protocol": "http", "port": "100000" }], @@ -1229,6 +1230,34 @@ "port": { "input": "80", "groups": {}} } }, + { + "pattern": [{ "port": "80" }], + "inputs": [{ "port": "8\t0" }], + "expected_match": { + "port": { "input": "80", "groups": {}} + } + }, + { + "pattern": [{ "port": "80" }], + "inputs": [{ "port": "80x" }], + "expected_match": { + "port": { "input": "80", "groups": {}} + } + }, + { + "pattern": [{ "port": "80" }], + "inputs": [{ "port": "80?x" }], + "expected_match": { + "port": { "input": "80", "groups": {}} + } + }, + { + "pattern": [{ "port": "80" }], + "inputs": [{ "port": "80\\x" }], + "expected_match": { + "port": { "input": "80", "groups": {}} + } + }, { "pattern": [{ "port": "(.*)" }], "inputs": [{ "port": "invalid80" }], @@ -1874,7 +1903,17 @@ { "pattern": [ "https://{sub.}?example{.com/}foo" ], "inputs": [ "https://example.com/foo" ], - "expected_obj": "error" + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "{sub.}?example.com", + "pathname": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo", "groups": { "0": "/foo" } } + } }, { "pattern": [ "{https://}example.com/foo" ],