Closed
Description
If there's Range in the Request header, it always failed with 416 status.
In my case, using Visual Studio 2022 C++, the value -1 is the same as SIZE_MAX
in range_error
function,
ssize_t prev_first_pos = -1;
ssize_t prev_last_pos = -1;
The comparision with these values always be the same or less.
inline bool range_error(Request &req, Response &res) {
if (!req.ranges.empty() && 200 <= res.status && res.status < 300) {
ssize_t contant_len = static_cast<ssize_t>(
res.content_length_ ? res.content_length_ : res.body.size());
ssize_t prev_first_pos = -1; // The value -1 is the same as SIZE_MAX
ssize_t prev_last_pos = -1;
size_t overwrapping_count = 0;
// NOTE: The following Range check is based on '14.2. Range' in RFC 9110
// 'HTTP Semantics' to avoid potential denial-of-service attacks.
// https://www.rfc-editor.org/rfc/rfc9110#section-14.2
// Too many ranges
if (req.ranges.size() > CPPHTTPLIB_RANGE_MAX_COUNT) { return true; }
for (auto &r : req.ranges) {
auto &first_pos = r.first;
auto &last_pos = r.second;
if (first_pos == -1 && last_pos == -1) {
first_pos = 0;
last_pos = contant_len;
}
if (first_pos == -1) {
first_pos = contant_len - last_pos;
last_pos = contant_len - 1;
}
if (last_pos == -1) { last_pos = contant_len - 1; }
// Range must be within content length
if (!(0 <= first_pos && first_pos <= last_pos &&
last_pos <= contant_len - 1)) {
return true;
}
// Ranges must be in ascending order
if (first_pos <= prev_first_pos) { return true; } // so this condition always true
// Request must not have more than two overlapping ranges
if (first_pos <= prev_last_pos) { // it's the same as here
overwrapping_count++;
if (overwrapping_count > 2) { return true; }
}
prev_first_pos = (std::max)(prev_first_pos, first_pos);
prev_last_pos = (std::max)(prev_last_pos, last_pos);
}
}
return false;
}