From 2cc5e24b38b7217630525034ee3b4042cb22deb8 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Sat, 11 Oct 2025 20:44:44 -0400 Subject: [PATCH 1/6] [esp32] Change Arduino dev & latest to 3.3.2 (#11169) --- esphome/components/esp32/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index d9b8d067a4..56ab2eda88 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -325,8 +325,8 @@ def _is_framework_url(source: str) -> str: # - https://github.com/espressif/arduino-esp32/releases ARDUINO_FRAMEWORK_VERSION_LOOKUP = { "recommended": cv.Version(3, 2, 1), - "latest": cv.Version(3, 3, 1), - "dev": cv.Version(3, 3, 1), + "latest": cv.Version(3, 3, 2), + "dev": cv.Version(3, 3, 2), } ARDUINO_PLATFORM_VERSION_LOOKUP = { cv.Version(3, 3, 2): cv.Version(55, 3, 31, "1"), From 9f20c48a24e4adbada8c7106c8700da433cb59e3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Oct 2025 15:23:51 -1000 Subject: [PATCH 2/6] adjust --- esphome/components/esp32_ble/ble.cpp | 6 +++++- esphome/components/ethernet/ethernet_component.cpp | 4 +++- esphome/components/mqtt/mqtt_client.cpp | 3 ++- esphome/components/wifi/wifi_component.cpp | 4 +++- esphome/core/application.h | 10 +++++++--- esphome/core/helpers.cpp | 11 ++++++++--- esphome/core/helpers.h | 5 +++-- 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/esphome/components/esp32_ble/ble.cpp b/esphome/components/esp32_ble/ble.cpp index e37b45fe71..7072a485a1 100644 --- a/esphome/components/esp32_ble/ble.cpp +++ b/esphome/components/esp32_ble/ble.cpp @@ -213,7 +213,11 @@ bool ESP32BLE::ble_setup_() { if (this->name_.has_value()) { name = this->name_.value(); if (App.is_name_add_mac_suffix_enabled()) { - name = make_name_with_suffix(name, '-', get_mac_address().substr(6)); + // MAC address suffix length (last 6 characters of 12-char MAC address string) + constexpr size_t MAC_ADDRESS_SUFFIX_LEN = 6; + const std::string mac_addr = get_mac_address(); + const char *mac_suffix_ptr = mac_addr.c_str() + MAC_ADDRESS_SUFFIX_LEN; + name = make_name_with_suffix(name, '-', mac_suffix_ptr, MAC_ADDRESS_SUFFIX_LEN); } } else { name = App.get_name(); diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index 5f28d6db25..8257e37b52 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -691,7 +691,9 @@ void EthernetComponent::set_manual_ip(const ManualIP &manual_ip) { this->manual_ std::string EthernetComponent::get_use_address() const { if (this->use_address_.empty()) { - return make_name_with_suffix(App.get_name(), '.', "local"); + // ".local" suffix length for mDNS hostnames + constexpr size_t MDNS_LOCAL_SUFFIX_LEN = 5; + return make_name_with_suffix(App.get_name(), '.', "local", MDNS_LOCAL_SUFFIX_LEN); } return this->use_address_; } diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 3642ddb38e..16f54ab8a0 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -29,7 +29,8 @@ static const char *const TAG = "mqtt"; MQTTClientComponent::MQTTClientComponent() { global_mqtt_client = this; - this->credentials_.client_id = make_name_with_suffix(App.get_name(), '-', get_mac_address()); + const std::string mac_addr = get_mac_address(); + this->credentials_.client_id = make_name_with_suffix(App.get_name(), '-', mac_addr.c_str(), mac_addr.size()); } // Connection diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index ec8687e927..db9b1d43fa 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -267,7 +267,9 @@ network::IPAddress WiFiComponent::get_dns_address(int num) { } std::string WiFiComponent::get_use_address() const { if (this->use_address_.empty()) { - return make_name_with_suffix(App.get_name(), '.', "local"); + // ".local" suffix length for mDNS hostnames + constexpr size_t MDNS_LOCAL_SUFFIX_LEN = 5; + return make_name_with_suffix(App.get_name(), '.', "local", MDNS_LOCAL_SUFFIX_LEN); } return this->use_address_; } diff --git a/esphome/core/application.h b/esphome/core/application.h index 47e902a191..646c2376bb 100644 --- a/esphome/core/application.h +++ b/esphome/core/application.h @@ -102,10 +102,14 @@ class Application { arch_init(); this->name_add_mac_suffix_ = name_add_mac_suffix; if (name_add_mac_suffix) { - const std::string mac_suffix = get_mac_address().substr(6); - this->name_ = make_name_with_suffix(name, '-', mac_suffix); + // MAC address suffix length (last 6 characters of 12-char MAC address string) + constexpr size_t MAC_ADDRESS_SUFFIX_LEN = 6; + const std::string mac_addr = get_mac_address(); + // Use pointer + offset to avoid substr() allocation + const char *mac_suffix_ptr = mac_addr.c_str() + MAC_ADDRESS_SUFFIX_LEN; + this->name_ = make_name_with_suffix(name, '-', mac_suffix_ptr, MAC_ADDRESS_SUFFIX_LEN); if (!friendly_name.empty()) { - this->friendly_name_ = make_name_with_suffix(friendly_name, ' ', mac_suffix); + this->friendly_name_ = make_name_with_suffix(friendly_name, ' ', mac_suffix_ptr, MAC_ADDRESS_SUFFIX_LEN); } } else { this->name_ = name; diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 0b6c203c01..cabd9ffd16 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -237,11 +237,16 @@ std::string str_sprintf(const char *fmt, ...) { // Maximum size for name with suffix: 120 (max friendly name) + 1 (separator) + 6 (MAC suffix) + 1 (null term) static constexpr size_t MAX_NAME_WITH_SUFFIX_SIZE = 128; +// MAC address suffix length (last 6 characters of 12-char MAC address string) +static constexpr size_t MAC_ADDRESS_SUFFIX_LEN = 6; +// Full MAC address string length (lowercase hex without separators) +static constexpr size_t MAC_ADDRESS_LEN = 12; +// ".local" suffix length for mDNS hostnames +static constexpr size_t MDNS_LOCAL_SUFFIX_LEN = 5; -std::string make_name_with_suffix(const std::string &name, char sep, const std::string &suffix) { +std::string make_name_with_suffix(const std::string &name, char sep, const char *suffix_ptr, size_t suffix_len) { char buffer[MAX_NAME_WITH_SUFFIX_SIZE]; size_t name_len = name.size(); - size_t suffix_len = suffix.size(); size_t total_len = name_len + 1 + suffix_len; // Silently truncate if needed: prioritize keeping the full suffix @@ -255,7 +260,7 @@ std::string make_name_with_suffix(const std::string &name, char sep, const std:: memcpy(buffer, name.c_str(), name_len); buffer[name_len] = sep; - memcpy(buffer + name_len + 1, suffix.c_str(), suffix_len); + memcpy(buffer + name_len + 1, suffix_ptr, suffix_len); buffer[total_len] = '\0'; return std::string(buffer, total_len); } diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index f64c14aa85..adce18408e 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -311,9 +311,10 @@ std::string __attribute__((format(printf, 1, 2))) str_sprintf(const char *fmt, . /// Maximum name length supported is 120 characters for friendly names. /// @param name The base name string /// @param sep The separator character (e.g., '-', ' ', or '.') -/// @param suffix The suffix to append (e.g., MAC address suffix or ".local") +/// @param suffix_ptr Pointer to the suffix characters +/// @param suffix_len Length of the suffix /// @return The concatenated string: name + sep + suffix -std::string make_name_with_suffix(const std::string &name, char sep, const std::string &suffix); +std::string make_name_with_suffix(const std::string &name, char sep, const char *suffix_ptr, size_t suffix_len); ///@} From 21c2c6e7825190d93eb3ea3aba6d529fcea40090 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Oct 2025 15:33:19 -1000 Subject: [PATCH 3/6] Update esphome/config_validation.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/config_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/config_validation.py b/esphome/config_validation.py index 2746f574ba..ebfedf2017 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -1200,7 +1200,7 @@ def hostname(value): Maximum length is 63 characters per RFC 1035. Note: If this limit is changed, update MAX_NAME_WITH_SUFFIX_SIZE in - esphome/core/application.h to accommodate the new maximum length. + esphome/core/helpers.cpp to accommodate the new maximum length. """ value = string(value) if re.match(r"^[a-z0-9-]{1,63}$", value, re.IGNORECASE) is not None: From 5fe319fcc56217c38e47b206b00784691bba1b79 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Oct 2025 15:33:22 -1000 Subject: [PATCH 4/6] preen --- esphome/core/helpers.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index cabd9ffd16..2d8122699b 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -237,12 +237,6 @@ std::string str_sprintf(const char *fmt, ...) { // Maximum size for name with suffix: 120 (max friendly name) + 1 (separator) + 6 (MAC suffix) + 1 (null term) static constexpr size_t MAX_NAME_WITH_SUFFIX_SIZE = 128; -// MAC address suffix length (last 6 characters of 12-char MAC address string) -static constexpr size_t MAC_ADDRESS_SUFFIX_LEN = 6; -// Full MAC address string length (lowercase hex without separators) -static constexpr size_t MAC_ADDRESS_LEN = 12; -// ".local" suffix length for mDNS hostnames -static constexpr size_t MDNS_LOCAL_SUFFIX_LEN = 5; std::string make_name_with_suffix(const std::string &name, char sep, const char *suffix_ptr, size_t suffix_len) { char buffer[MAX_NAME_WITH_SUFFIX_SIZE]; From e69013317d8c6f64e1d7bb5677e353d68730272c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Oct 2025 15:33:46 -1000 Subject: [PATCH 5/6] Update esphome/core/helpers.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/core/helpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 2d8122699b..fb8b220b2f 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -247,7 +247,7 @@ std::string make_name_with_suffix(const std::string &name, char sep, const char if (total_len >= MAX_NAME_WITH_SUFFIX_SIZE) { // NOTE: This calculation could underflow if suffix_len >= MAX_NAME_WITH_SUFFIX_SIZE - 2, // but this is safe because this helper is only called with small suffixes: - // MAC suffixes (6-12 bytes), ".local" (6 bytes), etc. + // MAC suffixes (6-12 bytes), ".local" (5 bytes), etc. name_len = MAX_NAME_WITH_SUFFIX_SIZE - suffix_len - 2; // -2 for separator and null terminator total_len = name_len + 1 + suffix_len; } From 153f01ef773c31bedf0350bd2440247906fea120 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Oct 2025 15:34:15 -1000 Subject: [PATCH 6/6] preen --- script/determine-jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/determine-jobs.py b/script/determine-jobs.py index 1601496877..a078fd8f9b 100755 --- a/script/determine-jobs.py +++ b/script/determine-jobs.py @@ -244,7 +244,7 @@ def main() -> None: component for component in changed_components if (component_test_dir := tests_dir / component).exists() - and next(component_test_dir.glob("test.*.yaml"), None) is not None + and any(component_test_dir.glob("test.*.yaml")) ] # Build output