From 91d144901a1efbeefec88a001e3c711476aa31cd Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Thu, 5 Feb 2026 09:47:01 -0700 Subject: [PATCH] Fix dangling pointer bug in WiFiManager getSSID/getConnectionName WiFi.SSID() returns a temporary String object. Calling .c_str() on it returns a pointer to the internal buffer, but the String is destroyed at the end of the statement - leaving a dangling pointer. Fix by caching the SSID in a member variable when connection state changes, and returning a pointer to that stable storage. Also fix getWiFiStatus() in MyMesh.cpp which was using WiFiState enum values instead of NetworkState (the interface return type). --- src/MyMesh.cpp | 6 +++--- src/WiFiManager.cpp | 19 +++++++++++-------- src/WiFiManager.h | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/MyMesh.cpp b/src/MyMesh.cpp index 30c9a12..6447302 100644 --- a/src/MyMesh.cpp +++ b/src/MyMesh.cpp @@ -1289,9 +1289,9 @@ const char* MyMesh::getMQTTStatus() const { const char* MyMesh::getWiFiStatus() const { switch (_wifi_mgr.getState()) { - case WiFiState::CONNECTED: return "connected"; - case WiFiState::CONNECTING: return "connecting"; - case WiFiState::AP_MODE: return "ap_mode"; + case NetworkState::CONNECTED: return "connected"; + case NetworkState::CONNECTING: return "connecting"; + case NetworkState::AP_MODE: return "ap_mode"; default: return "disconnected"; } } diff --git a/src/WiFiManager.cpp b/src/WiFiManager.cpp index 4ac1fbb..54e2117 100644 --- a/src/WiFiManager.cpp +++ b/src/WiFiManager.cpp @@ -10,6 +10,7 @@ WiFiManager::WiFiManager() _retry_count(0), _initialized(false) { memset(&_config, 0, sizeof(_config)); + memset(_cached_ssid, 0, sizeof(_cached_ssid)); } void WiFiManager::begin(const WiFiConfig& config) { @@ -82,6 +83,9 @@ void WiFiManager::loop() { _state = WiFiState::CONNECTED; _connected_since = millis(); _retry_count = 0; + // Cache SSID to avoid dangling pointer from WiFi.SSID().c_str() + strncpy(_cached_ssid, WiFi.SSID().c_str(), sizeof(_cached_ssid) - 1); + _cached_ssid[sizeof(_cached_ssid) - 1] = '\0'; Serial.printf("[WiFi] Connected! IP: %s, RSSI: %d dBm\n", WiFi.localIP().toString().c_str(), WiFi.RSSI()); } else if (status == WL_NO_SSID_AVAIL) { @@ -184,6 +188,9 @@ void WiFiManager::startAPMode() { if (success) { _state = WiFiState::AP_MODE; + // Cache AP SSID to avoid dangling pointer + strncpy(_cached_ssid, ap_ssid.c_str(), sizeof(_cached_ssid) - 1); + _cached_ssid[sizeof(_cached_ssid) - 1] = '\0'; Serial.printf("[WiFi] AP started: SSID='%s', IP=%s\n", ap_ssid.c_str(), WiFi.softAPIP().toString().c_str()); } else { @@ -221,10 +228,8 @@ int32_t WiFiManager::getRSSI() const { } const char* WiFiManager::getSSID() const { - if (_state == WiFiState::CONNECTED) { - return WiFi.SSID().c_str(); - } else if (_state == WiFiState::AP_MODE) { - return WiFi.softAPSSID().c_str(); + if (_state == WiFiState::CONNECTED || _state == WiFiState::AP_MODE) { + return _cached_ssid; } return ""; } @@ -264,10 +269,8 @@ NetworkState WiFiManager::getState() const { } const char* WiFiManager::getConnectionName() const { - if (_state == WiFiState::CONNECTED) { - return WiFi.SSID().c_str(); - } else if (_state == WiFiState::AP_MODE) { - return WiFi.softAPSSID().c_str(); + if (_state == WiFiState::CONNECTED || _state == WiFiState::AP_MODE) { + return _cached_ssid; } return "Not connected"; } diff --git a/src/WiFiManager.h b/src/WiFiManager.h index 23051e7..c780143 100644 --- a/src/WiFiManager.h +++ b/src/WiFiManager.h @@ -61,6 +61,7 @@ private: unsigned long _connected_since; uint8_t _retry_count; bool _initialized; + char _cached_ssid[33]; // Cached SSID to avoid dangling pointer from WiFi.SSID().c_str() void attemptConnection(); void checkConnection();