From 26ba6ccb7245b927a961d0fb46484b7a8116b90e Mon Sep 17 00:00:00 2001 From: Wessel Nieboer Date: Wed, 11 Feb 2026 04:17:26 +0100 Subject: [PATCH] fix infinite loop in WiFi frame skip when read fails The frame-skip loops in checkRecvFrame subtract the return value of client.read() from frame_length. On ESP32, WiFiClient::read() returns -1 on error. Subtracting -1 increments frame_length instead of decrementing it, turning the loop into an infinite hang. A WiFi client can trigger this by sending a frame header with a large length and then disconnecting (or sending fewer bytes than claimed). The node locks up in the skip loop and stops processing all traffic. Switch to single-byte client.read() which returns the byte value or -1, and break out of the loop on error. Decrement frame_length by exactly 1 per successful read. --- src/helpers/esp32/SerialWifiInterface.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/helpers/esp32/SerialWifiInterface.cpp b/src/helpers/esp32/SerialWifiInterface.cpp index 462e3ecc3..7203d9d22 100644 --- a/src/helpers/esp32/SerialWifiInterface.cpp +++ b/src/helpers/esp32/SerialWifiInterface.cpp @@ -131,9 +131,9 @@ size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { if(frame_length > MAX_FRAME_SIZE){ WIFI_DEBUG_PRINTLN("Skipping frame: length=%d is larger than MAX_FRAME_SIZE=%d", frame_length, MAX_FRAME_SIZE); while(frame_length > 0){ - uint8_t skip[1]; - int skipped = client.read(skip, 1); - frame_length -= skipped; + int skipped = client.read(); + if(skipped < 0) break; // read error, stop draining + frame_length--; } resetReceivedFrameHeader(); return 0; @@ -144,9 +144,9 @@ size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { if(frame_type != '<'){ WIFI_DEBUG_PRINTLN("Skipping frame: type=0x%x is unexpected", frame_type); while(frame_length > 0){ - uint8_t skip[1]; - int skipped = client.read(skip, 1); - frame_length -= skipped; + int skipped = client.read(); + if(skipped < 0) break; // read error, stop draining + frame_length--; } resetReceivedFrameHeader(); return 0;