From 7ad44c68f7761c400512b42e1a447474deae820b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 26 Feb 2026 11:23:41 -1000 Subject: [PATCH] [wifi] Fix CYW43 scan SSID not null-terminated The cyw43_ev_scan_result_t ssid field is a 32-byte buffer that is not guaranteed to be null-terminated. Use ssid_len to properly terminate the string before passing it to string comparison functions. This fixes false "should be marked hidden" warnings where the SSID match failed due to garbage bytes after the actual SSID in the buffer. --- .../components/wifi/wifi_component_pico_w.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 7200325d1b..e4a6dbaaa4 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -147,18 +147,24 @@ int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *r void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) { s_scan_result_count++; - const char *ssid_cstr = reinterpret_cast(result->ssid); + + // CYW43 scan results have ssid as a 32-byte buffer that is NOT null-terminated. + // Use ssid_len to create a properly terminated copy for string operations. + uint8_t len = std::min(result->ssid_len, static_cast(sizeof(result->ssid))); + char ssid_buf[33]; // 32 max + null terminator + memcpy(ssid_buf, result->ssid, len); + ssid_buf[len] = '\0'; // Skip networks that don't match any configured network (unless full results needed) - if (!this->needs_full_scan_results_() && !this->matches_configured_network_(ssid_cstr, result->bssid)) { - this->log_discarded_scan_result_(ssid_cstr, result->bssid, result->rssi, result->channel); + if (!this->needs_full_scan_results_() && !this->matches_configured_network_(ssid_buf, result->bssid)) { + this->log_discarded_scan_result_(ssid_buf, result->bssid, result->rssi, result->channel); return; } bssid_t bssid; std::copy(result->bssid, result->bssid + 6, bssid.begin()); - WiFiScanResult res(bssid, ssid_cstr, strlen(ssid_cstr), result->channel, result->rssi, - result->auth_mode != CYW43_AUTH_OPEN, ssid_cstr[0] == '\0'); + WiFiScanResult res(bssid, ssid_buf, len, result->channel, result->rssi, result->auth_mode != CYW43_AUTH_OPEN, + len == 0); if (std::find(this->scan_result_.begin(), this->scan_result_.end(), res) == this->scan_result_.end()) { this->scan_result_.push_back(res); }