diff --git a/esphome/components/api/proto.cpp b/esphome/components/api/proto.cpp index 7e011858499..4cbc8f46c2d 100644 --- a/esphome/components/api/proto.cpp +++ b/esphome/components/api/proto.cpp @@ -21,6 +21,8 @@ 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 04cb0cc85c0..55054ed1573 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -132,11 +132,11 @@ class ProtoVarInt { /// Parse a varint from buffer. Returns result with consumed=0 on failure. static inline ProtoVarIntResult ESPHOME_ALWAYS_INLINE parse(const uint8_t *buffer, uint32_t len) { - if (len == 0) - return {0, 0}; // Fast path: single-byte varints (0-127) are the most common case // (booleans, small enums, field tags, small message sizes/types). - if ((buffer[0] & 0x80) == 0) [[likely]] + // 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]] return {buffer[0], 1}; return parse_slow(buffer, len); }