mirror of
https://github.com/boostorg/beast.git
synced 2025-08-03 14:54:32 +02:00
@@ -1,6 +1,7 @@
|
||||
Version 186:
|
||||
|
||||
* basic_fields uses intrusive base hooks
|
||||
* Fix parsing of out-of-bounds hex values
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
* ([issue 1270]) `basic_fields` uses intrusive base hooks
|
||||
|
||||
* ([issue 1267]) Fix parsing of out-of-bounds hex values
|
||||
|
||||
* Workaround for http-server-fast and libstdc++
|
||||
|
||||
|
||||
|
@@ -35,6 +35,12 @@ struct basic_parser_base
|
||||
//
|
||||
static std::size_t constexpr max_obs_fold = 4096;
|
||||
|
||||
template<class T>
|
||||
struct is_unsigned_integer:
|
||||
std::integral_constant<bool,
|
||||
std::numeric_limits<T>::is_integer &&
|
||||
! std::numeric_limits<T>::is_signed> {};
|
||||
|
||||
enum class state
|
||||
{
|
||||
nothing_yet = 0,
|
||||
@@ -301,9 +307,7 @@ struct basic_parser_base
|
||||
|
||||
template<class Iter, class T>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::numeric_limits<T>::is_integer &&
|
||||
! std::numeric_limits<T>::is_signed, bool>::type
|
||||
typename std::enable_if<is_unsigned_integer<T>::value, bool>::type
|
||||
parse_dec(Iter it, Iter last, T& v)
|
||||
{
|
||||
if(it == last)
|
||||
@@ -325,24 +329,26 @@ struct basic_parser_base
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Iter, class Unsigned>
|
||||
template<class Iter, class T>
|
||||
static
|
||||
bool
|
||||
parse_hex(Iter& it, Unsigned& v)
|
||||
typename std::enable_if<is_unsigned_integer<T>::value, bool>::type
|
||||
parse_hex(Iter& it, T& v)
|
||||
{
|
||||
unsigned char d;
|
||||
if(! unhex(d, *it))
|
||||
return false;
|
||||
v = d;
|
||||
for(;;)
|
||||
T tmp = 0;
|
||||
do
|
||||
{
|
||||
if(! unhex(d, *++it))
|
||||
break;
|
||||
auto const v0 = v;
|
||||
v = 16 * v + d;
|
||||
if(v < v0)
|
||||
if(tmp > (std::numeric_limits<T>::max)() / 16)
|
||||
return false;
|
||||
tmp *= 16;
|
||||
if((std::numeric_limits<T>::max)() - tmp < d)
|
||||
return false;
|
||||
tmp += d;
|
||||
}
|
||||
while(unhex(d, *++it));
|
||||
v = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1249,6 +1249,40 @@ public:
|
||||
bad ("4294967296");
|
||||
}
|
||||
|
||||
void
|
||||
testIssue1267()
|
||||
{
|
||||
using base = detail::basic_parser_base;
|
||||
auto const good =
|
||||
[&](string_view s, std::uint64_t v0)
|
||||
{
|
||||
std::uint64_t v;
|
||||
auto it = s.begin();
|
||||
auto const result =
|
||||
base::parse_hex(it, v);
|
||||
if(BEAST_EXPECTS(result, s))
|
||||
BEAST_EXPECTS(v == v0, s);
|
||||
};
|
||||
auto const bad =
|
||||
[&](string_view s)
|
||||
{
|
||||
std::uint64_t v;
|
||||
auto it = s.begin();
|
||||
auto const result =
|
||||
base::parse_hex(it, v);
|
||||
BEAST_EXPECTS(! result, s);
|
||||
};
|
||||
good("f\r\n", 15);
|
||||
good("ff\r\n", 255);
|
||||
good("ffff\r\n", 65535);
|
||||
good("ffffffffr\n", 4294967295);
|
||||
good("ffffffffffffffff\r\n", 18446744073709551615ULL);
|
||||
bad ("\r\n");
|
||||
bad ("g\r\n");
|
||||
bad ("10000000000000000\r\n");
|
||||
bad ("ffffffffffffffffffffff\r\n");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
@@ -1274,6 +1308,7 @@ public:
|
||||
testFuzz();
|
||||
testRegression1();
|
||||
testIssue1211();
|
||||
testIssue1267();
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user