2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-19 04:42:15 +00:00

refactor: unsafe encoding assumes default options

The private unsafe encoding functions received a parameter to determine the encoding options. However, these functions are never used in any context where these options should diverge from the default values.

This is a partial solution to #828, where `detail/encode.hpp` is the file with the lowest coverage.
This commit is contained in:
alandefreitas
2024-03-12 21:59:29 -03:00
committed by Alan de Freitas
parent 6ec189b931
commit 1a6871339c
4 changed files with 69 additions and 197 deletions

View File

@@ -38,63 +38,32 @@ template<class CharSet>
std::size_t
re_encoded_size_unsafe(
core::string_view s,
CharSet const& unreserved,
encoding_opts opt) noexcept
CharSet const& unreserved) noexcept
{
std::size_t n = 0;
auto const end = s.end();
auto it = s.begin();
if(opt.space_as_plus)
auto const end = s.end();
while(it != end)
{
while(it != end)
if(*it != '%')
{
if(*it != '%')
{
if( unreserved(*it)
|| *it == ' ')
n += 1;
else
n += 3;
++it;
}
if( unreserved(*it) )
n += 1;
else
{
BOOST_ASSERT(end - it >= 3);
BOOST_ASSERT(
grammar::hexdig_value(
it[1]) >= 0);
BOOST_ASSERT(
grammar::hexdig_value(
it[2]) >= 0);
n += 3;
it += 3;
}
++it;
}
}
else
{
while(it != end)
else
{
if(*it != '%')
{
if(unreserved(*it))
n += 1;
else
n += 3;
++it;
}
else
{
BOOST_ASSERT(end - it >= 3);
BOOST_ASSERT(
BOOST_ASSERT(end - it >= 3);
BOOST_ASSERT(
grammar::hexdig_value(
it[1]) >= 0);
BOOST_ASSERT(
it[1]) >= 0);
BOOST_ASSERT(
grammar::hexdig_value(
it[2]) >= 0);
n += 3;
it += 3;
}
it[2]) >= 0);
n += 3;
it += 3;
}
}
return n;
@@ -108,14 +77,13 @@ re_encode_unsafe(
char*& dest_,
char const* const end,
core::string_view s,
CharSet const& unreserved,
encoding_opts opt) noexcept
CharSet const& unreserved) noexcept
{
char const* const hex =
detail::hexdigs[opt.lower_case];
static constexpr bool lower_case = false;
char const* const hex = detail::hexdigs[lower_case];
auto const encode = [end, hex](
char*& dest,
char c0) noexcept
char*& dest,
char c0) noexcept
{
auto c = static_cast<unsigned char>(c0);
ignore_unused(end);
@@ -132,67 +100,30 @@ re_encode_unsafe(
auto const last = s.end();
std::size_t dn = 0;
auto it = s.begin();
if(opt.space_as_plus)
while(it != last)
{
while(it != last)
BOOST_ASSERT(dest != end);
if(*it != '%')
{
BOOST_ASSERT(dest != end);
if(*it != '%')
if(unreserved(*it))
{
if(*it == ' ')
{
*dest++ = '+';
}
else if(unreserved(*it))
{
*dest++ = *it;
}
else
{
encode(dest, *it);
dn += 2;
}
++it;
*dest++ = *it;
}
else
{
*dest++ = *it++;
BOOST_ASSERT(dest != end);
*dest++ = *it++;
BOOST_ASSERT(dest != end);
*dest++ = *it++;
encode(dest, *it);
dn += 2;
}
++it;
}
}
else
{
while(it != last)
else
{
*dest++ = *it++;
BOOST_ASSERT(dest != end);
if(*it != '%')
{
if(unreserved(*it))
{
*dest++ = *it;
}
else
{
encode(dest, *it);
dn += 2;
}
++it;
}
else
{
*dest++ = *it++;
BOOST_ASSERT(dest != end);
*dest++ = *it++;
BOOST_ASSERT(dest != end);
*dest++ = *it++;
dn += 2;
}
*dest++ = *it++;
BOOST_ASSERT(dest != end);
*dest++ = *it++;
dn += 2;
}
}
dest_ = dest;

View File

@@ -300,17 +300,13 @@ measure(std::size_t& n) noexcept
{
if(at_end_)
return false;
encoding_opts opt;
opt.space_as_plus = false;
n += detail::re_encoded_size_unsafe(
s0,
detail::param_key_chars,
opt);
detail::param_key_chars);
if(has_value_)
n += detail::re_encoded_size_unsafe(
s1,
detail::param_value_chars,
opt) + 1; // for '='
detail::param_value_chars) + 1; // for '='
at_end_ = true;
return true;
}
@@ -321,14 +317,11 @@ copy(
char*& dest,
char const* end) noexcept
{
encoding_opts opt;
opt.space_as_plus = false;
detail::re_encode_unsafe(
dest,
end,
s0,
detail::param_key_chars,
opt);
detail::param_key_chars);
if(has_value_)
{
*dest++ = '=';
@@ -336,8 +329,7 @@ copy(
dest,
end,
s1,
detail::param_value_chars,
opt);
detail::param_value_chars);
}
}
@@ -354,17 +346,13 @@ measure_impl(
std::size_t& n,
param_view const& p) noexcept
{
encoding_opts opt;
opt.space_as_plus = false;
n += detail::re_encoded_size_unsafe(
p.key,
detail::param_key_chars,
opt);
detail::param_key_chars);
if(p.has_value)
n += detail::re_encoded_size_unsafe(
p.value,
detail::param_value_chars,
opt) + 1; // for '='
detail::param_value_chars) + 1; // for '='
}
void
@@ -374,14 +362,11 @@ copy_impl(
char const* end,
param_view const& p) noexcept
{
encoding_opts opt;
opt.space_as_plus = false;
detail::re_encode_unsafe(
dest,
end,
p.key,
detail::param_key_chars,
opt);
detail::param_key_chars);
if(p.has_value)
{
*dest++ = '=';
@@ -389,8 +374,7 @@ copy_impl(
dest,
end,
p.value,
detail::param_value_chars,
opt);
detail::param_value_chars);
}
}
@@ -469,12 +453,9 @@ measure(
n += nk_; // skip key
if(has_value_)
{
encoding_opts opt;
opt.space_as_plus = false;
n += detail::re_encoded_size_unsafe(
s0,
detail::param_value_chars,
opt) + 1; // for '='
detail::param_value_chars) + 1; // for '='
}
at_end_ = true;
return true;
@@ -490,14 +471,11 @@ copy(
if(! has_value_)
return;
*dest++ = '=';
encoding_opts opt;
opt.space_as_plus = false;
detail::re_encode_unsafe(
dest,
end,
s0,
detail::param_value_chars,
opt);
detail::param_value_chars);
}
} // detail

