From 7185c66779db02ff0219be05e9d514025a86d463 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 8 Mar 2026 17:42:17 -1000 Subject: [PATCH] Remove len==0 guard from parse(), add debug assert All callers guarantee len > 0 (decode loop checks ptr < end, header parse checks minimum bytes). Replace runtime check with ESPHOME_DEBUG_API assert. This removes the len check from the inline entirely, saving one branch per call site. Co-Authored-By: Claude Opus 4.6 --- esphome/components/api/proto.cpp | 2 -- esphome/components/api/proto.h | 10 ++++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/esphome/components/api/proto.cpp b/esphome/components/api/proto.cpp index 4cbc8f46c2..7e01185849 100644 --- a/esphome/components/api/proto.cpp +++ b/esphome/components/api/proto.cpp @@ -21,8 +21,6 @@ void ProtoWriteBuffer::encode_varint_raw_slow_(uint32_t value) { } ProtoVarIntResult ProtoVarInt::parse_slow(const uint8_t *buffer, uint32_t len) { - if (len == 0) - return {0, 0}; // Multi-byte varint: first byte already checked to have high bit set uint32_t result32 = buffer[0] & 0x7F; #ifdef USE_API_VARINT64 diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index 55054ed157..ebb0ecdd79 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -130,13 +130,15 @@ class ProtoVarInt { ProtoVarInt() : value_(0) {} explicit ProtoVarInt(uint64_t value) : value_(value) {} - /// Parse a varint from buffer. Returns result with consumed=0 on failure. + /// Parse a varint from buffer. Caller must ensure len >= 1. + /// Returns result with consumed=0 on failure (truncated multi-byte varint). static inline ProtoVarIntResult ESPHOME_ALWAYS_INLINE parse(const uint8_t *buffer, uint32_t len) { +#ifdef ESPHOME_DEBUG_API + assert(len > 0); // All callers guarantee len > 0 +#endif // Fast path: single-byte varints (0-127) are the most common case // (booleans, small enums, field tags, small message sizes/types). - // len==0 check is folded into the condition to minimize inline size; - // parse_slow() handles len==0. - if (len != 0 && (buffer[0] & 0x80) == 0) [[likely]] + if ((buffer[0] & 0x80) == 0) [[likely]] return {buffer[0], 1}; return parse_slow(buffer, len); }