mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: improved URL-parsing functions for URLs with parameters without values and "parameters" after fragment identifier [#METR-19806].
This commit is contained in:
parent
5c90d7d45c
commit
5dec54f4b5
@ -407,7 +407,7 @@ struct ExtractURLParameterImpl
|
||||
const char * str = reinterpret_cast<const char *>(&data[prev_offset]);
|
||||
|
||||
const char * pos = nullptr;
|
||||
const char * begin = strchr(str, '?');
|
||||
const char * begin = strpbrk(str, "?#");
|
||||
if (begin != nullptr)
|
||||
{
|
||||
pos = begin + 1;
|
||||
@ -418,7 +418,7 @@ struct ExtractURLParameterImpl
|
||||
if (pos == nullptr)
|
||||
break;
|
||||
|
||||
if (pos[-1] != '?' && pos[-1] != '&')
|
||||
if (pos[-1] != '?' && pos[-1] != '#' && pos[-1] != '&')
|
||||
{
|
||||
pos += param_len;
|
||||
continue;
|
||||
@ -484,14 +484,15 @@ struct CutURLParameterImpl
|
||||
|
||||
do
|
||||
{
|
||||
const char * begin = strchr(url_begin, '?');
|
||||
const char * begin = strpbrk(url_begin, "?#");
|
||||
if (begin == nullptr)
|
||||
break;
|
||||
|
||||
const char * pos = strstr(begin + 1, param_str);
|
||||
if (pos == nullptr)
|
||||
break;
|
||||
if (pos != begin + 1 && *(pos - 1) != ';' && *(pos - 1) != '&')
|
||||
|
||||
if (pos[-1] != '?' && pos[-1] != '#' && pos[-1] != '&')
|
||||
{
|
||||
pos = nullptr;
|
||||
break;
|
||||
@ -501,13 +502,13 @@ struct CutURLParameterImpl
|
||||
end_pos = begin_pos + param_len;
|
||||
|
||||
/// Пропустим значение.
|
||||
while (*end_pos && *end_pos != ';' && *end_pos != '&' && *end_pos != '#')
|
||||
while (*end_pos && *end_pos != '&' && *end_pos != '#')
|
||||
++end_pos;
|
||||
|
||||
/// Захватим ';' или '&' до или после параметра.
|
||||
if (*end_pos == ';' || *end_pos == '&')
|
||||
/// Захватим '&' до или после параметра.
|
||||
if (*end_pos == '&')
|
||||
++end_pos;
|
||||
else if (*(begin_pos - 1) == ';' || *(begin_pos - 1) == '&')
|
||||
else if (begin_pos[-1] == '&')
|
||||
--begin_pos;
|
||||
} while (false);
|
||||
|
||||
@ -573,22 +574,41 @@ public:
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
pos = strchr(pos, '?');
|
||||
pos = strpbrk(pos, "?#");
|
||||
if (pos == nullptr)
|
||||
return false;
|
||||
++pos;
|
||||
}
|
||||
|
||||
token_begin = pos;
|
||||
pos = strchr(pos, '=');
|
||||
if (pos == nullptr)
|
||||
return false;
|
||||
++pos;
|
||||
pos = strpbrk(pos, "&;#");
|
||||
if (pos == nullptr)
|
||||
token_end = end;
|
||||
else
|
||||
while (true)
|
||||
{
|
||||
token_begin = pos;
|
||||
pos = strpbrk(pos, "=&#?");
|
||||
if (pos == nullptr)
|
||||
return false;
|
||||
|
||||
if (*pos == '?')
|
||||
{
|
||||
++pos;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (*pos == '&' || *pos == '#')
|
||||
{
|
||||
token_end = pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
++pos;
|
||||
pos = strpbrk(pos, "&#");
|
||||
if (pos == nullptr)
|
||||
token_end = end;
|
||||
else
|
||||
token_end = pos++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -642,22 +662,33 @@ public:
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
pos = strchr(pos, '?');
|
||||
pos = strpbrk(pos, "?#");
|
||||
}
|
||||
else
|
||||
pos = strchr(pos, '&');
|
||||
pos = strpbrk(pos, "&#");
|
||||
|
||||
if (pos == nullptr)
|
||||
return false;
|
||||
++pos;
|
||||
|
||||
token_begin = pos;
|
||||
while (true)
|
||||
{
|
||||
token_begin = pos;
|
||||
|
||||
pos = strchr(pos, '=');
|
||||
if (pos == nullptr)
|
||||
return false;
|
||||
else
|
||||
token_end = pos++;
|
||||
pos = strpbrk(pos, "=&#?");
|
||||
if (pos == nullptr)
|
||||
return false;
|
||||
else
|
||||
token_end = pos;
|
||||
|
||||
if (*pos == '?')
|
||||
{
|
||||
++pos;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -981,12 +1012,12 @@ struct NameCutQueryStringAndFragment { static constexpr auto name = "cutQuerySt
|
||||
struct NameExtractURLParameter { static constexpr auto name = "extractURLParameter"; };
|
||||
struct NameCutURLParameter { static constexpr auto name = "cutURLParameter"; };
|
||||
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractProtocol>, NameProtocol> FunctionProtocol;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractProtocol>, NameProtocol> FunctionProtocol;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractDomain<false> >, NameDomain> FunctionDomain;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractDomain<true> >, NameDomainWithoutWWW> FunctionDomainWithoutWWW;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractFirstSignificantSubdomain>, NameFirstSignificantSubdomain> FunctionFirstSignificantSubdomain;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractTopLevelDomain>, NameTopLevelDomain> FunctionTopLevelDomain;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractPath>, NamePath> FunctionPath;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractPath>, NamePath> FunctionPath;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractPathFull>, NamePathFull> FunctionPathFull;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractQueryString<true> >, NameQueryString> FunctionQueryString;
|
||||
typedef FunctionStringToString<ExtractSubstringImpl<ExtractFragment<true> >, NameFragment> FunctionFragment;
|
||||
@ -996,7 +1027,7 @@ typedef FunctionStringToString<ExtractSubstringImpl<CutToFirstSignificantSubdoma
|
||||
|
||||
typedef FunctionStringToString<CutSubstringImpl<ExtractWWW>, NameCutWWW> FunctionCutWWW;
|
||||
typedef FunctionStringToString<CutSubstringImpl<ExtractQueryString<false> >, NameCutQueryString> FunctionCutQueryString;
|
||||
typedef FunctionStringToString<CutSubstringImpl<ExtractFragment<false> >, NameCutFragment> FunctionCutFragment;
|
||||
typedef FunctionStringToString<CutSubstringImpl<ExtractFragment<false> >, NameCutFragment> FunctionCutFragment;
|
||||
typedef FunctionStringToString<CutSubstringImpl<ExtractQueryStringAndFragment<false> >, NameCutQueryStringAndFragment> FunctionCutQueryStringAndFragment;
|
||||
|
||||
typedef FunctionsStringSearchToString<ExtractURLParameterImpl, NameExtractURLParameter> FunctionExtractURLParameter;
|
||||
|
@ -0,0 +1,8 @@
|
||||
['a=b','c=d'] ['a=b','c=d','e=f'] ['a','c=d','e=f'] ['a=b','c=d','e=f','g=h'] ['a=b','c=d'] ['a=b','c=d','e','g=h'] ['a=b','c=d','e=f','g=h']
|
||||
['a','c'] ['a','c','e'] ['a','c','e'] ['a','c','e','g'] ['a','c'] ['a','c','e','g'] ['a','c','e','g']
|
||||
b d f d f h b d d h f h
|
||||
http://yandex.ru/?c=d http://yandex.ru/?a=b http://yandex.ru/?a=b&c=d# http://yandex.ru/?a&c=d#e=f http://yandex.ru/?a#e=f http://yandex.ru/?a&c=d# http://yandex.ru/?a=b&c=d#e=f http://yandex.ru/?c=d#e http://yandex.ru/?a=b#e http://yandex.ru/?a=b&c=d#e http://yandex.ru/?a=b#e&g=h http://yandex.ru/?a=b&c=d#e&g=h http://yandex.ru/?a=b&c=d#e http://yandex.ru/?a=b&c=d#test?e=f&g=h http://yandex.ru/?a=b&c=d#test?g=h http://yandex.ru/?a=b&c=d#test?e=f
|
||||
['a=b','c=d'] ['a=b','c=d','e=f'] ['a','c=d','e=f'] ['a=b','c=d','e=f','g=h'] ['a=b','c=d'] ['a=b','c=d','e','g=h'] ['a=b','c=d','e=f','g=h']
|
||||
['a','c'] ['a','c','e'] ['a','c','e'] ['a','c','e','g'] ['a','c'] ['a','c','e','g'] ['a','c','e','g']
|
||||
b d f d f h b d d h f h
|
||||
http://yandex.ru/?c=d http://yandex.ru/?a=b http://yandex.ru/?a=b&c=d# http://yandex.ru/?a&c=d#e=f http://yandex.ru/?a#e=f http://yandex.ru/?a&c=d# http://yandex.ru/?a=b&c=d#e=f http://yandex.ru/?c=d#e http://yandex.ru/?a=b#e http://yandex.ru/?a=b&c=d#e http://yandex.ru/?a=b#e&g=h http://yandex.ru/?a=b&c=d#e&g=h http://yandex.ru/?a=b&c=d#e http://yandex.ru/?a=b&c=d#test?e=f&g=h http://yandex.ru/?a=b&c=d#test?g=h http://yandex.ru/?a=b&c=d#test?e=f
|
108
dbms/tests/queries/0_stateless/00296_url_parameters.sql
Normal file
108
dbms/tests/queries/0_stateless/00296_url_parameters.sql
Normal file
@ -0,0 +1,108 @@
|
||||
SELECT
|
||||
extractURLParameters('http://yandex.ru/?a=b&c=d'),
|
||||
extractURLParameters('http://yandex.ru/?a=b&c=d#e=f'),
|
||||
extractURLParameters('http://yandex.ru/?a&c=d#e=f'),
|
||||
extractURLParameters('http://yandex.ru/?a=b&c=d#e=f&g=h'),
|
||||
extractURLParameters('http://yandex.ru/?a=b&c=d#e'),
|
||||
extractURLParameters('http://yandex.ru/?a=b&c=d#e&g=h'),
|
||||
extractURLParameters('http://yandex.ru/?a=b&c=d#test?e=f&g=h');
|
||||
|
||||
SELECT
|
||||
extractURLParameterNames('http://yandex.ru/?a=b&c=d'),
|
||||
extractURLParameterNames('http://yandex.ru/?a=b&c=d#e=f'),
|
||||
extractURLParameterNames('http://yandex.ru/?a&c=d#e=f'),
|
||||
extractURLParameterNames('http://yandex.ru/?a=b&c=d#e=f&g=h'),
|
||||
extractURLParameterNames('http://yandex.ru/?a=b&c=d#e'),
|
||||
extractURLParameterNames('http://yandex.ru/?a=b&c=d#e&g=h'),
|
||||
extractURLParameterNames('http://yandex.ru/?a=b&c=d#test?e=f&g=h');
|
||||
|
||||
SELECT
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d', 'a'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d', 'c'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e=f', 'e'),
|
||||
extractURLParameter('http://yandex.ru/?a&c=d#e=f', 'a'),
|
||||
extractURLParameter('http://yandex.ru/?a&c=d#e=f', 'c'),
|
||||
extractURLParameter('http://yandex.ru/?a&c=d#e=f', 'e'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e=f&g=h', 'g'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e', 'a'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e', 'c'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e', 'e'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e&g=h', 'c'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e&g=h', 'e'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#e&g=h', 'g'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#test?e=f&g=h', 'test'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#test?e=f&g=h', 'e'),
|
||||
extractURLParameter('http://yandex.ru/?a=b&c=d#test?e=f&g=h', 'g');
|
||||
|
||||
SELECT
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d', 'a'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d', 'c'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e=f', 'e'),
|
||||
cutURLParameter('http://yandex.ru/?a&c=d#e=f', 'a'),
|
||||
cutURLParameter('http://yandex.ru/?a&c=d#e=f', 'c'),
|
||||
cutURLParameter('http://yandex.ru/?a&c=d#e=f', 'e'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e=f&g=h', 'g'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e', 'a'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e', 'c'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e', 'e'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e&g=h', 'c'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e&g=h', 'e'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#e&g=h', 'g'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#test?e=f&g=h', 'test'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#test?e=f&g=h', 'e'),
|
||||
cutURLParameter('http://yandex.ru/?a=b&c=d#test?e=f&g=h', 'g');
|
||||
|
||||
|
||||
SELECT
|
||||
extractURLParameters(materialize('http://yandex.ru/?a=b&c=d')),
|
||||
extractURLParameters(materialize('http://yandex.ru/?a=b&c=d#e=f')),
|
||||
extractURLParameters(materialize('http://yandex.ru/?a&c=d#e=f')),
|
||||
extractURLParameters(materialize('http://yandex.ru/?a=b&c=d#e=f&g=h')),
|
||||
extractURLParameters(materialize('http://yandex.ru/?a=b&c=d#e')),
|
||||
extractURLParameters(materialize('http://yandex.ru/?a=b&c=d#e&g=h')),
|
||||
extractURLParameters(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'));
|
||||
|
||||
SELECT
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a=b&c=d')),
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a=b&c=d#e=f')),
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a&c=d#e=f')),
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a=b&c=d#e=f&g=h')),
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a=b&c=d#e')),
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a=b&c=d#e&g=h')),
|
||||
extractURLParameterNames(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'));
|
||||
|
||||
SELECT
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d'), 'a'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d'), 'c'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e=f'), 'e'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a&c=d#e=f'), 'a'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a&c=d#e=f'), 'c'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a&c=d#e=f'), 'e'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e=f&g=h'), 'g'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e'), 'a'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e'), 'c'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e'), 'e'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e&g=h'), 'c'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e&g=h'), 'e'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#e&g=h'), 'g'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'), 'test'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'), 'e'),
|
||||
extractURLParameter(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'), 'g');
|
||||
|
||||
SELECT
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d'), 'a'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d'), 'c'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e=f'), 'e'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a&c=d#e=f'), 'a'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a&c=d#e=f'), 'c'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a&c=d#e=f'), 'e'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e=f&g=h'), 'g'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e'), 'a'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e'), 'c'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e'), 'e'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e&g=h'), 'c'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e&g=h'), 'e'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#e&g=h'), 'g'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'), 'test'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'), 'e'),
|
||||
cutURLParameter(materialize('http://yandex.ru/?a=b&c=d#test?e=f&g=h'), 'g');
|
Loading…
Reference in New Issue
Block a user