From 8142f5db44bfd7d54342ceb938d5d35bd2319359 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 18 Jan 2026 18:43:50 -1000 Subject: [PATCH] [zephyr] Avoid heap allocation in preferences key formatting (#13215) --- esphome/components/zephyr/preferences.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/esphome/components/zephyr/preferences.cpp b/esphome/components/zephyr/preferences.cpp index 08b361b8fb..311133a813 100644 --- a/esphome/components/zephyr/preferences.cpp +++ b/esphome/components/zephyr/preferences.cpp @@ -5,6 +5,8 @@ #include "esphome/core/preferences.h" #include "esphome/core/log.h" #include +#include +#include namespace esphome { namespace zephyr { @@ -13,6 +15,9 @@ static const char *const TAG = "zephyr.preferences"; #define ESPHOME_SETTINGS_KEY "esphome" +// Buffer size for key: "esphome/" (8) + max hex uint32 (8) + null terminator (1) = 17; use 20 for safety margin +static constexpr size_t KEY_BUFFER_SIZE = 20; + class ZephyrPreferenceBackend : public ESPPreferenceBackend { public: ZephyrPreferenceBackend(uint32_t type) { this->type_ = type; } @@ -27,7 +32,9 @@ class ZephyrPreferenceBackend : public ESPPreferenceBackend { bool load(uint8_t *data, size_t len) override { if (len != this->data.size()) { - ESP_LOGE(TAG, "size of setting key %s changed, from: %u, to: %u", get_key().c_str(), this->data.size(), len); + char key_buf[KEY_BUFFER_SIZE]; + this->format_key(key_buf, sizeof(key_buf)); + ESP_LOGE(TAG, "size of setting key %s changed, from: %u, to: %u", key_buf, this->data.size(), len); return false; } std::memcpy(data, this->data.data(), len); @@ -36,7 +43,7 @@ class ZephyrPreferenceBackend : public ESPPreferenceBackend { } uint32_t get_type() const { return this->type_; } - std::string get_key() const { return str_sprintf(ESPHOME_SETTINGS_KEY "/%" PRIx32, this->type_); } + void format_key(char *buf, size_t size) const { snprintf(buf, size, ESPHOME_SETTINGS_KEY "/%" PRIx32, this->type_); } std::vector data; @@ -85,7 +92,9 @@ class ZephyrPreferences : public ESPPreferences { } printf("type %u size %u\n", type, this->backends_.size()); auto *pref = new ZephyrPreferenceBackend(type); // NOLINT(cppcoreguidelines-owning-memory) - ESP_LOGD(TAG, "Add new setting %s.", pref->get_key().c_str()); + char key_buf[KEY_BUFFER_SIZE]; + pref->format_key(key_buf, sizeof(key_buf)); + ESP_LOGD(TAG, "Add new setting %s.", key_buf); this->backends_.push_back(pref); return ESPPreferenceObject(pref); } @@ -134,9 +143,10 @@ class ZephyrPreferences : public ESPPreferences { static int export_settings(int (*cb)(const char *name, const void *value, size_t val_len)) { for (auto *backend : static_cast(global_preferences)->backends_) { - auto name = backend->get_key(); - int err = cb(name.c_str(), backend->data.data(), backend->data.size()); - ESP_LOGD(TAG, "save in flash, name %s, len %u, err %d", name.c_str(), backend->data.size(), err); + char name[KEY_BUFFER_SIZE]; + backend->format_key(name, sizeof(name)); + int err = cb(name, backend->data.data(), backend->data.size()); + ESP_LOGD(TAG, "save in flash, name %s, len %u, err %d", name, backend->data.size(), err); } return 0; }