fix decodeUrl; decode all values; add more tests

This commit is contained in:
artpaul 2016-12-15 22:12:41 +05:00
parent fea00eb595
commit d3657d311b
3 changed files with 31 additions and 22 deletions

View File

@ -5,12 +5,13 @@
namespace DB
{
template <typename T>
static void decodeUrl(const StringView & url, T & dest, size_t & offset)
/// We assume that size of the buf isn't less than url.size().
static size_t decodeUrl(const StringView & url, char* dst)
{
const char* p = url.data();
const char* st = url.data();
const char* end = url.data() + url.size();
const char* const end = url.data() + url.size();
char* buf = dst;
for (; p < end; ++p)
{
@ -24,15 +25,11 @@ static void decodeUrl(const StringView & url, T & dest, size_t & offset)
{
unsigned char digit = (h << 4) + l;
if (digit < 127) {
dest.resize(dest.size() + p - st + 1);
memcpy(&dest[offset], st, p - st);
offset += p - st;
dest[offset] = digit;
offset++;
st = p + 3;
}
memcpy(buf, st, p - st);
buf += p - st;
*buf = digit;
++buf;
st = p + 3;
}
p += 2;
@ -40,17 +37,16 @@ static void decodeUrl(const StringView & url, T & dest, size_t & offset)
if (st == url.data())
{
dest.resize(dest.size() + url.size() + 1);
memcpy(&dest[offset], url.data(), url.size());
offset += url.size() + 1;
dest[offset - 1] = 0;
memcpy(buf, url.data(), url.size());
return url.size();
}
else if (st < p)
{
dest.resize(dest.size() + p - st);
memcpy(&dest[offset], st, p - st);
offset += p - st;
memcpy(buf, st, p - st);
buf += p - st;
}
return buf - dst;
}
@ -90,8 +86,14 @@ void DecodeURLComponentImpl::vector(const ColumnString::Chars_t & data, const Co
{
const char * current = reinterpret_cast<const char *>(&data[prev_offset]);
const StringView url(current, offsets[i] - prev_offset - 1);
size_t prev_size = res_data.size();
decodeUrl(url, res_data, res_offset);
res_data.resize(prev_size + url.size() + 1);
size_t len = decodeUrl(url, reinterpret_cast<char *>(res_data.data() + res_offset));
res_data.resize(prev_size + len);
res_offset += len;
res_data[res_offset] = 0;
res_offset++;
res_offsets[i] = res_offset;
prev_offset = offsets[i];
@ -102,8 +104,9 @@ void DecodeURLComponentImpl::vector(const ColumnString::Chars_t & data, const Co
void DecodeURLComponentImpl::constant(const std::string & data,
std::string & res_data)
{
size_t offset = 0;
decodeUrl(data, res_data, offset);
res_data.resize(data.size());
size_t len = decodeUrl(data, &res_data[0]);
res_data.resize(len);
}

View File

@ -12,4 +12,7 @@ com
ru
ru
П
%D%9
/?query=hello world+foo+bar
/?query=hello world+foo+bar

View File

@ -15,4 +15,7 @@ SELECT topLevelDomain('http://127.0.0.1:443/') AS Domain;
SELECT topLevelDomain('svn+ssh://example.ru?q=hello%20world') AS Domain;
SELECT topLevelDomain('svn+ssh://example.ru.?q=hello%20world') AS Domain;
SELECT decodeURLComponent('%D0%9F');
SELECT decodeURLComponent('%D%9');
SELECT decodeURLComponent(pathFull('http://127.0.0.1/?query=hello%20world+foo%2Bbar')) AS Path;
SELECT decodeURLComponent(materialize(pathFull('http://127.0.0.1/?query=hello%20world+foo%2Bbar'))) AS Path;