Skip to content

flag out-of-range Content-Length in get_header_value_u64#2494

Closed
metsw24-max wants to merge 2 commits into
yhirose:masterfrom
metsw24-max:header-u64-overflow
Closed

flag out-of-range Content-Length in get_header_value_u64#2494
metsw24-max wants to merge 2 commits into
yhirose:masterfrom
metsw24-max:header-u64-overflow

Conversation

@metsw24-max

Copy link
Copy Markdown
Contributor

Out-of-range Content-Length silently accepted in get_header_value_u64

The value is parsed with strtoull whose errno is never checked and the 64-bit result is cast straight to size_t, so a length past ULLONG_MAX saturates to SIZE_MAX while one above 2^32 truncates on 32-bit builds, and in both cases is_invalid_value stays clear so read_content and the streaming client use the bogus framing length instead of rejecting it (on 32-bit the truncated Content-Length desyncs the next request on a keep-alive connection). The sibling detail::from_chars already reports result_out_of_range, so this flags the same condition here when errno is ERANGE or the size_t cast loses information, returning SIZE_MAX so the existing > 0 and max_size() guards still see it as oversized.

@yhirose

yhirose commented Jul 12, 2026

Copy link
Copy Markdown
Owner

@metsw24-max thank you for the PR. However, it causes lots of CI errors....

@metsw24-max

Copy link
Copy Markdown
Contributor Author

Sorry about that. Every failure was the same test: OpenStreamMalformedContentLength.OutOfRange asserted the old lenient behaviour, where an out-of-range Content-Length silently clamps to ULLONG_MAX and the stream still opens. With this change the value is flagged invalid, so open_stream now fails cleanly, matching the not-a-number case next to it. I've updated that test's expectation; its original point (no crash from std::stoull) still holds since the process just gets an invalid handle. Ran the OpenStream, GetHeaderValue and BodyReader suites locally with the CI flags and they're green, so CI should be sorted now.

@metsw24-max
metsw24-max force-pushed the header-u64-overflow branch from 1e545d4 to f648fd1 Compare July 13, 2026 07:34
@metsw24-max

Copy link
Copy Markdown
Contributor Author

CI is green now, all 27 checks. After the test fix there was still one red job, ubuntu (mbedtls), but the failure was SSLClientTest.SetCaCertStoreNativeVerifiesLocalServer, a loopback TLS test this change doesn't touch. It binds a fixed port under the parallel runner and master has had the odd one-off mbedtls failure recently, so it looks like a flake; retriggering the run passed everything.

@yhirose

yhirose commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Merged into master as 3adc525 (and the two preceding commits), with the parsing swapped from strtoull to the existing detail::from_chars for size_t-width overflow detection. Thanks for catching this and for the clear write-up on the request-smuggling risk!

@yhirose yhirose closed this Jul 18, 2026
@yhirose

yhirose commented Jul 18, 2026

Copy link
Copy Markdown
Owner

@metsw24-max thank you for your contribution. I decided to use detail::from_chars for consistency.
3adc525

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants