From 6146e625dd6e466ab150e9030dad4d04b75334d3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 8 Sep 2026 14:12:09 +0200 Subject: [PATCH] Gate RP2 gzip on the core version, log an inflate overrun, document the window aliasing --- esphome/components/esphome/ota/ota_esphome.cpp | 4 +++- esphome/components/esphome/ota/ota_esphome_inflate.h | 4 +++- esphome/components/ota/ota_backend_arduino_rp2.h | 12 ++++++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index 68e048eeed..e724490b08 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -824,8 +824,10 @@ ota::OTAResponseTypes ESPHomeOTAComponent::inflate_flush_(InflateSession &sessio const size_t pending = produced - session.flushed; if (pending == 0) return ota::OTA_RESPONSE_OK; - if (pending > session.image_size - session.written) + if (pending > session.image_size - session.written) { + ESP_LOGW(TAG, "Inflate overrun"); return ota::OTA_RESPONSE_ERROR_UNKNOWN; + } ota::OTAResponseTypes result = this->write_flash_(session.window + session.flushed, pending); if (result != ota::OTA_RESPONSE_OK) return result; diff --git a/esphome/components/esphome/ota/ota_esphome_inflate.h b/esphome/components/esphome/ota/ota_esphome_inflate.h index 197e20e42d..5d9f268f73 100644 --- a/esphome/components/esphome/ota/ota_esphome_inflate.h +++ b/esphome/components/esphome/ota/ota_esphome_inflate.h @@ -56,7 +56,9 @@ struct OtaInflateState { /* dict must cover the encoder's window (its largest back reference) */ void ota_inflate_init(struct OtaInflateState *d, unsigned char *dict, unsigned int dict_len); -/* Fills dest up to dest_limit (OK) or to the end of the stream (DONE) */ +/* Fills dest up to dest_limit (OK) or to the end of the stream (DONE). dest may + alias dict only if dest_limit - dest == dict_len and dest is reset to dict + exactly when a call returns OK, so the ring index and dest stay in lockstep */ int ota_inflate(struct OtaInflateState *d); #ifdef __cplusplus diff --git a/esphome/components/ota/ota_backend_arduino_rp2.h b/esphome/components/ota/ota_backend_arduino_rp2.h index fd72685823..a9716c5d30 100644 --- a/esphome/components/ota/ota_backend_arduino_rp2.h +++ b/esphome/components/ota/ota_backend_arduino_rp2.h @@ -6,6 +6,8 @@ #include "esphome/core/defines.h" #include "esphome/core/macros.h" +#include + namespace esphome::ota { class ArduinoRP2OTABackend final { @@ -15,10 +17,12 @@ class ArduinoRP2OTABackend final { OTAResponseTypes write(uint8_t *data, size_t len); OTAResponseTypes end(); void abort(); - // The core's OTA stub inflates a staged gzip image at reboot (arduino-pico - // 2.4.0, RP2350 4.0.3; ESPHome pins 6.0.0). begin() only sees the gzip - // size; the inflated size is known when the stub reads the trailer. - static constexpr bool supports_compression() { return true; } + // The core's OTA stub inflates a staged gzip image at reboot, on every chip + // from 4.0.3 (ESPHome pins 6.0.0). begin() only sees the gzip size; the + // inflated size is known when the stub reads the trailer. + static constexpr bool supports_compression() { + return VERSION_CODE(ARDUINO_PICO_MAJOR, ARDUINO_PICO_MINOR, ARDUINO_PICO_REVISION) >= VERSION_CODE(4, 0, 3); + } private: bool md5_set_{false};