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

@ -12,10 +12,13 @@ class JsonFormatter {
uint8_t _objects = 0;
uint8_t _arrays = 0;
bool _nocomma = true;
// Something didn't fit and was left out so the JSON is incomplete.
bool _overflow = false;
char _numbuff[25] = {0};
virtual void _safecat(const char *val, bool escape = false);
void _appendNumber(const char *name);
public:
bool overflowed() const { return _overflow; }
// Writes c as it must appear inside a JSON string (out needs 7 bytes) and
// returns its length.
static size_t escapeChar(char c, char *out);