View File

@@ -150,14 +150,11 @@ measure(
{
if(at_end_)
return false;
encoding_opts opt;
opt.space_as_plus = false;
n += detail::re_encoded_size_unsafe(
s,
encode_colons ?
nocolon_pchars :
pchars,
opt);
pchars);
at_end_ = true;
return true;
}
@@ -168,16 +165,13 @@ copy(
char*& dest,
char const* end) noexcept
{
encoding_opts opt;
opt.space_as_plus = false;
detail::re_encode_unsafe(
dest,
end,
s,
encode_colons ?
nocolon_pchars :
pchars,
opt);
pchars);
}
//------------------------------------------------
@@ -193,14 +187,11 @@ measure_impl(
core::string_view s,
bool encode_colons) noexcept
{
encoding_opts opt;
opt.space_as_plus = false;
n += detail::re_encoded_size_unsafe(
s,
encode_colons ?
nocolon_pchars :
pchars,
opt);
pchars);
}
void
@@ -211,16 +202,13 @@ copy_impl(
core::string_view s,
bool encode_colons) noexcept
{
encoding_opts opt;
opt.space_as_plus = false;
detail::re_encode_unsafe(
dest,
end,
s,
encode_colons ?
nocolon_pchars :
pchars,
opt);
pchars);
}
} // detail

View File

