domainRFC support ipv6(square brackets) and fix #53179 (#53506)

This commit is contained in:
Chen768959 2023-08-29 17:42:59 +08:00 committed by GitHub
parent a1a45ee905
commit a2d451d6e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 2 deletions

View File

@ -44,6 +44,7 @@ inline std::string_view getURLHostRFC(const char * data, size_t size)
case '.':
case '-':
case '+':
case '[':
break;
case ' ': /// restricted symbols
case '\t':
@ -56,7 +57,6 @@ inline std::string_view getURLHostRFC(const char * data, size_t size)
case '\\':
case '^':
case '~':
case '[':
case ']':
case ';':
case '=':
@ -73,6 +73,13 @@ exloop: if ((scheme_end - pos) > 2 && *pos == ':' && *(pos + 1) == '/' && *(pos
pos = data;
}
bool has_open_bracket = false;
bool has_end_bracket = false;
if (*pos == '[') /// IPv6 [2001:db8::1]:80
{
has_open_bracket = true;
++pos;
}
Pos dot_pos = nullptr;
Pos colon_pos = nullptr;
bool has_sub_delims = false;
@ -84,10 +91,14 @@ exloop: if ((scheme_end - pos) > 2 && *pos == ':' && *(pos + 1) == '/' && *(pos
switch (*pos)
{
case '.':
if (has_open_bracket)
return std::string_view{};
if (has_at_symbol || colon_pos == nullptr)
dot_pos = pos;
break;
case ':':
if (has_open_bracket)
continue;
if (has_at_symbol || colon_pos) goto done;
colon_pos = pos;
break;
@ -116,6 +127,13 @@ exloop: if ((scheme_end - pos) > 2 && *pos == ':' && *(pos + 1) == '/' && *(pos
/// registered).
has_sub_delims = true;
continue;
case ']':
if (has_open_bracket)
{
has_end_bracket = true;
goto done;
}
[[fallthrough]];
case ' ': /// restricted symbols in whole URL
case '\t':
case '<':
@ -126,7 +144,6 @@ exloop: if ((scheme_end - pos) > 2 && *pos == ':' && *(pos + 1) == '/' && *(pos
case '\\':
case '^':
case '[':
case ']':
if (colon_pos == nullptr)
return std::string_view{};
else
@ -138,7 +155,11 @@ done:
if (has_sub_delims)
return std::string_view{};
if (!has_at_symbol)
{
if (has_open_bracket && has_end_bracket)
return std::string_view(start_of_host, pos - start_of_host);
pos = colon_pos ? colon_pos : pos;
}
return checkAndReturnHost(pos, dot_pos, start_of_host);
}

View File

@ -0,0 +1,32 @@
"2001:db8::1"
"2001:db8::1"
"::200"
"2001:db8::1"
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""
""

View File

@ -0,0 +1,33 @@
SELECT domainRFC('http://[2001:db8::1]:80') FORMAT CSV;
SELECT domainRFC('[2001:db8::1]:80') FORMAT CSV;
SELECT domainRFC('[::200]:80') FORMAT CSV;
SELECT domainRFC('[2001:db8::1]') FORMAT CSV;
-- Does not conform to the IPv6 format.
SELECT domainRFC('[2001db81]:80') FORMAT CSV;
SELECT domainRFC('[20[01:db8::1]:80') FORMAT CSV;
SELECT domainRFC('[20[01:db]8::1]:80') FORMAT CSV;
SELECT domainRFC('[2001:db8::1') FORMAT CSV;
SELECT domainRFC('2001:db8::1]:80') FORMAT CSV;
SELECT domainRFC('[2001db81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db.81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db/81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db?81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db#81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db@81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db;81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db=81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db&81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db~81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db%81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db<81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db>81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db{81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db}81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db|81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db\81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db^81]:80') FORMAT CSV;
SELECT domainRFC('[2001::db 81]:80') FORMAT CSV;
SELECT domainRFC('[[]:80') FORMAT CSV;
SELECT domainRFC('[]]:80') FORMAT CSV;
SELECT domainRFC('[]:80') FORMAT CSV;
SELECT domainRFC('[ ]:80') FORMAT CSV;