Fix stack overflow: access URL query directly from req->uri

search_query_sources was copying the URL query string into a 513-byte
stack buffer, then query_key_value added another 513-byte buffer for
the extracted value — 1026 bytes simultaneously on the httpd thread's
limited stack, causing a crash in lwip_select.

The query string already lives in req->uri after the '?'. Access it
directly via pointer instead of copying, eliminating one buffer entirely.
This commit is contained in:
J. Nick Koston
2026-02-11 18:51:45 -06:00
parent 53345724f2
commit 5a88bb6d8a
@@ -408,7 +408,7 @@ AsyncWebParameter *AsyncWebServerRequest::getParam(const char *name) {
/// Search post_query then URL query with a callback.
/// Returns first truthy result, or value-initialized default.
/// Uses stack buffer for URL query to avoid heap allocation.
/// URL query is accessed directly from req->uri to avoid stack buffer copy.
template<typename Func>
static auto search_query_sources(httpd_req_t *req, const std::string &post_query, const char *name, Func func)
-> decltype(func(nullptr, size_t{0}, name)) {
@@ -418,15 +418,17 @@ static auto search_query_sources(httpd_req_t *req, const std::string &post_query
return result;
}
}
auto len = httpd_req_get_url_query_len(req);
// Access query string directly from URI — no copy needed
const char *query = strchr(req->uri, '?');
if (query == nullptr) {
return {};
}
query++; // skip '?'
size_t len = strlen(query);
if (len == 0) {
return {};
}
char buf[AsyncWebServerRequest::URL_BUF_SIZE];
if (httpd_req_get_url_query_str(req, buf, len + 1) != ESP_OK) {
return {};
}
return func(buf, len, name);
return func(query, len, name);
}
optional<std::string> AsyncWebServerRequest::find_query_value_(const char *name) const {