From fa2b14ef412fceba6a62d6d11181490605e55453 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 27 Mar 2026 16:47:56 -1000 Subject: [PATCH] Guard against nullptr+0 UB in call() and fix assert bound - Add early return when size_==0 to avoid nullptr+0 pointer arithmetic (UB per C++ standard, even though all ESPHome targets treat it as no-op) - Fix debug assert: size < UINT16_MAX allows capacity up to 65535 --- esphome/core/helpers.cpp | 2 +- esphome/core/helpers.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 4768c4eb95..5940f6ec98 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -24,7 +24,7 @@ static const char *const TAG = "helpers"; __attribute__((noinline, cold)) void *callback_manager_grow(void *data, uint16_t size, uint16_t &capacity, size_t elem_size) { - ESPHOME_DEBUG_ASSERT(size < UINT16_MAX - 1); + ESPHOME_DEBUG_ASSERT(size < UINT16_MAX); uint16_t new_cap = size + 1; auto *new_data = ::operator new(new_cap *elem_size); if (data) { diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 4937dbdd4e..f65409bc5f 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -1834,6 +1834,9 @@ template class CallbackManager { /// Call all callbacks in this manager. inline void ESPHOME_ALWAYS_INLINE call(Ts... args) { + if (this->size_ == 0) { + return; + } for (auto *it = this->data_, *end = it + this->size_; it != end; ++it) { it->call(args...); }