fix: never write past a JSON buffer or send a broken socket event

When something didn't fit, the formatters skipped it silently, closing
brackets included, and clients got malformed JSON.  Two writes could
also go past the buffer:

- AsyncJsonResp flushed when full and then wrote the value without
  checking again, so a value bigger than the whole buffer overflowed.
  It is now streamed straight out instead.
- JsonSockEvent::closeEvent added the closing ] when only one byte was
  left, putting the terminator one byte past the buffer.

The formatters now set an overflowed() flag and log an error, and a
socket event that overflowed is logged and not sent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-11 13:31:48 +02:00
parent b2294ced34
commit 8881289b1d
4 changed files with 61 additions and 6 deletions

View file

@ -1,10 +1,14 @@
#include "JsonFormatter.h"
#include "esp_log.h"
static const char *TAG = "JSON";
void BufferedJsonFormatter::setBuffer(char *b, size_t sz) {
this->buff = b;
this->buffSize = sz;
this->buff[0] = 0;
this->_nocomma = true;
this->_overflow = false;
this->_objects = 0;
this->_arrays = 0;
}
@ -86,6 +90,8 @@ void JsonFormatter::_safecat(const char *val, bool escape) {
size_t len = (escape ? this->calcEscapedLength(val) : strlen(val)) + strlen(this->buff);
if(escape) len += 2;
if(len >= this->buffSize) {
if(!this->_overflow) ESP_LOGE(TAG, "JSON exceeded buffer size %u", (unsigned)this->buffSize);
this->_overflow = true;
return;
}
if(escape) strcat(this->buff, "\"");