HTTPClient POST body helper can dereference a released unique_ptr
Problem
proxygen::coro::HTTPClient::post() can dereference a null pointer while constructing a non-empty request body. The internal stringToIOBuf() helper evaluates accesses to a std::unique_ptr and release() in the same argument list:
auto strPtr = std::make_unique<std::string>(std::move(str).value());
strBuf = folly::IOBuf::takeOwnership(
strPtr->data(),
strPtr->size(),
[](void*, void* data) { delete static_cast<std::string*>(data); },
strPtr.release());C++ does not specify the order of evaluation of these arguments. If the last argument is evaluated first, release() clears strPtr, and evaluating either of the first two arguments then dereferences null. This is not a coroutine lifetime issue: the problem is within this single call expression.
The code is still present on upstream main at 6bd0ee43ad0709df359f2bcdb9137cc63b0dc43a.
Trigger and observations
An HTTP/1.1 POST to a local server, with a non-empty body, enters this path:
co_await proxygen::coro::HTTPClient::post(
evb, "http://127.0.0.1:8080/anything", "{\"a\":1}",
std::chrono::seconds{5}, false,
{{"content-type", "application/json"}});We observed a SIGSEGV on x86-64 Linux with a dependency based on release v2026.06.29.00; the corresponding test passes on arm64 macOS. The crash's async stack goes through HTTPClient::post(). The innermost CI frames are not symbolized, so this report distinguishes the definite source-level defect from full confirmation of that particular crash location.
GET and empty-body POST requests skip the offending block. A caller can avoid it by constructing an HTTPFixedSource with an owned IOBuf and using the HTTPClient::request() overload that accepts an HTTPSourceHolder.
Suggested fix
Use folly::IOBuf::fromString(std::move(*str)), or evaluate strPtr->data() and strPtr->size() into locals before the takeOwnership() call. In either case, no argument should dereference the pointer that another argument releases.
Source: facebook/proxygen