From fea2ec311f3ebf14dd390bbefb0a4fbbb7ec984b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 4 Feb 2025 14:12:20 +0100 Subject: [PATCH 1/2] fix(mem): memory management improvements: - abort request on failed allocations - std::vector => std::list for _pathParams - limit the use of std::vector in middleware code that could execute in the context of a request --- examples/Auth/Auth.ino | 4 ++- examples/CORS/CORS.ino | 4 ++- examples/CatchAllHandler/CatchAllHandler.ino | 4 ++- examples/ChunkResponse/ChunkResponse.ino | 4 ++- examples/EndBegin/EndBegin.ino | 4 ++- examples/Filters/Filters.ino | 4 ++- examples/FlashResponse/FlashResponse.ino | 4 ++- .../HeaderManipulation/HeaderManipulation.ino | 4 ++- examples/Json/Json.ino | 4 ++- examples/Logging/Logging.ino | 4 ++- examples/MessagePack/MessagePack.ino | 4 ++- examples/Middleware/Middleware.ino | 4 ++- examples/Params/Params.ino | 4 ++- examples/RateLimit/RateLimit.ino | 4 ++- examples/Redirect/Redirect.ino | 4 ++- .../ResumableDownload/ResumableDownload.ino | 4 ++- examples/Rewrite/Rewrite.ino | 4 ++- .../SkipServerMiddleware.ino | 4 ++- examples/StaticFile/StaticFile.ino | 4 ++- examples/Templates/Templates.ino | 4 ++- src/AsyncEventSource.cpp | 8 ++++- src/AsyncJson.cpp | 3 +- src/AsyncMessagePack.cpp | 3 +- src/AsyncWebHeader.cpp | 2 +- src/AsyncWebSocket.cpp | 17 ++++++--- src/ESPAsyncWebServer.h | 10 +++--- src/Middleware.cpp | 18 +++++++--- src/WebAuthentication.cpp | 10 +++--- src/WebHandlers.cpp | 17 ++++++++- src/WebRequest.cpp | 35 +++++++++++-------- src/WebResponses.cpp | 5 +-- src/WebServer.cpp | 29 +++++++++++---- 32 files changed, 171 insertions(+), 66 deletions(-) diff --git a/examples/Auth/Auth.ino b/examples/Auth/Auth.ino index acc842fc..8403e47e 100644 --- a/examples/Auth/Auth.ino +++ b/examples/Auth/Auth.ino @@ -152,4 +152,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/CORS/CORS.ino b/examples/CORS/CORS.ino index 6815c611..8376da5f 100644 --- a/examples/CORS/CORS.ino +++ b/examples/CORS/CORS.ino @@ -55,4 +55,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/CatchAllHandler/CatchAllHandler.ino b/examples/CatchAllHandler/CatchAllHandler.ino index 1d70cab1..8ee657b0 100644 --- a/examples/CatchAllHandler/CatchAllHandler.ino +++ b/examples/CatchAllHandler/CatchAllHandler.ino @@ -128,4 +128,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/ChunkResponse/ChunkResponse.ino b/examples/ChunkResponse/ChunkResponse.ino index f78963e2..9b4df2c4 100644 --- a/examples/ChunkResponse/ChunkResponse.ino +++ b/examples/ChunkResponse/ChunkResponse.ino @@ -135,4 +135,6 @@ void setup() { server.begin(); } -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/EndBegin/EndBegin.ino b/examples/EndBegin/EndBegin.ino index 3b61366d..1f0de8ba 100644 --- a/examples/EndBegin/EndBegin.ino +++ b/examples/EndBegin/EndBegin.ino @@ -44,4 +44,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 07a103ce..d5cca803 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -131,4 +131,6 @@ void setup() { // ESP.restart(); } -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/FlashResponse/FlashResponse.ino b/examples/FlashResponse/FlashResponse.ino index 93aaf069..a2f98712 100644 --- a/examples/FlashResponse/FlashResponse.ino +++ b/examples/FlashResponse/FlashResponse.ino @@ -102,4 +102,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/HeaderManipulation/HeaderManipulation.ino b/examples/HeaderManipulation/HeaderManipulation.ino index 2723efbb..c57a5353 100644 --- a/examples/HeaderManipulation/HeaderManipulation.ino +++ b/examples/HeaderManipulation/HeaderManipulation.ino @@ -83,4 +83,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Json/Json.ino b/examples/Json/Json.ino index 7ba752e9..d8111167 100644 --- a/examples/Json/Json.ino +++ b/examples/Json/Json.ino @@ -85,4 +85,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Logging/Logging.ino b/examples/Logging/Logging.ino index 4249adce..51f64ffc 100644 --- a/examples/Logging/Logging.ino +++ b/examples/Logging/Logging.ino @@ -44,4 +44,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/MessagePack/MessagePack.ino b/examples/MessagePack/MessagePack.ino index a8fda5d5..96bf8ae7 100644 --- a/examples/MessagePack/MessagePack.ino +++ b/examples/MessagePack/MessagePack.ino @@ -83,4 +83,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Middleware/Middleware.ino b/examples/Middleware/Middleware.ino index 1a54392e..9c929036 100644 --- a/examples/Middleware/Middleware.ino +++ b/examples/Middleware/Middleware.ino @@ -77,4 +77,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Params/Params.ino b/examples/Params/Params.ino index f15efcf9..e3336846 100644 --- a/examples/Params/Params.ino +++ b/examples/Params/Params.ino @@ -117,4 +117,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/RateLimit/RateLimit.ino b/examples/RateLimit/RateLimit.ino index 86c25148..87e129d7 100644 --- a/examples/RateLimit/RateLimit.ino +++ b/examples/RateLimit/RateLimit.ino @@ -59,4 +59,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Redirect/Redirect.ino b/examples/Redirect/Redirect.ino index b26320ca..383dadaa 100644 --- a/examples/Redirect/Redirect.ino +++ b/examples/Redirect/Redirect.ino @@ -43,4 +43,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/ResumableDownload/ResumableDownload.ino b/examples/ResumableDownload/ResumableDownload.ino index bbf6f166..9f8bdf34 100644 --- a/examples/ResumableDownload/ResumableDownload.ino +++ b/examples/ResumableDownload/ResumableDownload.ino @@ -56,4 +56,6 @@ void setup() { server.begin(); } -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Rewrite/Rewrite.ino b/examples/Rewrite/Rewrite.ino index 3db89628..195beb26 100644 --- a/examples/Rewrite/Rewrite.ino +++ b/examples/Rewrite/Rewrite.ino @@ -47,4 +47,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/SkipServerMiddleware/SkipServerMiddleware.ino b/examples/SkipServerMiddleware/SkipServerMiddleware.ino index 55f32e6c..88cfbe0b 100644 --- a/examples/SkipServerMiddleware/SkipServerMiddleware.ino +++ b/examples/SkipServerMiddleware/SkipServerMiddleware.ino @@ -68,4 +68,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/StaticFile/StaticFile.ino b/examples/StaticFile/StaticFile.ino index 7ff2131b..dd83843e 100644 --- a/examples/StaticFile/StaticFile.ino +++ b/examples/StaticFile/StaticFile.ino @@ -117,4 +117,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/examples/Templates/Templates.ino b/examples/Templates/Templates.ino index e0d0173a..bfbe86ea 100644 --- a/examples/Templates/Templates.ino +++ b/examples/Templates/Templates.ino @@ -94,4 +94,6 @@ void setup() { } // not needed -void loop() {} +void loop() { + delay(100); +} diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index df61714d..c8758206 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -26,7 +26,7 @@ static String generateEventMessage(const char *message, const char *event, uint3 if (!str.reserve(len)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif return emptyString; } @@ -358,6 +358,12 @@ void AsyncEventSourceClient::set_max_inflight_bytes(size_t value) { void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { AsyncAuthorizationMiddleware *m = new AsyncAuthorizationMiddleware(401, cb); + if (!m) { +#ifdef ESP32 + log_e("Failed to allocate"); +#endif + return; + } m->_freeOnRemoval = true; addMiddleware(m); } diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index ce12a694..b8d014b2 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -152,8 +152,9 @@ void AsyncCallbackJsonWebHandler::handleBody(AsyncWebServerRequest *request, uin request->_tempObject = malloc(total); if (request->_tempObject == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + request->abort(); return; } } diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp index f8cb0387..0c6faa10 100644 --- a/src/AsyncMessagePack.cpp +++ b/src/AsyncMessagePack.cpp @@ -104,8 +104,9 @@ void AsyncCallbackMessagePackWebHandler::handleBody(AsyncWebServerRequest *reque request->_tempObject = malloc(total); if (request->_tempObject == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + request->abort(); return; } } diff --git a/src/AsyncWebHeader.cpp b/src/AsyncWebHeader.cpp index 50747b84..6d82f749 100644 --- a/src/AsyncWebHeader.cpp +++ b/src/AsyncWebHeader.cpp @@ -25,7 +25,7 @@ String AsyncWebHeader::toString() const { str.concat(asyncsrv::T_rn); } else { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif } return str; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 64149c98..4d35bbbf 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -67,8 +67,9 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool uint8_t *buf = (uint8_t *)malloc(headLen); if (buf == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + client->abort(); return 0; } @@ -170,7 +171,7 @@ class AsyncWebSocketControl { if (_data == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif _len = 0; } else { @@ -522,7 +523,8 @@ void AsyncWebSocketClient::close(uint16_t code, const char *message) { return; } else { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); + _client->abort(); #endif } } @@ -1252,6 +1254,13 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) { } const AsyncWebHeader *key = request->getHeader(WS_STR_KEY); AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); + if (response == NULL) { +#ifdef ESP32 + log_e("Failed to allocate"); +#endif + request->abort(); + return; + } if (request->hasHeader(WS_STR_PROTOCOL)) { const AsyncWebHeader *protocol = request->getHeader(WS_STR_PROTOCOL); // ToDo: check protocol @@ -1298,7 +1307,7 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String &key, AsyncWebSocket #else String k; if (!k.reserve(key.length() + WS_STR_UUID_LEN)) { - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); return; } k.concat(key); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 17f5181e..aa66054d 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -218,7 +218,7 @@ class AsyncWebServerRequest { std::list _headers; std::list _params; - std::vector _pathParams; + std::list _pathParams; std::unordered_map, std::equal_to> _attributes; @@ -790,13 +790,13 @@ class AsyncHeaderFreeMiddleware : public AsyncMiddleware { _toKeep.push_back(name); } void unKeep(const char *name) { - _toKeep.erase(std::remove(_toKeep.begin(), _toKeep.end(), name), _toKeep.end()); + _toKeep.remove(name); } void run(AsyncWebServerRequest *request, ArMiddlewareNext next); private: - std::vector _toKeep; + std::list _toKeep; }; // filter out specific headers from the incoming request @@ -806,13 +806,13 @@ class AsyncHeaderFilterMiddleware : public AsyncMiddleware { _toRemove.push_back(name); } void unFilter(const char *name) { - _toRemove.erase(std::remove(_toRemove.begin(), _toRemove.end(), name), _toRemove.end()); + _toRemove.remove(name); } void run(AsyncWebServerRequest *request, ArMiddlewareNext next); private: - std::vector _toRemove; + std::list _toRemove; }; // curl-like logging of incoming requests diff --git a/src/Middleware.cpp b/src/Middleware.cpp index 77e94c4a..71fe43c6 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -14,6 +14,12 @@ AsyncMiddlewareChain::~AsyncMiddlewareChain() { void AsyncMiddlewareChain::addMiddleware(ArMiddlewareCallback fn) { AsyncMiddlewareFunction *m = new AsyncMiddlewareFunction(fn); + if (!m) { +#ifdef ESP32 + log_e("Failed to allocate"); +#endif + return; + } m->_freeOnRemoval = true; _middlewares.emplace_back(m); } @@ -140,20 +146,22 @@ void AsyncAuthenticationMiddleware::run(AsyncWebServerRequest *request, ArMiddle } void AsyncHeaderFreeMiddleware::run(AsyncWebServerRequest *request, ArMiddlewareNext next) { - std::vector reqHeaders; - request->getHeaderNames(reqHeaders); - for (const char *h : reqHeaders) { + std::list toRemove; + for (auto &h : request->getHeaders()) { bool keep = false; for (const char *k : _toKeep) { - if (strcasecmp(h, k) == 0) { + if (strcasecmp(h.name().c_str(), k) == 0) { keep = true; break; } } if (!keep) { - request->removeHeader(h); + toRemove.push_back(h.name().c_str()); } } + for (const char *h : toRemove) { + request->removeHeader(h); + } next(); } diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index c80f24ba..f5a2aacb 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -87,7 +87,7 @@ String genRandomMD5() { char *out = (char *)malloc(33); if (out == NULL || !getMD5((uint8_t *)(&r), 4, out)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif return emptyString; } @@ -100,7 +100,7 @@ static String stringMD5(const String &in) { char *out = (char *)malloc(33); if (out == NULL || !getMD5((uint8_t *)(in.c_str()), in.length(), out)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif return emptyString; } @@ -116,7 +116,7 @@ String generateDigestHash(const char *username, const char *password, const char char *out = (char *)malloc(33); if (out == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif return emptyString; } @@ -124,7 +124,7 @@ String generateDigestHash(const char *username, const char *password, const char String in; if (!in.reserve(strlen(username) + strlen(realm) + strlen(password) + 2)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif free(out); return emptyString; @@ -138,7 +138,7 @@ String generateDigestHash(const char *username, const char *password, const char if (!getMD5((uint8_t *)(in.c_str()), in.length(), out)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif free(out); return emptyString; diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 856ca85d..d92a7ea9 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -13,6 +13,12 @@ AsyncWebHandler &AsyncWebHandler::setFilter(ArRequestFilterFunction fn) { AsyncWebHandler &AsyncWebHandler::setAuthentication(const char *username, const char *password, AsyncAuthType authMethod) { if (!_authMiddleware) { _authMiddleware = new AsyncAuthenticationMiddleware(); + if (!_authMiddleware) { +#ifdef ESP32 + log_e("Failed to allocate"); +#endif + return *this; + } _authMiddleware->_freeOnRemoval = true; addMiddleware(_authMiddleware); } @@ -174,8 +180,9 @@ bool AsyncStaticWebHandler::_searchFile(AsyncWebServerRequest *request, const St char *_tempPath = (char *)malloc(pathLen + 1); if (_tempPath == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + request->abort(); request->_tempFile.close(); return false; } @@ -242,6 +249,14 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) { response = new AsyncFileResponse(request->_tempFile, filename, emptyString, false, _callback); } + if (!response) { +#ifdef ESP32 + log_e("Failed to allocate"); +#endif + request->abort(); + return; + } + response->addHeader(T_ETag, etag.c_str()); if (_last_modified.length()) { diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 9888e70d..5c3cfa9b 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -116,7 +116,7 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len) { log_d("SSL/TLS handshake detected: resetting connection"); #endif _parseState = PARSE_REQ_FAIL; - _client->abort(); + abort(); return; } #endif @@ -131,7 +131,7 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len) { // Check for null characters in header if (!str[i]) { _parseState = PARSE_REQ_FAIL; - _client->abort(); + abort(); return; } if (str[i] == '\n') { @@ -143,10 +143,10 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len) { str[len - 1] = 0; if (!_temp.reserve(_temp.length() + len)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif _parseState = PARSE_REQ_FAIL; - _client->abort(); + abort(); return; } _temp.concat(str); @@ -539,9 +539,10 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { _itemBuffer = (uint8_t *)malloc(RESPONSE_STREAM_BUFFER_SIZE); if (_itemBuffer == NULL) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif _multiParseState = PARSE_ERROR; + abort(); return; } _itemBufferIndex = 0; @@ -652,13 +653,13 @@ void AsyncWebServerRequest::_parseLine() { if (_parseState == PARSE_REQ_START) { if (!_temp.length()) { _parseState = PARSE_REQ_FAIL; - _client->abort(); + abort(); } else { if (_parseReqHead()) { _parseState = PARSE_REQ_HEADERS; } else { _parseState = PARSE_REQ_FAIL; - _client->abort(); + abort(); } } return; @@ -795,12 +796,11 @@ const AsyncWebHeader *AsyncWebServerRequest::getHeader(size_t num) const { } size_t AsyncWebServerRequest::getHeaderNames(std::vector &names) const { - const size_t size = _headers.size(); - names.reserve(size); + const size_t size = names.size(); for (const auto &h : _headers) { names.push_back(h.name().c_str()); } - return size; + return names.size() - size; } bool AsyncWebServerRequest::removeHeader(const char *name) { @@ -1002,8 +1002,9 @@ void AsyncWebServerRequest::requestAuthentication(AsyncAuthType method, const ch r->addHeader(T_WWW_AUTH, header.c_str()); } else { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + abort(); } break; @@ -1027,8 +1028,9 @@ void AsyncWebServerRequest::requestAuthentication(AsyncAuthType method, const ch r->addHeader(T_WWW_AUTH, header.c_str()); } else { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + abort(); } } break; @@ -1078,7 +1080,12 @@ const String &AsyncWebServerRequest::argName(size_t i) const { } const String &AsyncWebServerRequest::pathArg(size_t i) const { - return i < _pathParams.size() ? _pathParams[i] : emptyString; + if (i >= _pathParams.size()) { + return emptyString; + } + auto it = _pathParams.begin(); + std::advance(it, i); + return *it; } const String &AsyncWebServerRequest::header(const char *name) const { @@ -1110,7 +1117,7 @@ String AsyncWebServerRequest::urlDecode(const String &text) const { // Allocate the string internal buffer - never longer from source text if (!decoded.reserve(len)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif return emptyString; } diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 1d1f8158..f5d46530 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -409,8 +409,9 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u uint8_t *buf = (uint8_t *)malloc(outLen + headLen); if (!buf) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif + request->abort(); return 0; } @@ -821,7 +822,7 @@ AsyncResponseStream::AsyncResponseStream(const char *contentType, size_t bufferS _contentType = contentType; if (!_content.reserve(bufferSize)) { #ifdef ESP32 - log_e("Failed to allocate buffer"); + log_e("Failed to allocate"); #endif } } diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 2bcd2de6..2f931d8c 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -30,6 +30,12 @@ const char *fs::FileOpenMode::append = "a"; AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) { _catchAllHandler = new AsyncCallbackWebHandler(); + if (!_catchAllHandler) { +#ifdef ESP32 + log_e("Failed to allocate"); +#endif + return; + } _server.onClient( [](void *s, AsyncClient *c) { if (c == NULL) { @@ -50,6 +56,7 @@ AsyncWebServer::~AsyncWebServer() { reset(); end(); delete _catchAllHandler; + _catchAllHandler = nullptr; // Prevent potential use-after-free } AsyncWebRewrite &AsyncWebServer::addRewrite(std::shared_ptr rewrite) { @@ -120,6 +127,8 @@ void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request) { } void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request) { + // the last rewrite that matches the request will be used + // we do not break the loop to allow for multiple rewrites to be applied and only the last one to be used (allows overriding) for (const auto &r : _rewrites) { if (r->match(request)) { request->_url = r->toUrl(); @@ -159,15 +168,21 @@ AsyncStaticWebHandler &AsyncWebServer::serveStatic(const char *uri, fs::FS &fs, } void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn) { - _catchAllHandler->onRequest(fn); + if (_catchAllHandler) { + _catchAllHandler->onRequest(fn); + } } void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn) { - _catchAllHandler->onUpload(fn); + if (_catchAllHandler) { + _catchAllHandler->onUpload(fn); + } } void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn) { - _catchAllHandler->onBody(fn); + if (_catchAllHandler) { + _catchAllHandler->onBody(fn); + } } AsyncWebHandler &AsyncWebServer::catchAllHandler() const { @@ -178,7 +193,9 @@ void AsyncWebServer::reset() { _rewrites.clear(); _handlers.clear(); - _catchAllHandler->onRequest(NULL); - _catchAllHandler->onUpload(NULL); - _catchAllHandler->onBody(NULL); + if (_catchAllHandler) { + _catchAllHandler->onRequest(NULL); + _catchAllHandler->onUpload(NULL); + _catchAllHandler->onBody(NULL); + } } From 18cb706ca9be4d4430099020eceac542ee181743 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 6 Feb 2025 11:02:40 +0100 Subject: [PATCH 2/2] Further adjustments --- src/AsyncEventSource.cpp | 6 ------ src/AsyncWebSocket.cpp | 16 ++-------------- src/Middleware.cpp | 6 ------ src/WebHandlers.cpp | 6 ------ src/WebServer.cpp | 26 ++++++-------------------- 5 files changed, 8 insertions(+), 52 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index c8758206..797c5d13 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -358,12 +358,6 @@ void AsyncEventSourceClient::set_max_inflight_bytes(size_t value) { void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { AsyncAuthorizationMiddleware *m = new AsyncAuthorizationMiddleware(401, cb); - if (!m) { -#ifdef ESP32 - log_e("Failed to allocate"); -#endif - return; - } m->_freeOnRemoval = true; addMiddleware(m); } diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 4d35bbbf..5e93e794 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1270,23 +1270,11 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) { } AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(size_t size) { - AsyncWebSocketMessageBuffer *buffer = new AsyncWebSocketMessageBuffer(size); - if (buffer->length() != size) { - delete buffer; - return nullptr; - } else { - return buffer; - } + return new AsyncWebSocketMessageBuffer(size); } AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(const uint8_t *data, size_t size) { - AsyncWebSocketMessageBuffer *buffer = new AsyncWebSocketMessageBuffer(data, size); - if (buffer->length() != size) { - delete buffer; - return nullptr; - } else { - return buffer; - } + return new AsyncWebSocketMessageBuffer(data, size); } /* diff --git a/src/Middleware.cpp b/src/Middleware.cpp index 71fe43c6..890303de 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -14,12 +14,6 @@ AsyncMiddlewareChain::~AsyncMiddlewareChain() { void AsyncMiddlewareChain::addMiddleware(ArMiddlewareCallback fn) { AsyncMiddlewareFunction *m = new AsyncMiddlewareFunction(fn); - if (!m) { -#ifdef ESP32 - log_e("Failed to allocate"); -#endif - return; - } m->_freeOnRemoval = true; _middlewares.emplace_back(m); } diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index d92a7ea9..8ffe0697 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -13,12 +13,6 @@ AsyncWebHandler &AsyncWebHandler::setFilter(ArRequestFilterFunction fn) { AsyncWebHandler &AsyncWebHandler::setAuthentication(const char *username, const char *password, AsyncAuthType authMethod) { if (!_authMiddleware) { _authMiddleware = new AsyncAuthenticationMiddleware(); - if (!_authMiddleware) { -#ifdef ESP32 - log_e("Failed to allocate"); -#endif - return *this; - } _authMiddleware->_freeOnRemoval = true; addMiddleware(_authMiddleware); } diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 2f931d8c..7fc54bf1 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -30,12 +30,6 @@ const char *fs::FileOpenMode::append = "a"; AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) { _catchAllHandler = new AsyncCallbackWebHandler(); - if (!_catchAllHandler) { -#ifdef ESP32 - log_e("Failed to allocate"); -#endif - return; - } _server.onClient( [](void *s, AsyncClient *c) { if (c == NULL) { @@ -168,21 +162,15 @@ AsyncStaticWebHandler &AsyncWebServer::serveStatic(const char *uri, fs::FS &fs, } void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn) { - if (_catchAllHandler) { - _catchAllHandler->onRequest(fn); - } + _catchAllHandler->onRequest(fn); } void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn) { - if (_catchAllHandler) { - _catchAllHandler->onUpload(fn); - } + _catchAllHandler->onUpload(fn); } void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn) { - if (_catchAllHandler) { - _catchAllHandler->onBody(fn); - } + _catchAllHandler->onBody(fn); } AsyncWebHandler &AsyncWebServer::catchAllHandler() const { @@ -193,9 +181,7 @@ void AsyncWebServer::reset() { _rewrites.clear(); _handlers.clear(); - if (_catchAllHandler) { - _catchAllHandler->onRequest(NULL); - _catchAllHandler->onUpload(NULL); - _catchAllHandler->onBody(NULL); - } + _catchAllHandler->onRequest(NULL); + _catchAllHandler->onUpload(NULL); + _catchAllHandler->onBody(NULL); }