From 716a868da6af6046aec311bd6de2c3d9f64d187a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 6 Dec 2025 23:29:10 -0600 Subject: [PATCH 1/2] reduce --- esphome/components/text_sensor/__init__.py | 12 ++++++------ esphome/components/text_sensor/filter.cpp | 18 ++++++++++-------- esphome/components/text_sensor/filter.h | 13 ++++++------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/esphome/components/text_sensor/__init__.py b/esphome/components/text_sensor/__init__.py index 2be14b36fd..0d22400a8e 100644 --- a/esphome/components/text_sensor/__init__.py +++ b/esphome/components/text_sensor/__init__.py @@ -86,12 +86,12 @@ async def to_lower_filter_to_code(config, filter_id): @FILTER_REGISTRY.register("append", AppendFilter, cv.string) async def append_filter_to_code(config, filter_id): - return cg.new_Pvariable(filter_id, cg.StringRefLiteral(config)) + return cg.new_Pvariable(filter_id, config) @FILTER_REGISTRY.register("prepend", PrependFilter, cv.string) async def prepend_filter_to_code(config, filter_id): - return cg.new_Pvariable(filter_id, cg.StringRefLiteral(config)) + return cg.new_Pvariable(filter_id, config) def validate_mapping(value): @@ -114,8 +114,8 @@ async def substitute_filter_to_code(config, filter_id): substitutions = [ cg.StructInitializer( cg.MockObj("Substitution", "esphome::text_sensor::"), - ("from", cg.StringRefLiteral(conf[CONF_FROM])), - ("to", cg.StringRefLiteral(conf[CONF_TO])), + ("from", conf[CONF_FROM]), + ("to", conf[CONF_TO]), ) for conf in config ] @@ -127,8 +127,8 @@ async def map_filter_to_code(config, filter_id): mappings = [ cg.StructInitializer( cg.MockObj("Substitution", "esphome::text_sensor::"), - ("from", cg.StringRefLiteral(conf[CONF_FROM])), - ("to", cg.StringRefLiteral(conf[CONF_TO])), + ("from", conf[CONF_FROM]), + ("to", conf[CONF_TO]), ) for conf in config ] diff --git a/esphome/components/text_sensor/filter.cpp b/esphome/components/text_sensor/filter.cpp index d9afaf80f1..4cace372ae 100644 --- a/esphome/components/text_sensor/filter.cpp +++ b/esphome/components/text_sensor/filter.cpp @@ -57,13 +57,13 @@ optional ToLowerFilter::new_value(std::string value) { // Append optional AppendFilter::new_value(std::string value) { - value += this->suffix_; + value.append(this->suffix_); return value; } // Prepend optional PrependFilter::new_value(std::string value) { - value.insert(0, this->prefix_.c_str(), this->prefix_.size()); + value.insert(0, this->prefix_); return value; } @@ -73,13 +73,15 @@ SubstituteFilter::SubstituteFilter(const std::initializer_list &su optional SubstituteFilter::new_value(std::string value) { for (const auto &sub : this->substitutions_) { + // Compute lengths once per substitution (strlen is fast, called infrequently) + const size_t from_len = strlen(sub.from); + const size_t to_len = strlen(sub.to); std::size_t pos = 0; - // Use c_str()/size() to avoid temporary std::string allocation from implicit conversion - while ((pos = value.find(sub.from.c_str(), pos, sub.from.size())) != std::string::npos) { - value.replace(pos, sub.from.size(), sub.to.c_str(), sub.to.size()); + while ((pos = value.find(sub.from, pos, from_len)) != std::string::npos) { + value.replace(pos, from_len, sub.to, to_len); // Advance past the replacement to avoid infinite loop when // the replacement contains the search pattern (e.g., f -> foo) - pos += sub.to.size(); + pos += to_len; } } return value; @@ -90,8 +92,8 @@ MapFilter::MapFilter(const std::initializer_list &mappings) : mapp optional MapFilter::new_value(std::string value) { for (const auto &mapping : this->mappings_) { - if (mapping.from == value) { - value.assign(mapping.to.c_str(), mapping.to.size()); + if (value == mapping.from) { + value.assign(mapping.to); return value; } } diff --git a/esphome/components/text_sensor/filter.h b/esphome/components/text_sensor/filter.h index 472dd87f15..0f66b753b4 100644 --- a/esphome/components/text_sensor/filter.h +++ b/esphome/components/text_sensor/filter.h @@ -2,7 +2,6 @@ #include "esphome/core/component.h" #include "esphome/core/helpers.h" -#include "esphome/core/string_ref.h" namespace esphome { namespace text_sensor { @@ -93,26 +92,26 @@ class ToLowerFilter : public Filter { /// A simple filter that adds a string to the end of another string class AppendFilter : public Filter { public: - explicit AppendFilter(StringRef suffix) : suffix_(suffix) {} + explicit AppendFilter(const char *suffix) : suffix_(suffix) {} optional new_value(std::string value) override; protected: - StringRef suffix_; + const char *suffix_; }; /// A simple filter that adds a string to the start of another string class PrependFilter : public Filter { public: - explicit PrependFilter(StringRef prefix) : prefix_(prefix) {} + explicit PrependFilter(const char *prefix) : prefix_(prefix) {} optional new_value(std::string value) override; protected: - StringRef prefix_; + const char *prefix_; }; struct Substitution { - StringRef from; - StringRef to; + const char *from; + const char *to; }; /// A simple filter that replaces a substring with another substring From d442095d9ab65d40ef7b1950964b724eeafe6644 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 10 Dec 2025 02:26:12 +0100 Subject: [PATCH 2/2] fix buffer overflow --- esphome/components/api/api_connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 09b311c1e4..5186e5afda 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1669,7 +1669,7 @@ bool APIConnection::send_noise_encryption_set_key_response(const NoiseEncryption } else { ESP_LOGW(TAG, "Failed to clear encryption key"); } - } else if (base64_decode(msg.key, psk.data(), msg.key.size()) != psk.size()) { + } else if (base64_decode(msg.key, psk.data(), psk.size()) != psk.size()) { ESP_LOGW(TAG, "Invalid encryption key length"); } else if (!this->parent_->save_noise_psk(psk, true)) { ESP_LOGW(TAG, "Failed to save encryption key");