1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-30 06:33:51 +00:00

Merge branch 'integration' into memory_api

This commit is contained in:
J. Nick Koston
2025-10-11 15:34:42 -10:00
10 changed files with 30 additions and 17 deletions

View File

@@ -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"),

View File

@@ -217,7 +217,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();

View File

@@ -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_;
}

View File

@@ -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

View File

@@ -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_;
}

View File

@@ -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:

View File

@@ -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;

View File

@@ -238,24 +238,23 @@ 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;
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
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;
}
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);
}

View File

@@ -314,9 +314,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);
///@}

View File

@@ -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