From cfe121b38b2dd945bf76782f284b010a3147d65a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 29 Jan 2026 18:45:18 -0600 Subject: [PATCH] private implementation details --- esphome/components/json/json_util.cpp | 10 +++++----- esphome/components/json/json_util.h | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/esphome/components/json/json_util.cpp b/esphome/components/json/json_util.cpp index 80d48431cb..9a159fb28a 100644 --- a/esphome/components/json/json_util.cpp +++ b/esphome/components/json/json_util.cpp @@ -98,24 +98,24 @@ SerializationBuffer<> JsonBuilder::serialize() { if (doc_.overflowed()) { ESP_LOGE(TAG, "JSON document overflow"); - auto *buf = result.data_writable(); + auto *buf = result.data_writable_(); buf[0] = '{'; buf[1] = '}'; buf[2] = '\0'; - result.set_size(2); + result.set_size_(2); return result; } - size_t size = serializeJson(doc_, result.data_writable(), buf_size); + size_t size = serializeJson(doc_, result.data_writable_(), buf_size); if (size < buf_size) { // Fits in stack buffer - update size to actual length - result.set_size(size); + result.set_size_(size); return result; } // Needs heap allocation - reallocate and serialize again with exact size result.reallocate_heap_(size); - serializeJson(doc_, result.data_writable(), size + 1); + serializeJson(doc_, result.data_writable_(), size + 1); return result; } diff --git a/esphome/components/json/json_util.h b/esphome/components/json/json_util.h index 73beb05c92..95a9d25194 100644 --- a/esphome/components/json/json_util.h +++ b/esphome/components/json/json_util.h @@ -84,16 +84,23 @@ template class SerializationBuffer { const char *data() const { return buffer_; } /// Get string length (excluding null terminator) size_t size() const { return size_; } - /// Get writable buffer (for serialization) - char *data_writable() { return buffer_; } - /// Set actual size after serialization (must not exceed allocated size) - void set_size(size_t size) { size_ = size; } /// Implicit conversion to std::string for backward compatibility + /// WARNING: This allocates a new std::string on the heap. Prefer using + /// c_str() or data()/size() directly when possible to avoid allocation. operator std::string() const { return std::string(buffer_, size_); } // NOLINT(google-explicit-constructor) private: - friend class JsonBuilder; ///< Allows JsonBuilder::serialize() to call reallocate_heap_() + friend class JsonBuilder; ///< Allows JsonBuilder::serialize() to call private methods + + /// Get writable buffer (for serialization) + char *data_writable_() { return buffer_; } + /// Set actual size after serialization (must not exceed allocated size) + /// Also ensures null termination for c_str() safety + void set_size_(size_t size) { + size_ = size; + buffer_[size] = '\0'; + } /// Reallocate to heap buffer with new size (for when stack buffer is too small) /// This invalidates any previous buffer content. Used by JsonBuilder::serialize().