The http_request target asserted that ReadBody() returns an empty string. That held for the libevent-based http_libevent::HTTPRequest, where the harness only parsed the request line and headers and never populated a body. Commit 9c20859b5f (PR #35182) replaced libevent with http_bitcoin::HTTPRequest, and the target was switched over in e427c227fa; its LoadBody() now decodes Content-Length and chunked bodies per RFC 9112, so any fully-parsed request carrying a body trips the stale assertion (e.g. "POST / HTTP/1.1\r\nContent-Length: 3\r\n\r\nabc").
Replace the emptiness check with a framing-consistency check that mirrors LoadBody()'s own branch logic: a chunked body is bounded by MAX_BODY_SIZE, a Content-Length body is exactly that many bytes, and a request with neither framing header has no body. This strengthens the target instead of dropping the assertion.
Steps to reproduce (old assertion):
Build the fuzz binary and pass this input as a file to the http_request target:
POST / HTTP/1.1\r\nContent-Length: 3\r\n\r\nabc
→ test/fuzz/http_request.cpp:49: Assertion 'body.empty()' failed
Testing the fix:
Ran the updated target ~16 min under libFuzzer with ASAN/UBSAN
(14.2M execs, no crashes), plus targeted inputs for each branch:
Content-Length body, chunked, Transfer-Encoding: identity + Content-Length,
no framing headers, and Content-Length: 0. Happy to contribute the repro
input to qa-assets as a follow-up.