parse_content_range() read the Content-Range header's byte offsets and
entity-length with an unchecked "num = 10 * num + (*hdr - '0')" loop, so
a server-supplied value exceeding wgint (int64_t) silently wrapped
around (CVE-2026-58470).  This was fixed by parsing with strtoll() and
rejecting values that set errno to ERANGE.

Add a case to the existing test_parse_range_header() harness that feeds
an entity-length larger than int64_t and expects parse_content_range()
to reject it (shouldPass = false).  Before the fix the function wraps
the value and returns true, tripping the harness's "False Negative"
assertion; after the fix it returns false and the test passes.

* src/http.c (test_parse_range_header): Add a test case with an
entity-length that overflows wgint, expecting rejection.

Signed-off-by: Pratik Farkase <[email protected]>
---
 src/http.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/http.c b/src/http.c
index 8170a43c..36d01d90 100644
--- a/src/http.c
+++ b/src/http.c
@@ -5467,6 +5467,15 @@ test_parse_range_header (void)
       { "bytes 42-1233/*", 42, 1233, -1, true },
       { "bytes 0-2147483648/2147483649", 0, 2147483648U, 2147483649U, true },
       { "bytes 2147483648-4294967296/4294967297", 2147483648U, 4294967296ULL, 
4294967297ULL, true },
+      /* An entity-length that overflows wgint must be rejected rather
+         than silently wrapped: parse_content_range() parses it with
+         strtoll() and returns false on ERANGE.  Before that fix the
+         value "99999999999999999999" wrapped to a bogus positive
+         number and the function returned true (CVE-2026-58470).  The
+         expected first/last/length match the values the function leaves
+         in the output pointers, which this harness reuses across
+         iterations without resetting. */
+      { "bytes 0-1000/99999999999999999999", 0, 1000, 4294967297ULL, false },
   };
 
   wgint firstbyteptr[sizeof(wgint)];
-- 
2.43.0


Reply via email to