Use UINT16_MAX instead of hard coded 65535 in api (#8884)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
J. Nick Koston 2025-05-22 18:51:06 -05:00 committed by GitHub
parent 926b42ba1c
commit 2ab1fe1abf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 8 deletions

View File

@ -887,7 +887,7 @@ APIError APIPlaintextFrameHelper::try_read_frame_(ParsedFrame *frame) {
// - At least 2 bytes in the buffer for the varints // - At least 2 bytes in the buffer for the varints
// Buffer layout: // Buffer layout:
// First 1-3 bytes: Message size varint (variable length) // First 1-3 bytes: Message size varint (variable length)
// - 2 bytes would only allow up to 16383, which is less than noise's 65535 // - 2 bytes would only allow up to 16383, which is less than noise's UINT16_MAX (65535)
// - 3 bytes allows up to 2097151, ensuring we support at least as much as noise // - 3 bytes allows up to 2097151, ensuring we support at least as much as noise
// Remaining 1-2 bytes: Message type varint (variable length) // Remaining 1-2 bytes: Message type varint (variable length)
// We now attempt to parse both varints. If either is incomplete, // We now attempt to parse both varints. If either is incomplete,
@ -900,9 +900,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(ParsedFrame *frame) {
continue; continue;
} }
if (msg_size_varint->as_uint32() > 65535) { if (msg_size_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
state_ = State::FAILED; state_ = State::FAILED;
HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum 65535", msg_size_varint->as_uint32()); HELPER_LOG("Bad packet: message size %" PRIu32 " exceeds maximum %u", msg_size_varint->as_uint32(),
std::numeric_limits<uint16_t>::max());
return APIError::BAD_DATA_PACKET; return APIError::BAD_DATA_PACKET;
} }
rx_header_parsed_len_ = msg_size_varint->as_uint16(); rx_header_parsed_len_ = msg_size_varint->as_uint16();
@ -912,9 +913,10 @@ APIError APIPlaintextFrameHelper::try_read_frame_(ParsedFrame *frame) {
// not enough data there yet // not enough data there yet
continue; continue;
} }
if (msg_type_varint->as_uint32() > 65535) { if (msg_type_varint->as_uint32() > std::numeric_limits<uint16_t>::max()) {
state_ = State::FAILED; state_ = State::FAILED;
HELPER_LOG("Bad packet: message type %" PRIu32 " exceeds maximum 65535", msg_type_varint->as_uint32()); HELPER_LOG("Bad packet: message type %" PRIu32 " exceeds maximum %u", msg_type_varint->as_uint32(),
std::numeric_limits<uint16_t>::max());
return APIError::BAD_DATA_PACKET; return APIError::BAD_DATA_PACKET;
} }
rx_header_parsed_type_ = msg_type_varint->as_uint16(); rx_header_parsed_type_ = msg_type_varint->as_uint16();

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <deque> #include <deque>
#include <limits>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -101,7 +102,7 @@ class APIFrameHelper {
std::vector<uint8_t> data; std::vector<uint8_t> data;
uint16_t offset{0}; // Current offset within the buffer (uint16_t to reduce memory usage) uint16_t offset{0}; // Current offset within the buffer (uint16_t to reduce memory usage)
// Using uint16_t reduces memory usage since ESPHome API messages are limited to 64KB max // Using uint16_t reduces memory usage since ESPHome API messages are limited to UINT16_MAX (65535) bytes
uint16_t remaining() const { return static_cast<uint16_t>(data.size()) - offset; } uint16_t remaining() const { return static_cast<uint16_t>(data.size()) - offset; }
const uint8_t *current_data() const { return data.data() + offset; } const uint8_t *current_data() const { return data.data() + offset; }
}; };
@ -192,7 +193,7 @@ class APINoiseFrameHelper : public APIFrameHelper {
void send_explicit_handshake_reject_(const std::string &reason); void send_explicit_handshake_reject_(const std::string &reason);
// Fixed-size header buffer for noise protocol: // Fixed-size header buffer for noise protocol:
// 1 byte for indicator + 2 bytes for message size (16-bit value, not varint) // 1 byte for indicator + 2 bytes for message size (16-bit value, not varint)
// Note: Maximum message size is 65535, with a limit of 128 bytes during handshake phase // Note: Maximum message size is UINT16_MAX (65535), with a limit of 128 bytes during handshake phase
uint8_t rx_header_buf_[3]; uint8_t rx_header_buf_[3];
uint8_t rx_header_buf_len_ = 0; uint8_t rx_header_buf_len_ = 0;
@ -230,7 +231,7 @@ class APIPlaintextFrameHelper : public APIFrameHelper {
APIError try_read_frame_(ParsedFrame *frame); APIError try_read_frame_(ParsedFrame *frame);
// Fixed-size header buffer for plaintext protocol: // Fixed-size header buffer for plaintext protocol:
// We only need space for the two varints since we validate the indicator byte separately. // We only need space for the two varints since we validate the indicator byte separately.
// To match noise protocol's maximum message size (65535), we need: // To match noise protocol's maximum message size (UINT16_MAX = 65535), we need:
// 3 bytes for message size varint (supports up to 2097151) + 2 bytes for message type varint // 3 bytes for message size varint (supports up to 2097151) + 2 bytes for message type varint
// //
// While varints could theoretically be up to 10 bytes each for 64-bit values, // While varints could theoretically be up to 10 bytes each for 64-bit values,