1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-24 14:12:24 +01:00

[api] Fix string lifetime issue in Home Assistant service calls with templated values (#9909)

This commit is contained in:
J. Nick Koston
2025-07-27 18:39:25 -10:00
committed by GitHub
parent 05f6d01cbe
commit 1702356fc8
12 changed files with 670 additions and 25 deletions

View File

@@ -760,7 +760,7 @@ message SubscribeHomeassistantServicesRequest {
message HomeassistantServiceMap {
string key = 1;
string value = 2;
string value = 2 [(no_zero_copy) = true];
}
message HomeassistantServiceResponse {

View File

@@ -27,4 +27,5 @@ extend google.protobuf.MessageOptions {
extend google.protobuf.FieldOptions {
optional string field_ifdef = 1042;
optional uint32 fixed_array_size = 50007;
optional bool no_zero_copy = 50008 [default=false];
}

View File

@@ -846,11 +846,11 @@ void NoiseEncryptionSetKeyResponse::calculate_size(uint32_t &total_size) const {
#ifdef USE_API_HOMEASSISTANT_SERVICES
void HomeassistantServiceMap::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->key_ref_);
buffer.encode_string(2, this->value_ref_);
buffer.encode_string(2, this->value);
}
void HomeassistantServiceMap::calculate_size(uint32_t &total_size) const {
ProtoSize::add_string_field(total_size, 1, this->key_ref_.size());
ProtoSize::add_string_field(total_size, 1, this->value_ref_.size());
ProtoSize::add_string_field(total_size, 1, this->value.size());
}
void HomeassistantServiceResponse::encode(ProtoWriteBuffer buffer) const {
buffer.encode_string(1, this->service_ref_);

View File

@@ -1062,8 +1062,7 @@ class HomeassistantServiceMap : public ProtoMessage {
public:
StringRef key_ref_{};
void set_key(const StringRef &ref) { this->key_ref_ = ref; }
StringRef value_ref_{};
void set_value(const StringRef &ref) { this->value_ref_ = ref; }
std::string value{};
void encode(ProtoWriteBuffer buffer) const override;
void calculate_size(uint32_t &total_size) const override;
#ifdef HAS_PROTO_MESSAGE_DUMP

View File

@@ -1045,7 +1045,7 @@ void SubscribeHomeassistantServicesRequest::dump_to(std::string &out) const {
void HomeassistantServiceMap::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "HomeassistantServiceMap");
dump_field(out, "key", this->key_ref_);
dump_field(out, "value", this->value_ref_);
dump_field(out, "value", this->value);
}
void HomeassistantServiceResponse::dump_to(std::string &out) const {
MessageDumpHelper helper(out, "HomeassistantServiceResponse");

View File

@@ -175,7 +175,7 @@ class CustomAPIDevice {
resp.data.emplace_back();
auto &kv = resp.data.back();
kv.set_key(StringRef(it.first));
kv.set_value(StringRef(it.second));
kv.value = it.second;
}
global_api_server->send_homeassistant_service_call(resp);
}
@@ -218,7 +218,7 @@ class CustomAPIDevice {
resp.data.emplace_back();
auto &kv = resp.data.back();
kv.set_key(StringRef(it.first));
kv.set_value(StringRef(it.second));
kv.value = it.second;
}
global_api_server->send_homeassistant_service_call(resp);
}

View File

@@ -70,22 +70,19 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
resp.data.emplace_back();
auto &kv = resp.data.back();
kv.set_key(StringRef(it.key));
std::string value = it.value.value(x...);
kv.set_value(StringRef(value));
kv.value = it.value.value(x...);
}
for (auto &it : this->data_template_) {
resp.data_template.emplace_back();
auto &kv = resp.data_template.back();
kv.set_key(StringRef(it.key));
std::string value = it.value.value(x...);
kv.set_value(StringRef(value));
kv.value = it.value.value(x...);
}
for (auto &it : this->variables_) {
resp.variables.emplace_back();
auto &kv = resp.variables.back();
kv.set_key(StringRef(it.key));
std::string value = it.value.value(x...);
kv.set_value(StringRef(value));
kv.value = it.value.value(x...);
}
this->parent_->send_homeassistant_service_call(resp);
}