From 70503442f4e743793222c529ef56a03c08a8c4d2 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:37:29 -0400 Subject: [PATCH 1/7] [dfrobot_sen0395] Brace single-statement else-if in enqueue() (#16089) --- esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp b/esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp index f47025698b..98901bd353 100644 --- a/esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +++ b/esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp @@ -104,8 +104,9 @@ int8_t CircularCommandQueue::enqueue(std::unique_ptr cmd) { if (this->is_full()) { ESP_LOGE(TAG, "Command queue is full"); return -1; - } else if (this->is_empty()) + } else if (this->is_empty()) { front_++; + } rear_ = (rear_ + 1) % COMMAND_QUEUE_SIZE; commands_[rear_] = std::move(cmd); // Transfer ownership using std::move return 1; From 16cf4fb5e8818933de0f833170ad4acde7a8f105 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:47:20 -0400 Subject: [PATCH 2/7] [nextion] Use std::string::starts_with for HTTPS URL check (#16090) --- esphome/components/nextion/nextion_upload_arduino.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/nextion/nextion_upload_arduino.cpp b/esphome/components/nextion/nextion_upload_arduino.cpp index e0d18352ff..399f217a19 100644 --- a/esphome/components/nextion/nextion_upload_arduino.cpp +++ b/esphome/components/nextion/nextion_upload_arduino.cpp @@ -331,7 +331,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { #ifdef USE_ESP8266 WiFiClient *Nextion::get_wifi_client_() { - if (this->tft_url_.compare(0, 6, "https:") == 0) { + if (this->tft_url_.starts_with("https:")) { if (this->wifi_client_secure_ == nullptr) { // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) this->wifi_client_secure_ = new BearSSL::WiFiClientSecure(); From 3d195d748c258236532dcc843dd24487956d06b6 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:50:15 -0400 Subject: [PATCH 3/7] [ezo] Use make_unique to construct EzoCommand (#16092) --- esphome/components/ezo/ezo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/ezo/ezo.cpp b/esphome/components/ezo/ezo.cpp index 2dc65b7d14..bb8fb92f21 100644 --- a/esphome/components/ezo/ezo.cpp +++ b/esphome/components/ezo/ezo.cpp @@ -35,7 +35,7 @@ void EZOSensor::update() { } if (!found) { - std::unique_ptr ezo_command(new EzoCommand); + auto ezo_command = make_unique(); ezo_command->command = "R"; ezo_command->command_type = EzoCommandType::EZO_READ; ezo_command->delay_ms = 900; @@ -162,7 +162,7 @@ void EZOSensor::loop() { } void EZOSensor::add_command_(const char *command, EzoCommandType command_type, uint16_t delay_ms) { - std::unique_ptr ezo_command(new EzoCommand); + auto ezo_command = make_unique(); ezo_command->command = command; ezo_command->command_type = command_type; ezo_command->delay_ms = delay_ms; From ab6bda50e46eab26bc229618bdc9375fe8cd52dc Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:58:40 -0400 Subject: [PATCH 4/7] [esp32_ble] Widen loop variable in as_128bit() to match uuid_.len type (#16088) --- esphome/components/esp32_ble/ble_uuid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/esp32_ble/ble_uuid.cpp b/esphome/components/esp32_ble/ble_uuid.cpp index 334780e3b8..886f8237ad 100644 --- a/esphome/components/esp32_ble/ble_uuid.cpp +++ b/esphome/components/esp32_ble/ble_uuid.cpp @@ -104,7 +104,7 @@ ESPBTUUID ESPBTUUID::as_128bit() const { } else { uuid32 = this->uuid_.uuid.uuid16; } - for (uint8_t i = 0; i < this->uuid_.len; i++) { + for (uint16_t i = 0; i < this->uuid_.len; i++) { data[12 + i] = ((uuid32 >> i * 8) & 0xFF); } return ESPBTUUID::from_raw(data); From 7d6b9bee19ffe49e0fab2c9c30252368c61a3cc0 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:22:29 -0400 Subject: [PATCH 5/7] [wifi] Avoid copying EAP config in three connect handlers (#16094) --- esphome/components/wifi/wifi_component.cpp | 4 ++-- esphome/components/wifi/wifi_component_esp8266.cpp | 4 ++-- esphome/components/wifi/wifi_component_esp_idf.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index f7c70b1147..1da2d630c1 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -1099,9 +1099,9 @@ void WiFiComponent::start_connecting(const WiFiAP &ap) { } #ifdef USE_WIFI_WPA2_EAP - auto eap_opt = ap.get_eap(); + const auto &eap_opt = ap.get_eap(); if (eap_opt.has_value()) { - EAPAuth eap_config = *eap_opt; + const EAPAuth &eap_config = *eap_opt; // clang-format off ESP_LOGV( TAG, diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index bf3a0d2949..402ca051cd 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -313,10 +313,10 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { // setup enterprise authentication if required #ifdef USE_WIFI_WPA2_EAP - auto eap_opt = ap.get_eap(); + const auto &eap_opt = ap.get_eap(); if (eap_opt.has_value()) { // note: all certificates and keys have to be null terminated. Lengths are appended by +1 to include \0. - EAPAuth eap = *eap_opt; + const EAPAuth &eap = *eap_opt; ret = wifi_station_set_enterprise_identity((uint8_t *) eap.identity.c_str(), eap.identity.length()); if (ret) { ESP_LOGV(TAG, "esp_wifi_sta_wpa2_ent_set_identity failed: %d", ret); diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 82ecc80811..4f39a3a4b1 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -407,10 +407,10 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { // setup enterprise authentication if required #ifdef USE_WIFI_WPA2_EAP - auto eap_opt = ap.get_eap(); + const auto &eap_opt = ap.get_eap(); if (eap_opt.has_value()) { // note: all certificates and keys have to be null terminated. Lengths are appended by +1 to include \0. - EAPAuth eap = *eap_opt; + const EAPAuth &eap = *eap_opt; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) err = esp_eap_client_set_identity((uint8_t *) eap.identity.c_str(), eap.identity.length()); #else From a62e3fe4fcd13d135cd5710d4dd0189fd7d56cff Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:35:40 -0400 Subject: [PATCH 6/7] [json] NOLINT StackAddressEscape false positive in parse_json (#16091) --- esphome/components/json/json_util.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esphome/components/json/json_util.cpp b/esphome/components/json/json_util.cpp index edcd23f922..ec1490be1f 100644 --- a/esphome/components/json/json_util.cpp +++ b/esphome/components/json/json_util.cpp @@ -39,7 +39,8 @@ bool parse_json(const uint8_t *data, size_t len, const json_parse_t &f) { } JsonDocument parse_json(const uint8_t *data, size_t len) { - // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson + // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks,clang-analyzer-core.StackAddressEscape) false positives with + // ArduinoJson if (data == nullptr || len == 0) { ESP_LOGE(TAG, "No data to parse"); return JsonObject(); // return unbound object @@ -63,7 +64,7 @@ JsonDocument parse_json(const uint8_t *data, size_t len) { } ESP_LOGE(TAG, "Parse error: %s", err.c_str()); return JsonObject(); // return unbound object - // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks) + // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks,clang-analyzer-core.StackAddressEscape) } SerializationBuffer<> JsonBuilder::serialize() { From e39c474577e73c5467b0e6828af4460f844e25b7 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:13:35 -0400 Subject: [PATCH 7/7] [binary_sensor] Bind at_index_ once in MultiClick on_state_ (#16095) --- esphome/components/binary_sensor/automation.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/esphome/components/binary_sensor/automation.cpp b/esphome/components/binary_sensor/automation.cpp index eb68abce3b..b13e4a88dd 100644 --- a/esphome/components/binary_sensor/automation.cpp +++ b/esphome/components/binary_sensor/automation.cpp @@ -50,29 +50,31 @@ void MultiClickTriggerBase::on_state_(bool state) { return; } - if (*this->at_index_ == this->timing_count_) { + // at_index_ has a value here (the !has_value() branch above returns). + size_t at_index = *this->at_index_; + if (at_index == this->timing_count_) { this->trigger_(); return; } - MultiClickTriggerEvent evt = this->timing_[*this->at_index_]; + MultiClickTriggerEvent evt = this->timing_[at_index]; if (evt.max_length != 4294967294UL) { - ESP_LOGV(TAG, "A i=%zu min=%" PRIu32 " max=%" PRIu32, *this->at_index_, evt.min_length, evt.max_length); // NOLINT + ESP_LOGV(TAG, "A i=%zu min=%" PRIu32 " max=%" PRIu32, at_index, evt.min_length, evt.max_length); // NOLINT this->schedule_is_valid_(evt.min_length); this->schedule_is_not_valid_(evt.max_length); - } else if (*this->at_index_ + 1 != this->timing_count_) { - ESP_LOGV(TAG, "B i=%zu min=%" PRIu32, *this->at_index_, evt.min_length); // NOLINT + } else if (at_index + 1 != this->timing_count_) { + ESP_LOGV(TAG, "B i=%zu min=%" PRIu32, at_index, evt.min_length); // NOLINT this->cancel_timeout(MULTICLICK_IS_NOT_VALID_ID); this->schedule_is_valid_(evt.min_length); } else { - ESP_LOGV(TAG, "C i=%zu min=%" PRIu32, *this->at_index_, evt.min_length); // NOLINT + ESP_LOGV(TAG, "C i=%zu min=%" PRIu32, at_index, evt.min_length); // NOLINT this->is_valid_ = false; this->cancel_timeout(MULTICLICK_IS_NOT_VALID_ID); this->set_timeout(MULTICLICK_TRIGGER_ID, evt.min_length, [this]() { this->trigger_(); }); } - *this->at_index_ = *this->at_index_ + 1; + this->at_index_ = at_index + 1; } void MultiClickTriggerBase::schedule_cooldown_() { ESP_LOGV(TAG, "Multi Click: Invalid length of press, starting cooldown of %" PRIu32 " ms", this->invalid_cooldown_);