@@ -389,7 +389,6 @@ set_encoded_userinfo(
pct_string_view s)
{
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const pos = s.find_first_of(':');
if(pos != core::string_view::npos)
{
@@ -399,12 +398,10 @@ set_encoded_userinfo(
auto const n0 =
detail::re_encoded_size_unsafe(
s0,
detail::user_chars,
opt);
detail::user_chars);
auto const n1 =
detail::re_encoded_size_unsafe(s1,
detail::password_chars,
opt);
detail::password_chars);
auto dest =
set_userinfo_impl(n0 + n1 + 1, op);
impl_.decoded_[id_user] =
@@ -412,16 +409,14 @@ set_encoded_userinfo(
dest,
dest + n0,
s0,
detail::user_chars,
opt);
detail::user_chars);
*dest++ = ':';
impl_.decoded_[id_pass] =
detail::re_encode_unsafe(
dest,
dest + n1,
s1,
detail::password_chars,
opt);
detail::password_chars);
impl_.split(id_user, 2 + n0);
}
else
@@ -429,15 +424,14 @@ set_encoded_userinfo(
// user
auto const n =
detail::re_encoded_size_unsafe(
s, detail::user_chars, opt);
s, detail::user_chars);
auto dest = set_userinfo_impl(n, op);
impl_.decoded_[id_user] =
detail::re_encode_unsafe(
dest,
dest + n,
s,
detail::user_chars,
opt);
detail::user_chars);
impl_.split(id_user, 2 + n);
impl_.decoded_[id_pass] = 0;
}
@@ -487,18 +481,16 @@ set_encoded_user(
pct_string_view s)
{
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const n =
detail::re_encoded_size_unsafe(
s, detail::user_chars, opt);
s, detail::user_chars);
auto dest = set_user_impl(n, op);
impl_.decoded_[id_user] =
detail::re_encode_unsafe(
dest,
dest + n,
s,
detail::user_chars,
opt);
detail::user_chars);
BOOST_ASSERT(
impl_.decoded_[id_user] ==
s.decoded_size());
@@ -532,20 +524,17 @@ set_encoded_password(
pct_string_view s)
{
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const n =
detail::re_encoded_size_unsafe(
s,
detail::password_chars,
opt);
detail::password_chars);
auto dest = set_password_impl(n, op);
impl_.decoded_[id_pass] =
detail::re_encode_unsafe(
dest,
dest + n,
s,
detail::password_chars,
opt);
detail::password_chars);
BOOST_ASSERT(
impl_.decoded_[id_pass] ==
s.decoded_size());
@@ -692,17 +681,15 @@ set_encoded_host(
// reg-name
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const n = detail::re_encoded_size_unsafe(
s, detail::host_chars, opt);
s, detail::host_chars);
auto dest = set_host_impl(n, op);
impl_.decoded_[id_host] =
detail::re_encode_unsafe(
dest,
impl_.get(id_path).data(),
s,
detail::host_chars,
opt);
detail::host_chars);
BOOST_ASSERT(impl_.decoded_[id_host] ==
s.decoded_size());
impl_.host_type_ =
@@ -782,17 +769,15 @@ set_encoded_host_address(
// reg-name
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const n = detail::re_encoded_size_unsafe(
s, detail::host_chars, opt);
s, detail::host_chars);
auto dest = set_host_impl(n, op);
impl_.decoded_[id_host] =
detail::re_encode_unsafe(
dest,
impl_.get(id_path).data(),
s,
detail::host_chars,
opt);
detail::host_chars);
BOOST_ASSERT(impl_.decoded_[id_host] ==
s.decoded_size());
impl_.host_type_ =
@@ -916,17 +901,15 @@ set_encoded_host_name(
allowed = allowed - '.';
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const n = detail::re_encoded_size_unsafe(
s, allowed, opt);
s, allowed);
auto dest = set_host_impl(n, op);
impl_.decoded_[id_host] =
detail::re_encode_unsafe(
dest,
dest + n,
s,
allowed,
opt);
allowed);
BOOST_ASSERT(
impl_.decoded_[id_host] ==
s.decoded_size());
@@ -1210,7 +1193,6 @@ set_encoded_path(
pct_string_view s)
{
op_t op(*this, &detail::ref(s));
encoding_opts opt;
//------------------------------------------------
//
@@ -1220,7 +1202,7 @@ set_encoded_path(
// - colons in first segment might need to be re-encoded
// - the path might need to receive a prefix
auto const n = detail::re_encoded_size_unsafe(
s, detail::path_chars, opt);
s, detail::path_chars);
std::size_t n_reencode_colons = 0;
core::string_view first_seg;
if (!has_scheme() &&
@@ -1278,15 +1260,13 @@ set_encoded_path(
dest,
impl_.get(id_query).data(),
first_seg,
detail::segment_chars - ':',
opt);
detail::segment_chars - ':');
impl_.decoded_[id_path] +=
detail::re_encode_unsafe(
dest,
impl_.get(id_query).data(),
s.substr(first_seg.size()),
detail::path_chars,
opt);
detail::path_chars);
BOOST_ASSERT(dest == impl_.get(id_query).data());
BOOST_ASSERT(
impl_.decoded_[id_path] ==
@@ -1358,7 +1338,6 @@ set_encoded_query(
pct_string_view s)
{
op_t op(*this);
encoding_opts opt;
std::size_t n = 0; // encoded size
std::size_t nparam = 1; // param count
auto const end = s.end();
@@ -1400,8 +1379,7 @@ set_encoded_query(
dest,
dest + n,
s,
detail::query_chars,
opt);
detail::query_chars);
BOOST_ASSERT(
impl_.decoded_[id_query] ==
s.decoded_size());
@@ -1505,12 +1483,10 @@ set_encoded_fragment(
pct_string_view s)
{
op_t op(*this, &detail::ref(s));
encoding_opts opt;
auto const n =
detail::re_encoded_size_unsafe(
s,
detail::fragment_chars,
opt);
detail::fragment_chars);
auto dest = resize_impl(
id_frag, n + 1, op);
*dest++ = '#';
@@ -1519,8 +1495,7 @@ set_encoded_fragment(
dest,
dest + n,
s,
detail::fragment_chars,
opt);
detail::fragment_chars);
BOOST_ASSERT(
impl_.decoded_[id_frag] ==
s.decoded_size());