ESPAsyncWebServer
ESPAsyncWebServer copied to clipboard
ESP32 crashes and reboots when sending Zalgo Text
Im using a Basic Webserver like this:
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);
const char* ssid = "ssid";
const char* password = "********";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi Failed!\n");
return;
}
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello, world");
});
server.begin();
}
void loop() {
}
When I go to this URL which has some "cursed text" after the ?:
zalgo_text.txt UTF-8 Encoded
It crashes with this error:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400894c7 PS : 0x00060f30 A0 : 0x800e0117 A1 : 0x3ffda690
A2 : 0x3ffda71c A3 : 0x00000000 A4 : 0x00000001 A5 : 0x0000ff00
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x00000000 A9 : 0x00000000
A10 : 0x00000001 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x0000ff00
A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000015 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x4008a691 LEND : 0x4008a6a1 LCOUNT : 0xffffffff
Backtrace: 0x400894c4:0x3ffda690 0x400e0114:0x3ffda6b0 0x400e021e:0x3ffda6d0 0x400d63a1:0x3ffda6f0 0x400d67c1:0x3ffda760 0x400d6935:0x3ffda7b0 0x400d6b1d:0x3ffda800 0x40160b31:0x3ffda820 0x40160ba9:0x3ffda850 0x40161362:0x3ffda870
#0 0x400894c4:0x3ffda690 in memmove at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/string/memmove.c:66
#1 0x400e0114:0x3ffda6b0 in String::move(String&) at C:/Users/User/.platformio/packages/framework-arduinoespressif32/cores/esp32/WString.cpp:237
#2 0x400e021e:0x3ffda6d0 in String::operator=(String&&) at C:/Users/User/.platformio/packages/framework-arduinoespressif32/cores/esp32/WString.cpp:277
#3 0x400d63a1:0x3ffda6f0 in AsyncWebServerRequest::_parseReqHead() at .pio/libdeps/esp_wroom_02/ESP Async WebServer/src/WebRequest.cpp:280 (discriminator 1)
#4 0x400d67c1:0x3ffda760 in AsyncWebServerRequest::_parseLine() at .pio/libdeps/esp_wroom_02/ESP Async WebServer/src/WebRequest.cpp:561
#5 0x400d6935:0x3ffda7b0 in AsyncWebServerRequest::_onData(void*, unsigned int) at .pio/libdeps/esp_wroom_02/ESP Async WebServer/src/WebRequest.cpp:123
#6 0x400d6b1d:0x3ffda800 in std::_Function_handler<void (void*, AsyncClient*, void*, unsigned int), AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer*, AsyncClient*)::{lambda(void*, AsyncClient*, void*, unsigned int)#8}>::_M_invoke(std::_Any_data const&, void*&&, AsyncClient*&&, std::_Any_data const&, unsigned int&&) at .pio/libdeps/esp_wroom_02/ESP Async WebServer/src/WebRequest.cpp:76
(inlined by) _M_invoke at c:\users\user\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h:297
#7 0x40160b31:0x3ffda820 in std::function<void (void*, AsyncClient*, void*, unsigned int)>::operator()(void*, AsyncClient*, void*, unsigned int) const at c:\users\user\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits/std_function.h:687
(inlined by) AsyncClient::_recv(tcp_pcb*, pbuf*, signed char) at .pio/libdeps/esp_wroom_02/AsyncTCP/src/AsyncTCP.cpp:915
#8 0x40160ba9:0x3ffda850 in AsyncClient::_s_recv(void*, tcp_pcb*, pbuf*, signed char) at .pio/libdeps/esp_wroom_02/AsyncTCP/src/AsyncTCP.cpp:1191
#9 0x40161362:0x3ffda870 in _async_service_task(void*) at .pio/libdeps/esp_wroom_02/AsyncTCP/src/AsyncTCP.cpp:159
(inlined by) _async_service_task at .pio/libdeps/esp_wroom_02/AsyncTCP/src/AsyncTCP.cpp:194
ELF file SHA256: 219f7cef713eeb1c
Rebooting...
According to the backtrace, this happens in WebRequest.cpp at line 280
g = u.substring(index +1);
For now i fixed it with a bit of a hacky solution by only processing a requests parameters if its shorter than 1024 Characters. WebRequest.cpp:278
String g = String();
index = u.indexOf('?');
if(index > 0 && u.length() < 1024){
g = u.substring(index +1);
u = u.substring(0, index);
}
_url = urlDecode(u);
_addGetParams(g);