From 7335b64a69115d3f64d58ef5dd61b40e50cbef9d Mon Sep 17 00:00:00 2001 From: Gabriel Sieben Date: Tue, 24 Feb 2026 20:04:40 +0100 Subject: [PATCH 01/15] Implement hostname setting for ESP32 WiFi Add hostname configuration for WiFi connection based on cmDNS. --- wled00/wled.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index d67f784078..4e831f4469 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -865,6 +865,17 @@ void WLED::handleConnection() #endif const bool wifiConfigured = WLED_WIFI_CONFIGURED; + // The DNS name of the ESP must be set before the first connection to the DHCP server. Otherwise, the esp default name, such as “esp32s3-267D0C,” will be used. GG + #ifdef ARDUINO_ARCH_ESP32 + // Use cmDNS (this is the buffer that holds your name) + if (cmDNS && cmDNS[0] != '\0') { + WiFi.setHostname(cmDNS); + } else { + // Fallback to DEVICE_NAME if cmDNS is still empty + WiFi.setHostname(WLED_HOST_NAME); + } + #endif + // ignore connection handling if WiFi is configured and scan still running // or within first 2s if WiFi is not configured or AP is always active if ((wifiConfigured && multiWiFi.size() > 1 && WiFi.scanComplete() < 0) || (now < 2000 && (!wifiConfigured || apBehavior == AP_BEHAVIOR_ALWAYS))) From f54537541b4d02a655a52c8846d28a6839c82ee2 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sat, 14 Mar 2026 19:32:54 +0100 Subject: [PATCH 02/15] refactor prepareHostname * refactor legacy prepareHostname() logic, and split hostname sanitization from hostname creation. * always use the max possible length allowed for a FQDN hostname --- wled00/fcn_declare.h | 3 +- wled00/network.cpp | 4 +-- wled00/util.cpp | 67 ++++++++++++++++++++++++++++++++------------ wled00/wled.cpp | 4 +-- 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 67958314b4..195b016194 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -409,7 +409,8 @@ size_t printSetFormValue(Print& settingsScript, const char* key, int val); size_t printSetFormValue(Print& settingsScript, const char* key, const char* val); size_t printSetFormIndex(Print& settingsScript, const char* key, int index); size_t printSetClassElementHTML(Print& settingsScript, const char* key, const int index, const char* val); -void prepareHostname(char* hostname); +void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS=false); // maxLen = hostname buffer size including \0; if preferMDNSname=true, use mdns name (sanitized) +void prepareHostname(char* hostname, size_t maxLen); // legacy function - not recommended for new code [[gnu::pure]] bool isAsterisksOnly(const char* str, byte maxLen); bool requestJSONBufferLock(uint8_t moduleID=JSON_LOCK_UNKNOWN); void releaseJSONBufferLock(); diff --git a/wled00/network.cpp b/wled00/network.cpp index 105fdf6b27..7825c4b88b 100644 --- a/wled00/network.cpp +++ b/wled00/network.cpp @@ -414,8 +414,8 @@ void WiFiEvent(WiFiEvent_t event) WiFi.disconnect(true); // disable WiFi entirely } // convert the "serverDescription" into a valid DNS hostname (alphanumeric) - char hostname[64]; - prepareHostname(hostname); + char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters + getWLEDhostname(hostname, sizeof(hostname)); ETH.setHostname(hostname); showWelcomePage = false; break; diff --git a/wled00/util.cpp b/wled00/util.cpp index c6fbb280b4..cf1f7eabd1 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -127,30 +127,61 @@ size_t printSetClassElementHTML(Print& settingsScript, const char* key, const in } - -void prepareHostname(char* hostname) -{ - sprintf_P(hostname, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); - const char *pC = serverDescription; - unsigned pos = 5; // keep "wled-" - while (*pC && pos < 24) { // while !null and not over length - if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname - hostname[pos] = *pC; - pos++; - } else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') { - hostname[pos] = '-'; - pos++; +// in-place hostname sanitizer, extracted from prepareHostname() +static void sanitizeHostname(char* hostname, size_t maxLen) { + if (hostname == nullptr || maxLen < 1 || strlen(hostname) < 1) return; + + char *pC = hostname; + unsigned pos = 0; + while (*pC && pos < maxLen) { + char c = *pC; + if (isalnum((unsigned char)c)) { + hostname[pos++] = c; + } else if (c == ' ' || c == '_' || c == '-' || c == '+' || c == '!' || c == '?' || c == '*') { // convert certain characters to hyphens + if (pos > 0 && hostname[pos -1] != '-') hostname[pos++] = '-'; // keep single non-leading hyphens only } - // else do nothing - no leading hyphens and do not include hyphens for all other characters. + // else: drop any character not valid in a DNS hostname label pC++; } - //last character must not be hyphen - if (pos > 5) { - while (pos > 4 && hostname[pos -1] == '-') pos--; - hostname[pos] = '\0'; // terminate string (leave at least "wled") + // Hostname must not end with a hyphen. + while (pos > 0 && hostname[pos -1] == '-') pos--; + hostname[min(pos, maxLen-1)] = '\0'; // terminate string +} + +/* + * Stores sanitized hostname into buffer provided by caller + * maxLen = hostname buffer size including \0 + * preferMDNSname -> use mDNS name if set, otherwise fall back to WLED "server description" name (legacy behaviour) + */ +void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { + if (maxLen < 6) return; // buffer too small + if (preferMDNS && strlen(cmDNS) > 0) { + strlcpy(hostname, cmDNS, maxLen); + sanitizeHostname(hostname, maxLen); // sanitize cmDNS name + if (strlen(hostname) < 1) { // if result is empty -> fall back to wled-MAC + snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); + hostname[maxLen -1] = '\0'; // ensure string termination + } + } else { + prepareHostname(hostname, maxLen); // use legacy hostname based on "server description" - already sanitized } } +/* Legacy hostname construction: + * Start with "wled-" + serverDescription as suffix. + * Sanitize only the suffix (always keep wled- prefix intact). + * If the sanitized suffix ends up empty, fall back to wled-. + */ +void prepareHostname(char* hostname, size_t maxLen) +{ + if (maxLen < 6) return; // buffer too small (should not happen) + snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); + hostname[maxLen -1] = '\0'; // ensure string termination + sanitizeHostname(hostname+5, maxLen-5); // sanitize name, keep "wled-" intact + if (strlen(hostname) <= 5) + snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC +} + bool isAsterisksOnly(const char* str, byte maxLen) { diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 4e831f4469..9dc1d93634 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -719,8 +719,8 @@ void WLED::initConnection() DEBUG_PRINTF_P(PSTR("Connecting to %s...\n"), multiWiFi[selectedWiFi].clientSSID); // convert the "serverDescription" into a valid DNS hostname (alphanumeric) - char hostname[25]; - prepareHostname(hostname); + char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters + getWLEDhostname(hostname, sizeof(hostname)); #ifdef WLED_ENABLE_WPA_ENTERPRISE if (multiWiFi[selectedWiFi].encryptionType == WIFI_ENCRYPTION_TYPE_PSK) { From c3cc1a0adeb49f19d236f47bb8e2e9aca64dde4b Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sat, 14 Mar 2026 19:46:54 +0100 Subject: [PATCH 03/15] simplified variant of #5397 * hostname by cmDNS is now included in getWLEDhostname() * ensure that the name is sanitized * avoid using a potentially undefined macro --- wled00/wled.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 9dc1d93634..a1d8755fb2 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -865,15 +865,11 @@ void WLED::handleConnection() #endif const bool wifiConfigured = WLED_WIFI_CONFIGURED; - // The DNS name of the ESP must be set before the first connection to the DHCP server. Otherwise, the esp default name, such as “esp32s3-267D0C,” will be used. GG + // The DNS name of the ESP must be set before the first connection to the DHCP server; otherwise, the default ESP name (such as "esp32s3-267D0C") will be used. #ifdef ARDUINO_ARCH_ESP32 - // Use cmDNS (this is the buffer that holds your name) - if (cmDNS && cmDNS[0] != '\0') { - WiFi.setHostname(cmDNS); - } else { - // Fallback to DEVICE_NAME if cmDNS is still empty - WiFi.setHostname(WLED_HOST_NAME); - } + char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters + getWLEDhostname(hostname, sizeof(hostname), true); // create DNS name based on mDNS name if set, or fall back to standard WLED server name + WiFi.setHostname(hostname); #endif // ignore connection handling if WiFi is configured and scan still running From a28d970584322ca1bc6256efb14c2b8c8032d6e7 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sat, 14 Mar 2026 20:13:49 +0100 Subject: [PATCH 04/15] guarantee deterministic output even with too-small buffer robustness improvement. --- wled00/util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index cf1f7eabd1..226b2bce0b 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -154,7 +154,7 @@ static void sanitizeHostname(char* hostname, size_t maxLen) { * preferMDNSname -> use mDNS name if set, otherwise fall back to WLED "server description" name (legacy behaviour) */ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { - if (maxLen < 6) return; // buffer too small + if (maxLen < 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) if (preferMDNS && strlen(cmDNS) > 0) { strlcpy(hostname, cmDNS, maxLen); sanitizeHostname(hostname, maxLen); // sanitize cmDNS name @@ -174,7 +174,7 @@ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { */ void prepareHostname(char* hostname, size_t maxLen) { - if (maxLen < 6) return; // buffer too small (should not happen) + if (maxLen < 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); hostname[maxLen -1] = '\0'; // ensure string termination sanitizeHostname(hostname+5, maxLen-5); // sanitize name, keep "wled-" intact From 8880894486dbdecc3bdeba165944644d3bc74239 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sat, 14 Mar 2026 20:22:33 +0100 Subject: [PATCH 05/15] Tighten the small-buffer guard to avoid returning wled- on 6-byte buffers --- wled00/util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index 226b2bce0b..d1b4d6923d 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -154,7 +154,7 @@ static void sanitizeHostname(char* hostname, size_t maxLen) { * preferMDNSname -> use mDNS name if set, otherwise fall back to WLED "server description" name (legacy behaviour) */ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { - if (maxLen < 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) + if (maxLen <= 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) if (preferMDNS && strlen(cmDNS) > 0) { strlcpy(hostname, cmDNS, maxLen); sanitizeHostname(hostname, maxLen); // sanitize cmDNS name @@ -174,7 +174,7 @@ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { */ void prepareHostname(char* hostname, size_t maxLen) { - if (maxLen < 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) + if (maxLen <= 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); hostname[maxLen -1] = '\0'; // ensure string termination sanitizeHostname(hostname+5, maxLen-5); // sanitize name, keep "wled-" intact From 6ff7efb7ffb9ab76ec18359c4e2bb07682cb3767 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sat, 14 Mar 2026 23:51:28 +0100 Subject: [PATCH 06/15] esp32: set hostname before wifi.mode(STA) * follow the rabbit's suggestion to set the hostname before WiFi.mode(STA) * WiFi.mode(WIFI_MODE_NULL) after WiFi.disconnect(), to ensure that all changes are applied on wifi re-start --- wled00/wled.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index a1d8755fb2..4755d265a7 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -507,8 +507,12 @@ void WLED::setup() #ifndef ESP8266 WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.persistent(true); // storing credentials in NVM fixes boot-up pause as connection is much faster, is disabled after first connection + // ESP32 DNS name must be set before the first connection to the DHCP server; otherwise, the default ESP name (such as "esp32s3-267D0C") will be used. + char hostname[64] = {'\0'}; + getWLEDhostname(hostname, sizeof(hostname), true); // create DNS name based on mDNS name if set, or fall back to standard WLED server name + WiFi.setHostname(hostname); #else - WiFi.persistent(false); // on ES8266 using NVM for wifi config has no benefit of faster connection + WiFi.persistent(false); // on ESP8266 using NVM for wifi config has no benefit of faster connection #endif WiFi.onEvent(WiFiEvent); WiFi.mode(WIFI_STA); // enable scanning @@ -691,6 +695,18 @@ void WLED::initConnection() WiFi.setPhyMode(force802_3g ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N); #endif + char hostname[64] = {'\0'}; + getWLEDhostname(hostname, sizeof(hostname), true); // create DNS name based on mDNS name if set, or fall back to standard WLED server name + +#ifdef ARDUINO_ARCH_ESP32 + // Reset mode to NULL to force a full STA mode transition, so that WiFi.mode(WIFI_STA) below actually applies the hostname (and TX power, etc.). + // This is required on reconnects when mode is already WIFI_STA. + WiFi.mode(WIFI_MODE_NULL); + delay(5); // give the WiFi stack time to complete the mode transition + WiFi.setHostname(hostname); + DEBUG_PRINTF("\ninitConnection setHostname(%s)\n\n", hostname); +#endif + if (multiWiFi[selectedWiFi].staticIP != 0U && multiWiFi[selectedWiFi].staticGW != 0U) { WiFi.config(multiWiFi[selectedWiFi].staticIP, multiWiFi[selectedWiFi].staticGW, multiWiFi[selectedWiFi].staticSN, dnsAddress); } else { @@ -718,10 +734,6 @@ void WLED::initConnection() DEBUG_PRINTF_P(PSTR("Connecting to %s...\n"), multiWiFi[selectedWiFi].clientSSID); - // convert the "serverDescription" into a valid DNS hostname (alphanumeric) - char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters - getWLEDhostname(hostname, sizeof(hostname)); - #ifdef WLED_ENABLE_WPA_ENTERPRISE if (multiWiFi[selectedWiFi].encryptionType == WIFI_ENCRYPTION_TYPE_PSK) { DEBUG_PRINTLN(F("Using PSK")); @@ -774,8 +786,8 @@ void WLED::initConnection() #ifdef ARDUINO_ARCH_ESP32 WiFi.setTxPower(wifi_power_t(txPower)); WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(hostname); -#else + WiFi.setHostname(hostname); // ToDO: check if this is needed here +#else // ESP8266 accepts a hostname set after WiFi interface initialization wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); WiFi.hostname(hostname); #endif @@ -864,13 +876,6 @@ void WLED::handleConnection() const unsigned long nowS = now/1000; #endif const bool wifiConfigured = WLED_WIFI_CONFIGURED; - - // The DNS name of the ESP must be set before the first connection to the DHCP server; otherwise, the default ESP name (such as "esp32s3-267D0C") will be used. - #ifdef ARDUINO_ARCH_ESP32 - char hostname[64] = {'\0'}; // any "hostname" within a Fully Qualified Domain Name (FQDN) must not exceed 63 characters - getWLEDhostname(hostname, sizeof(hostname), true); // create DNS name based on mDNS name if set, or fall back to standard WLED server name - WiFi.setHostname(hostname); - #endif // ignore connection handling if WiFi is configured and scan still running // or within first 2s if WiFi is not configured or AP is always active From 22bf4a5157e89fd809006da097e47c1dede319ed Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sat, 14 Mar 2026 23:56:11 +0100 Subject: [PATCH 07/15] remove debug statement --- wled00/wled.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 4755d265a7..a93ed42d57 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -704,7 +704,6 @@ void WLED::initConnection() WiFi.mode(WIFI_MODE_NULL); delay(5); // give the WiFi stack time to complete the mode transition WiFi.setHostname(hostname); - DEBUG_PRINTF("\ninitConnection setHostname(%s)\n\n", hostname); #endif if (multiWiFi[selectedWiFi].staticIP != 0U && multiWiFi[selectedWiFi].staticGW != 0U) { From bac797c6dd045f629a465312fed84927431a4a8b Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 00:10:49 +0100 Subject: [PATCH 08/15] avoid wled-WLED- as hostname by checking if the serverDescription also start with "wled". --- wled00/util.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index d1b4d6923d..906fe44920 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -175,8 +175,12 @@ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { void prepareHostname(char* hostname, size_t maxLen) { if (maxLen <= 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) - snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); + if (strncasecmp(serverDescription, "wled", 4) == 0) // avoid wled-WLED-... as a hostname + strlcpy(hostname, serverDescription, maxLen); + else + snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); hostname[maxLen -1] = '\0'; // ensure string termination + sanitizeHostname(hostname+5, maxLen-5); // sanitize name, keep "wled-" intact if (strlen(hostname) <= 5) snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC From 3e7c66e604cb9392b7e06500fa281f3040f6bb09 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 00:14:43 +0100 Subject: [PATCH 09/15] keep ApActive flag in sync with AP state --- wled00/wled.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index a93ed42d57..e64e76615c 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -702,6 +702,7 @@ void WLED::initConnection() // Reset mode to NULL to force a full STA mode transition, so that WiFi.mode(WIFI_STA) below actually applies the hostname (and TX power, etc.). // This is required on reconnects when mode is already WIFI_STA. WiFi.mode(WIFI_MODE_NULL); + apActive = false; // the AP is physically torn down by WIFI_MODE_NULL delay(5); // give the WiFi stack time to complete the mode transition WiFi.setHostname(hostname); #endif From f4b1bfda643caa32b58a069f132451cc3131b8f7 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 00:16:59 +0100 Subject: [PATCH 10/15] remove redundant WiFi.setHostname() call --- wled00/wled.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index e64e76615c..b28e40a22c 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -786,7 +786,6 @@ void WLED::initConnection() #ifdef ARDUINO_ARCH_ESP32 WiFi.setTxPower(wifi_power_t(txPower)); WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(hostname); // ToDO: check if this is needed here #else // ESP8266 accepts a hostname set after WiFi interface initialization wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); WiFi.hostname(hostname); From 5417552b8e9bd3c2673dfd83d740aaea0efc9ac2 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 00:37:22 +0100 Subject: [PATCH 11/15] ensure that "WLED foo" and "WLED!foo" get sanitized --- wled00/util.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index 906fe44920..dc38194393 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -175,13 +175,14 @@ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { void prepareHostname(char* hostname, size_t maxLen) { if (maxLen <= 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) - if (strncasecmp(serverDescription, "wled", 4) == 0) // avoid wled-WLED-... as a hostname + if (strncasecmp(serverDescription, "wled", 4) == 0) // avoid wled-WLED-... as a hostname strlcpy(hostname, serverDescription, maxLen); else snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); - hostname[maxLen -1] = '\0'; // ensure string termination + hostname[maxLen -1] = '\0'; // ensure string termination - sanitizeHostname(hostname+5, maxLen-5); // sanitize name, keep "wled-" intact + size_t sanOffset = hostname[4]!='-' ? 4 : 5; // ensure that "WLED foo" and "WLED!foo" get sanitized + sanitizeHostname(hostname+sanOffset, maxLen-sanOffset); // sanitize name, keep "wled-" intact if (strlen(hostname) <= 5) snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC } From 0bc87a379dd512c82bab9793a7c46370d29bcb34 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 11:15:16 +0100 Subject: [PATCH 12/15] progmem optimization saves 5 bytes of RAM on 8266 --- wled00/util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index dc38194393..850d623598 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -175,13 +175,13 @@ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { void prepareHostname(char* hostname, size_t maxLen) { if (maxLen <= 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) - if (strncasecmp(serverDescription, "wled", 4) == 0) // avoid wled-WLED-... as a hostname + if (strncasecmp_P(serverDescription, PSTR("wled"), 4) == 0) // avoid wled-WLED-... as a hostname strlcpy(hostname, serverDescription, maxLen); else snprintf_P(hostname, maxLen, PSTR("wled-%s"), serverDescription); hostname[maxLen -1] = '\0'; // ensure string termination - size_t sanOffset = hostname[4]!='-' ? 4 : 5; // ensure that "WLED foo" and "WLED!foo" get sanitized + size_t sanOffset = hostname[4] != '-' ? 4 : 5; // ensure that "WLED foo" and "WLED!foo" get sanitized sanitizeHostname(hostname+sanOffset, maxLen-sanOffset); // sanitize name, keep "wled-" intact if (strlen(hostname) <= 5) snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC From 10dfb1f7b7205e9bcc8622aa1eeb47c413045aaa Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 11:34:20 +0100 Subject: [PATCH 13/15] fix off-by-one corner case Names like WLED0 or WLEDa survive sanitization, but strlen(hostname) == 5 still sends them down the wled- fallback path. --- wled00/util.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index 850d623598..1bc94ad55c 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -182,9 +182,9 @@ void prepareHostname(char* hostname, size_t maxLen) hostname[maxLen -1] = '\0'; // ensure string termination size_t sanOffset = hostname[4] != '-' ? 4 : 5; // ensure that "WLED foo" and "WLED!foo" get sanitized - sanitizeHostname(hostname+sanOffset, maxLen-sanOffset); // sanitize name, keep "wled-" intact - if (strlen(hostname) <= 5) - snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC + sanitizeHostname(hostname+sanOffset, maxLen-sanOffset); // sanitize name, keep "wled-" intact + if (strlen(hostname) <= sanOffset) + snprintf_P(hostname, maxLen, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); // fallback to wled-MAC if sanitization cleaned everything } From f8c903ae765d7f63689446e2e8466c964e423d0e Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 11:42:00 +0100 Subject: [PATCH 14/15] undo whitespace change --- wled00/wled.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index b28e40a22c..305ce35fac 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -875,7 +875,7 @@ void WLED::handleConnection() const unsigned long nowS = now/1000; #endif const bool wifiConfigured = WLED_WIFI_CONFIGURED; - + // ignore connection handling if WiFi is configured and scan still running // or within first 2s if WiFi is not configured or AP is always active if ((wifiConfigured && multiWiFi.size() > 1 && WiFi.scanComplete() < 0) || (now < 2000 && (!wifiConfigured || apBehavior == AP_BEHAVIOR_ALWAYS))) From c9d983ebdc3e65258cdb4ed4dec70858fe6dadaf Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 15 Mar 2026 16:20:07 +0100 Subject: [PATCH 15/15] protect against special case "x" avoid "x" = not set (default MDNS) --- wled00/util.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wled00/util.cpp b/wled00/util.cpp index 1bc94ad55c..393e9eb165 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -155,7 +155,7 @@ static void sanitizeHostname(char* hostname, size_t maxLen) { */ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { if (maxLen <= 6) { strlcpy(hostname, "wled", maxLen); return; } // buffer too small (should not happen) - if (preferMDNS && strlen(cmDNS) > 0) { + if (preferMDNS && (strlen(cmDNS) > 0) && (strcmp_P(cmDNS, PSTR(DEFAULT_MDNS_NAME)) != 0)) { // avoid "x" = not set (use wled-MAC) strlcpy(hostname, cmDNS, maxLen); sanitizeHostname(hostname, maxLen); // sanitize cmDNS name if (strlen(hostname) < 1) { // if result is empty -> fall back to wled-MAC @@ -165,6 +165,7 @@ void getWLEDhostname(char* hostname, size_t maxLen, bool preferMDNS) { } else { prepareHostname(hostname, maxLen); // use legacy hostname based on "server description" - already sanitized } + DEBUG_PRINTF_P(PSTR("getWLEDHostname: '%s'\n"), hostname); } /* Legacy hostname construction: