Skip to content

Commit

Permalink
URLPattern: Support constructor strings with ipv6 addresses.
Browse files Browse the repository at this point in the history
This adds support for constructor strings like:

  new URLPattern("http://[\\:\\:1]/");

As discussed in spec issue #113:

  whatwg/urlpattern#113

Fixed: 1245760
Change-Id: I712341e72a5c2af745dbbdbb8673a79809a98425
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3138336
Commit-Queue: Ben Kelly <wanderview@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/main@{#917682}
  • Loading branch information
wanderview authored and Chromium LUCI CQ committed Sep 2, 2021
1 parent 1fc63ec commit 43dcc53
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,15 @@ void Parser::Parse(ExceptionState& exception_state) {
break;

case StringParseState::kHostname:
// Track whether we are inside ipv6 address brackets.
if (IsIPv6Open())
hostname_ipv6_bracket_depth_ += 1;
else if (IsIPv6Close())
hostname_ipv6_bracket_depth_ -= 1;

// If we find a `:` then we transition to the port component state.
if (IsPortPrefix())
// However, we ignore `:` when parsing an ipv6 address.
else if (IsPortPrefix() && !hostname_ipv6_bracket_depth_)
ChangeState(StringParseState::kPort, Skip(1));

// If we find a `/` then we transition to the pathname component state.
Expand Down Expand Up @@ -424,6 +431,14 @@ bool Parser::IsGroupClose() const {
return token_list_[token_index_].type == liburlpattern::TokenType::kClose;
}

bool Parser::IsIPv6Open() const {
return IsNonSpecialPatternChar(token_index_, "[");
}

bool Parser::IsIPv6Close() const {
return IsNonSpecialPatternChar(token_index_, "]");
}

String Parser::MakeComponentString() const {
DCHECK_LT(token_index_, token_list_.size());
const auto& token = token_list_[token_index_];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ class Parser final {
bool IsGroupOpen() const;
bool IsGroupClose() const;

// These methods indicate if the current token is an opening or closing
// bracket for an ipv6 hostname; e.g. '[' or ']'.
bool IsIPv6Open() const;
bool IsIPv6Close() const;

// This method returns a String consisting of the tokens between
// `component_start_` and the current `token_index_`.
String MakeComponentString() const;
Expand Down Expand Up @@ -177,6 +182,9 @@ class Parser final {
// The current nesting depth of `{ }` pattern groupings.
int group_depth_ = 0;

// The current netsting depth of `[ ]` in hostname patterns.
int hostname_ipv6_bracket_depth_ = 0;

// The current parse state. This should only be changed via `ChangeState()`
// or `RewindAndSetState()`.
StringParseState state_ = StringParseState::kInit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2150,6 +2150,55 @@
"pathname": { "input": "/data:channel.html", "groups": {} }
}
},
{
"pattern": [ "http://[\\:\\:1]/" ],
"inputs": [ "http://[::1]/" ],
"exactly_empty_components": [ "username", "password", "port", "search",
"hash" ],
"expected_obj": {
"protocol": "http",
"hostname": "[\\:\\:1]",
"pathname": "/"
},
"expected_match": {
"protocol": { "input": "http", "groups": {} },
"hostname": { "input": "[::1]", "groups": {} },
"pathname": { "input": "/", "groups": {} }
}
},
{
"pattern": [ "http://[\\:\\:1]:8080/" ],
"inputs": [ "http://[::1]:8080/" ],
"exactly_empty_components": [ "username", "password", "search", "hash" ],
"expected_obj": {
"protocol": "http",
"hostname": "[\\:\\:1]",
"port": "8080",
"pathname": "/"
},
"expected_match": {
"protocol": { "input": "http", "groups": {} },
"hostname": { "input": "[::1]", "groups": {} },
"port": { "input": "8080", "groups": {} },
"pathname": { "input": "/", "groups": {} }
}
},
{
"pattern": [ "http://[\\:\\:a]/" ],
"inputs": [ "http://[::a]/" ],
"exactly_empty_components": [ "username", "password", "port", "search",
"hash" ],
"expected_obj": {
"protocol": "http",
"hostname": "[\\:\\:a]",
"pathname": "/"
},
"expected_match": {
"protocol": { "input": "http", "groups": {} },
"hostname": { "input": "[::a]", "groups": {} },
"pathname": { "input": "/", "groups": {} }
}
},
{
"pattern": [ "https://foo{{@}}example.com" ],
"inputs": [ "https://foo@example.com" ],
Expand Down

0 comments on commit 43dcc53

Please sign in to comment.