diff --git a/esphome/components/esphome/ota/ota_esphome.cpp b/esphome/components/esphome/ota/ota_esphome.cpp index f640c0113b..8b20ee85cc 100644 --- a/esphome/components/esphome/ota/ota_esphome.cpp +++ b/esphome/components/esphome/ota/ota_esphome.cpp @@ -829,10 +829,8 @@ 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) { - ESP_LOGW(TAG, "Inflate size mismatch"); + if (pending > session.image_size - session.written) 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; @@ -861,10 +859,9 @@ ota::OTAResponseTypes ESPHomeOTAComponent::inflate_data_(uint8_t *in, size_t ima if (s->error != ota::OTA_RESPONSE_OK) return -1; s->self->ack_written_(*s->xfer); - if (s->xfer->total >= s->xfer->ota_size) { - ESP_LOGW(TAG, "Inflate size mismatch"); + // The stream wants more than announced; the size check below reports it + if (s->xfer->total >= s->xfer->ota_size) return -1; - } ssize_t read = s->self->receive_data_(s->in, *s->xfer); if (read <= 0) return -1; @@ -882,22 +879,21 @@ ota::OTAResponseTypes ESPHomeOTAComponent::inflate_data_(uint8_t *in, size_t ima session.flushed = 0; res = ota_inflate(&session); // A stored block keeps decoding zeros after the read callback failed, so - // eof is checked as well; that failure is already logged - if (res < 0 || session.eof) { - if (!session.eof) { - ESP_LOGW(TAG, "Inflate err %d", res); - } - return session.error != ota::OTA_RESPONSE_OK ? session.error : ota::OTA_RESPONSE_ERROR_UNKNOWN; - } - ota::OTAResponseTypes flush_result = this->inflate_flush_(session); - if (flush_result != ota::OTA_RESPONSE_OK) - return flush_result; + // eof is checked as well + if (res < 0 || session.eof) + break; + session.error = this->inflate_flush_(session); + if (session.error != ota::OTA_RESPONSE_OK) + break; this->ack_written_(xfer); } while (res != OTA_INFLATE_DONE); - if (session.written != image_size || xfer.total != xfer.ota_size) { - ESP_LOGW(TAG, "Inflate size mismatch"); - return ota::OTA_RESPONSE_ERROR_UNKNOWN; + if (res != OTA_INFLATE_DONE || session.written != image_size || xfer.total != xfer.ota_size) { + // A transport failure is already logged; a flash error is reported by write_flash_ + if (session.error == ota::OTA_RESPONSE_OK && (!session.eof || xfer.total == xfer.ota_size)) { + ESP_LOGW(TAG, "Inflate err %d", res); + } + return session.error != ota::OTA_RESPONSE_OK ? session.error : ota::OTA_RESPONSE_ERROR_UNKNOWN; } ESP_LOGD(TAG, "Inflated %zu bytes from %zu", session.written, xfer.total); return ota::OTA_RESPONSE_OK; diff --git a/esphome/components/esphome/ota/ota_esphome_inflate.c b/esphome/components/esphome/ota/ota_esphome_inflate.c index 58baecfc8c..f69c0cdc4c 100644 --- a/esphome/components/esphome/ota/ota_esphome_inflate.c +++ b/esphome/components/esphome/ota/ota_esphome_inflate.c @@ -82,37 +82,6 @@ static const unsigned char CLCIDX[] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, * -- utility functions -- * * ----------------------- */ -/* build the fixed huffman trees */ -static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt) { - int i; - - /* build fixed length tree */ - for (i = 0; i < 7; ++i) - lt->table[i] = 0; - - lt->table[7] = 24; - lt->table[8] = 152; - lt->table[9] = 112; - - for (i = 0; i < 24; ++i) - lt->trans[i] = 256 + i; - for (i = 0; i < 144; ++i) - lt->trans[24 + i] = i; - for (i = 0; i < 8; ++i) - lt->trans[24 + 144 + i] = 280 + i; - for (i = 0; i < 112; ++i) - lt->trans[24 + 144 + 8 + i] = 144 + i; - - /* build fixed distance tree */ - for (i = 0; i < 5; ++i) - dt->table[i] = 0; - - dt->table[5] = 32; - - for (i = 0; i < 32; ++i) - dt->trans[i] = i; -} - /* given an array of code lengths, build a tree */ static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned int num) { unsigned short offs[16]; @@ -319,6 +288,27 @@ static int tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt) { return TINF_OK; } +/* build the fixed huffman trees (RFC 1951 3.2.6) through the generic tree + builder; altered from upstream, which unrolls them by hand */ +static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt) { + unsigned char lengths[288]; + unsigned int i; + + for (i = 0; i < 144; ++i) + lengths[i] = 8; + for (; i < 256; ++i) + lengths[i] = 9; + for (; i < 280; ++i) + lengths[i] = 7; + for (; i < 288; ++i) + lengths[i] = 8; + tinf_build_tree(lt, lengths, 288); + + for (i = 0; i < 32; ++i) + lengths[i] = 5; + tinf_build_tree(dt, lengths, 32); +} + /* ----------------------------- * * -- block inflate functions -- * * ----------------------------- */