Skip to content

Commit 8a69727

Browse files
committed
fix(mem): Log an error when a memory allocation fails
1 parent 77d8341 commit 8a69727

11 files changed

+156
-50
lines changed

src/AsyncEventSource.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ static String generateEventMessage(const char *message, const char *event, uint3
2424

2525
len += 42; // give it some overhead
2626

27-
str.reserve(len);
27+
if (!str.reserve(len)) {
28+
#ifdef ESP32
29+
log_e("Failed to allocate buffer");
30+
#endif
31+
return emptyString;
32+
}
2833

2934
if (reconnect) {
3035
str += T_retry_;

src/AsyncJson.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ void AsyncCallbackJsonWebHandler::handleBody(AsyncWebServerRequest *request, uin
150150
_contentLength = total;
151151
if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) {
152152
request->_tempObject = malloc(total);
153+
if (request->_tempObject == NULL) {
154+
#ifdef ESP32
155+
log_e("Failed to allocate buffer");
156+
#endif
157+
return;
158+
}
153159
}
154160
if (request->_tempObject != NULL) {
155161
memcpy((uint8_t *)(request->_tempObject) + index, data, len);

src/AsyncMessagePack.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ void AsyncCallbackMessagePackWebHandler::handleBody(AsyncWebServerRequest *reque
102102
_contentLength = total;
103103
if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) {
104104
request->_tempObject = malloc(total);
105+
if (request->_tempObject == NULL) {
106+
#ifdef ESP32
107+
log_e("Failed to allocate buffer");
108+
#endif
109+
return;
110+
}
105111
}
106112
if (request->_tempObject != NULL) {
107113
memcpy((uint8_t *)(request->_tempObject) + index, data, len);

src/AsyncWebHeader.cpp

+11-6
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ AsyncWebHeader::AsyncWebHeader(const String &data) {
1717

1818
String AsyncWebHeader::toString() const {
1919
String str;
20-
str.reserve(_name.length() + _value.length() + 2);
21-
str.concat(_name);
22-
str.concat((char)0x3a);
23-
str.concat((char)0x20);
24-
str.concat(_value);
25-
str.concat(asyncsrv::T_rn);
20+
if (str.reserve(_name.length() + _value.length() + 2)) {
21+
str.concat(_name);
22+
str.concat((char)0x3a);
23+
str.concat((char)0x20);
24+
str.concat(_value);
25+
str.concat(asyncsrv::T_rn);
26+
} else {
27+
#ifdef ESP32
28+
log_e("Failed to allocate buffer");
29+
#endif
30+
}
2631
return str;
2732
}

src/AsyncWebSocket.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool
6666

6767
uint8_t *buf = (uint8_t *)malloc(headLen);
6868
if (buf == NULL) {
69-
// os_printf("could not malloc %u bytes for frame header\n", headLen);
70-
// Serial.println("SF 3");
69+
#ifdef ESP32
70+
log_e("Failed to allocate buffer");
71+
#endif
7172
return 0;
7273
}
7374

@@ -168,6 +169,9 @@ class AsyncWebSocketControl {
168169
_data = (uint8_t *)malloc(_len);
169170

170171
if (_data == NULL) {
172+
#ifdef ESP32
173+
log_e("Failed to allocate buffer");
174+
#endif
171175
_len = 0;
172176
} else {
173177
memcpy(_data, data, len);
@@ -516,6 +520,10 @@ void AsyncWebSocketClient::close(uint16_t code, const char *message) {
516520
_queueControl(WS_DISCONNECT, (uint8_t *)buf, packetLen);
517521
free(buf);
518522
return;
523+
} else {
524+
#ifdef ESP32
525+
log_e("Failed to allocate buffer");
526+
#endif
519527
}
520528
}
521529
_queueControl(WS_DISCONNECT);
@@ -1289,7 +1297,10 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String &key, AsyncWebSocket
12891297
sha1(key + WS_STR_UUID, hash);
12901298
#else
12911299
String k;
1292-
k.reserve(key.length() + WS_STR_UUID_LEN);
1300+
if (!k.reserve(key.length() + WS_STR_UUID_LEN)) {
1301+
log_e("Failed to allocate buffer");
1302+
return;
1303+
}
12931304
k.concat(key);
12941305
k.concat(WS_STR_UUID);
12951306
SHA1Builder sha1;

src/Middleware.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,21 @@ bool AsyncAuthenticationMiddleware::generateHash() {
9999
switch (_authMethod) {
100100
case AsyncAuthType::AUTH_DIGEST:
101101
_credentials = generateDigestHash(_username.c_str(), _credentials.c_str(), _realm.c_str());
102-
_hash = true;
103-
return true;
102+
if (_credentials.length()) {
103+
_hash = true;
104+
return true;
105+
} else {
106+
return false;
107+
}
104108

105109
case AsyncAuthType::AUTH_BASIC:
106110
_credentials = generateBasicHash(_username.c_str(), _credentials.c_str());
107-
_hash = true;
108-
return true;
111+
if (_credentials.length()) {
112+
_hash = true;
113+
return true;
114+
} else {
115+
return false;
116+
}
109117

110118
default: return false;
111119
}

src/WebAuthentication.cpp

+25-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ String genRandomMD5() {
8686
#endif
8787
char *out = (char *)malloc(33);
8888
if (out == NULL || !getMD5((uint8_t *)(&r), 4, out)) {
89+
#ifdef ESP32
90+
log_e("Failed to allocate buffer");
91+
#endif
8992
return emptyString;
9093
}
9194
String res = String(out);
@@ -96,6 +99,9 @@ String genRandomMD5() {
9699
static String stringMD5(const String &in) {
97100
char *out = (char *)malloc(33);
98101
if (out == NULL || !getMD5((uint8_t *)(in.c_str()), in.length(), out)) {
102+
#ifdef ESP32
103+
log_e("Failed to allocate buffer");
104+
#endif
99105
return emptyString;
100106
}
101107
String res = String(out);
@@ -108,16 +114,33 @@ String generateDigestHash(const char *username, const char *password, const char
108114
return emptyString;
109115
}
110116
char *out = (char *)malloc(33);
117+
if (out == NULL) {
118+
#ifdef ESP32
119+
log_e("Failed to allocate buffer");
120+
#endif
121+
return emptyString;
122+
}
111123

112124
String in;
113-
in.reserve(strlen(username) + strlen(realm) + strlen(password) + 2);
125+
if (!in.reserve(strlen(username) + strlen(realm) + strlen(password) + 2)) {
126+
#ifdef ESP32
127+
log_e("Failed to allocate buffer");
128+
#endif
129+
free(out);
130+
return emptyString;
131+
}
132+
114133
in.concat(username);
115134
in.concat(':');
116135
in.concat(realm);
117136
in.concat(':');
118137
in.concat(password);
119138

120-
if (out == NULL || !getMD5((uint8_t *)(in.c_str()), in.length(), out)) {
139+
if (!getMD5((uint8_t *)(in.c_str()), in.length(), out)) {
140+
#ifdef ESP32
141+
log_e("Failed to allocate buffer");
142+
#endif
143+
free(out);
121144
return emptyString;
122145
}
123146

src/WebHandlers.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ bool AsyncStaticWebHandler::_searchFile(AsyncWebServerRequest *request, const St
172172
// Extract the file name from the path and keep it in _tempObject
173173
size_t pathLen = path.length();
174174
char *_tempPath = (char *)malloc(pathLen + 1);
175+
if (_tempPath == NULL) {
176+
#ifdef ESP32
177+
log_e("Failed to allocate buffer");
178+
#endif
179+
request->_tempFile.close();
180+
return false;
181+
}
175182
snprintf_P(_tempPath, pathLen + 1, PSTR("%s"), path.c_str());
176183
request->_tempObject = (void *)_tempPath;
177184
}

src/WebRequest.cpp

+57-21
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,14 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len) {
129129
if (i == len) { // No new line, just add the buffer in _temp
130130
char ch = str[len - 1];
131131
str[len - 1] = 0;
132-
_temp.reserve(_temp.length() + len);
132+
if (!_temp.reserve(_temp.length() + len)) {
133+
#ifdef ESP32
134+
log_e("Failed to allocate buffer");
135+
#endif
136+
_parseState = PARSE_REQ_FAIL;
137+
_client->abort();
138+
return;
139+
}
133140
_temp.concat(str);
134141
_temp.concat(ch);
135142
} else { // Found new line - extract it and parse
@@ -280,9 +287,11 @@ void AsyncWebServerRequest::_addGetParams(const String &params) {
280287
if (equal < 0 || equal > end) {
281288
equal = end;
282289
}
283-
String name(params.substring(start, equal));
284-
String value(equal + 1 < end ? params.substring(equal + 1, end) : String());
285-
_params.emplace_back(urlDecode(name), urlDecode(value));
290+
String name = urlDecode(params.substring(start, equal));
291+
String value = urlDecode(equal + 1 < end ? params.substring(equal + 1, end) : emptyString);
292+
if (name.length()) {
293+
_params.emplace_back(name, value);
294+
}
286295
start = end + 1;
287296
}
288297
}
@@ -408,7 +417,10 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) {
408417
name = _temp.substring(0, _temp.indexOf('='));
409418
value = _temp.substring(_temp.indexOf('=') + 1);
410419
}
411-
_params.emplace_back(urlDecode(name), urlDecode(value), true);
420+
name = urlDecode(name);
421+
if (name.length()) {
422+
_params.emplace_back(name, urlDecode(value), true);
423+
}
412424

413425
#ifndef TARGET_RP2040
414426
_temp.clear();
@@ -531,6 +543,9 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) {
531543
}
532544
_itemBuffer = (uint8_t *)malloc(RESPONSE_STREAM_BUFFER_SIZE);
533545
if (_itemBuffer == NULL) {
546+
#ifdef ESP32
547+
log_e("Failed to allocate buffer");
548+
#endif
534549
_multiParseState = PARSE_ERROR;
535550
return;
536551
}
@@ -934,27 +949,42 @@ void AsyncWebServerRequest::requestAuthentication(AsyncAuthType method, const ch
934949
case AsyncAuthType::AUTH_BASIC:
935950
{
936951
String header;
937-
header.reserve(strlen(T_BASIC_REALM) + strlen(realm) + 1);
938-
header.concat(T_BASIC_REALM);
939-
header.concat(realm);
940-
header.concat('"');
941-
r->addHeader(T_WWW_AUTH, header.c_str());
952+
if (header.reserve(strlen(T_BASIC_REALM) + strlen(realm) + 1)) {
953+
header.concat(T_BASIC_REALM);
954+
header.concat(realm);
955+
header.concat('"');
956+
r->addHeader(T_WWW_AUTH, header.c_str());
957+
} else {
958+
#ifdef ESP32
959+
log_e("Failed to allocate buffer");
960+
#endif
961+
}
962+
942963
break;
943964
}
944965
case AsyncAuthType::AUTH_DIGEST:
945966
{
946967
size_t len = strlen(T_DIGEST_) + strlen(T_realm__) + strlen(T_auth_nonce) + 32 + strlen(T__opaque) + 32 + 1;
947968
String header;
948-
header.reserve(len + strlen(realm));
949-
header.concat(T_DIGEST_);
950-
header.concat(T_realm__);
951-
header.concat(realm);
952-
header.concat(T_auth_nonce);
953-
header.concat(genRandomMD5());
954-
header.concat(T__opaque);
955-
header.concat(genRandomMD5());
956-
header.concat((char)0x22); // '"'
957-
r->addHeader(T_WWW_AUTH, header.c_str());
969+
if (header.reserve(len + strlen(realm))) {
970+
const String nonce = genRandomMD5();
971+
const String opaque = genRandomMD5();
972+
if (nonce.length() && opaque.length()) {
973+
header.concat(T_DIGEST_);
974+
header.concat(T_realm__);
975+
header.concat(realm);
976+
header.concat(T_auth_nonce);
977+
header.concat(nonce);
978+
header.concat(T__opaque);
979+
header.concat(opaque);
980+
header.concat((char)0x22); // '"'
981+
r->addHeader(T_WWW_AUTH, header.c_str());
982+
} else {
983+
#ifdef ESP32
984+
log_e("Failed to allocate buffer");
985+
#endif
986+
}
987+
}
958988
break;
959989
}
960990
default: break;
@@ -1031,7 +1061,13 @@ String AsyncWebServerRequest::urlDecode(const String &text) const {
10311061
unsigned int len = text.length();
10321062
unsigned int i = 0;
10331063
String decoded;
1034-
decoded.reserve(len); // Allocate the string internal buffer - never longer from source text
1064+
// Allocate the string internal buffer - never longer from source text
1065+
if (!decoded.reserve(len)) {
1066+
#ifdef ESP32
1067+
log_e("Failed to allocate buffer");
1068+
#endif
1069+
return emptyString;
1070+
}
10351071
while (i < len) {
10361072
char decodedChar;
10371073
char encodedChar = text.charAt(i++);

src/WebResponses.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,9 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u
408408

409409
uint8_t *buf = (uint8_t *)malloc(outLen + headLen);
410410
if (!buf) {
411-
// os_printf("_ack malloc %d failed\n", outLen+headLen);
411+
#ifdef ESP32
412+
log_e("Failed to allocate buffer");
413+
#endif
412414
return 0;
413415
}
414416

@@ -817,7 +819,11 @@ AsyncResponseStream::AsyncResponseStream(const char *contentType, size_t bufferS
817819
_code = 200;
818820
_contentLength = 0;
819821
_contentType = contentType;
820-
_content.reserve(bufferSize);
822+
if (!_content.reserve(bufferSize)) {
823+
#ifdef ESP32
824+
log_e("Failed to allocate buffer");
825+
#endif
826+
}
821827
}
822828

823829
size_t AsyncResponseStream::_fillBuffer(uint8_t *buf, size_t maxLen) {

src/WebServer.cpp

+4-11
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ const char *fs::FileOpenMode::append = "a";
3030

3131
AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) {
3232
_catchAllHandler = new AsyncCallbackWebHandler();
33-
if (_catchAllHandler == NULL) {
34-
return;
35-
}
3633
_server.onClient(
3734
[](void *s, AsyncClient *c) {
3835
if (c == NULL) {
@@ -52,9 +49,7 @@ AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) {
5249
AsyncWebServer::~AsyncWebServer() {
5350
reset();
5451
end();
55-
if (_catchAllHandler) {
56-
delete _catchAllHandler;
57-
}
52+
delete _catchAllHandler;
5853
}
5954

6055
AsyncWebRewrite &AsyncWebServer::addRewrite(std::shared_ptr<AsyncWebRewrite> rewrite) {
@@ -179,9 +174,7 @@ void AsyncWebServer::reset() {
179174
_rewrites.clear();
180175
_handlers.clear();
181176

182-
if (_catchAllHandler != NULL) {
183-
_catchAllHandler->onRequest(NULL);
184-
_catchAllHandler->onUpload(NULL);
185-
_catchAllHandler->onBody(NULL);
186-
}
177+
_catchAllHandler->onRequest(NULL);
178+
_catchAllHandler->onUpload(NULL);
179+
_catchAllHandler->onBody(NULL);
187180
}

0 commit comments

Comments
 (0)