mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-26 12:24:46 +00:00
flag out-of-range Content-Length in get_header_value_u64
This commit is contained in:
1 parent
255c075b82
commit
982235c0a9
2 files changed
+32
-1
No files matched your search
@@ -2957,7 +2957,18 @@ inline size_t get_header_value_u64(const Headers &headers,
|
|||||||
std::advance(it, static_cast<ssize_t>(id));
|
std::advance(it, static_cast<ssize_t>(id));
|
||||||
if (it != rng.second) {
|
if (it != rng.second) {
|
||||||
if (is_numeric(it->second)) {
|
if (is_numeric(it->second)) {
|
||||||
return static_cast<size_t>(std::strtoull(it->second.data(), nullptr, 10));
|
errno = 0;
|
||||||
|
auto val = std::strtoull(it->second.data(), nullptr, 10);
|
||||||
|
auto result = static_cast<size_t>(val);
|
||||||
|
// strtoull saturates to ULLONG_MAX on overflow, and the size_t cast
|
||||||
|
// truncates a value that doesn't fit (a Content-Length above 2^32 wraps
|
||||||
|
// to a small length on 32-bit builds). Either way the framing length
|
||||||
|
// would be wrong, so flag it rather than return a bogus size.
|
||||||
|
if (errno == ERANGE || static_cast<unsigned long long>(result) != val) {
|
||||||
|
is_invalid_value = true;
|
||||||
|
return (std::numeric_limits<size_t>::max)();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
is_invalid_value = true;
|
is_invalid_value = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1300,6 +1300,26 @@ TEST(GetHeaderValueTest, RegularInvalidValueInt) {
|
|||||||
EXPECT_TRUE(is_invalid_value);
|
EXPECT_TRUE(is_invalid_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GetHeaderValueTest, OutOfRangeValueInt) {
|
||||||
|
// An all-digit value that overflows size_t must be reported as invalid, not
|
||||||
|
// silently saturated/truncated: strtoull would otherwise return ULLONG_MAX
|
||||||
|
// (or, on 32-bit builds, the cast would wrap a large length to a small one),
|
||||||
|
// leaving the framing length wrong while is_invalid_value stayed false.
|
||||||
|
Headers headers = {{"Content-Length", "99999999999999999999999999"}};
|
||||||
|
auto is_invalid_value = false;
|
||||||
|
detail::get_header_value_u64(headers, "Content-Length", 0, 0,
|
||||||
|
is_invalid_value);
|
||||||
|
EXPECT_TRUE(is_invalid_value);
|
||||||
|
|
||||||
|
// A well-formed length is unaffected.
|
||||||
|
Headers ok = {{"Content-Length", "1234"}};
|
||||||
|
is_invalid_value = false;
|
||||||
|
auto val = detail::get_header_value_u64(ok, "Content-Length", 0, 0,
|
||||||
|
is_invalid_value);
|
||||||
|
EXPECT_EQ(1234ull, val);
|
||||||
|
EXPECT_FALSE(is_invalid_value);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(GetHeaderValueTest, Range) {
|
TEST(GetHeaderValueTest, Range) {
|
||||||
{
|
{
|
||||||
Headers headers = {make_range_header({{1, -1}})};
|
Headers headers = {make_range_header({{1, -1}})};
|
||||||
|
|||||||
Reference in new issue
Block a user