mirror of
https://github.com/esphome/esphome.git
synced 2025-08-03 08:57:47 +00:00
Merge remote-tracking branch 'kahrendt/json-bump-library' into integration
This commit is contained in:
commit
cf9130f906
@ -83,8 +83,7 @@ void HttpRequestUpdate::update_task(void *params) {
|
|||||||
container.reset(); // Release ownership of the container's shared_ptr
|
container.reset(); // Release ownership of the container's shared_ptr
|
||||||
|
|
||||||
valid = json::parse_json(response, [this_update](JsonObject root) -> bool {
|
valid = json::parse_json(response, [this_update](JsonObject root) -> bool {
|
||||||
if (!root["name"].is<const char *>() || !root["version"].is<const char *>() ||
|
if (!root["name"].is<const char *>() || !root["version"].is<const char *>() || !root["builds"].is<JsonArray>()) {
|
||||||
!root["builds"].is<const char *>()) {
|
|
||||||
ESP_LOGE(TAG, "Manifest does not contain required fields");
|
ESP_LOGE(TAG, "Manifest does not contain required fields");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "json_util.h"
|
#include "json_util.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/Allocator.hpp>
|
// ArduinoJson::Allocator is included via ArduinoJson.h in json_util.h
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace json {
|
namespace json {
|
||||||
@ -13,7 +13,12 @@ struct SpiRamAllocator : ArduinoJson::Allocator {
|
|||||||
void *allocate(size_t size) override { return this->allocator_.allocate(size); }
|
void *allocate(size_t size) override { return this->allocator_.allocate(size); }
|
||||||
|
|
||||||
void deallocate(void *pointer) override {
|
void deallocate(void *pointer) override {
|
||||||
// RAMAllocator requires passing the size of the allocated space which don't know, so use free directly
|
// ArduinoJson's Allocator interface doesn't provide the size parameter in deallocate.
|
||||||
|
// RAMAllocator::deallocate() requires the size, which we don't have access to here.
|
||||||
|
// RAMAllocator::deallocate implementation just calls free() regardless of whether
|
||||||
|
// the memory was allocated with heap_caps_malloc or malloc.
|
||||||
|
// This is safe because ESP-IDF's heap implementation internally tracks the memory region
|
||||||
|
// and routes free() to the appropriate heap.
|
||||||
free(pointer); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc)
|
free(pointer); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,18 +31,15 @@ struct SpiRamAllocator : ArduinoJson::Allocator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string build_json(const json_build_t &f) {
|
std::string build_json(const json_build_t &f) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
auto doc_allocator = SpiRamAllocator();
|
auto doc_allocator = SpiRamAllocator();
|
||||||
JsonDocument json_document(&doc_allocator);
|
JsonDocument json_document(&doc_allocator);
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
if (json_document.overflowed()) {
|
if (json_document.overflowed()) {
|
||||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
JsonObject root = json_document.to<JsonObject>();
|
JsonObject root = json_document.to<JsonObject>();
|
||||||
f(root);
|
f(root);
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
if (json_document.overflowed()) {
|
if (json_document.overflowed()) {
|
||||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||||
return "{}";
|
return "{}";
|
||||||
@ -45,18 +47,17 @@ std::string build_json(const json_build_t &f) {
|
|||||||
std::string output;
|
std::string output;
|
||||||
serializeJson(json_document, output);
|
serializeJson(json_document, output);
|
||||||
return output;
|
return output;
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_json(const std::string &data, const json_parse_t &f) {
|
bool parse_json(const std::string &data, const json_parse_t &f) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
auto doc_allocator = SpiRamAllocator();
|
auto doc_allocator = SpiRamAllocator();
|
||||||
JsonDocument json_document(&doc_allocator);
|
JsonDocument json_document(&doc_allocator);
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
if (json_document.overflowed()) {
|
if (json_document.overflowed()) {
|
||||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
DeserializationError err = deserializeJson(json_document, data);
|
DeserializationError err = deserializeJson(json_document, data);
|
||||||
|
|
||||||
JsonObject root = json_document.as<JsonObject>();
|
JsonObject root = json_document.as<JsonObject>();
|
||||||
@ -69,6 +70,7 @@ bool parse_json(const std::string &data, const json_parse_t &f) {
|
|||||||
}
|
}
|
||||||
ESP_LOGE(TAG, "Parse error: %s", err.c_str());
|
ESP_LOGE(TAG, "Parse error: %s", err.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace json
|
} // namespace json
|
||||||
|
@ -31,11 +31,13 @@ void MQTTButtonComponent::dump_config() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MQTTButtonComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
void MQTTButtonComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
config.state_topic = false;
|
config.state_topic = false;
|
||||||
if (!this->button_->get_device_class().empty())
|
if (!this->button_->get_device_class().empty()) {
|
||||||
root[MQTT_DEVICE_CLASS] = this->button_->get_device_class();
|
root[MQTT_DEVICE_CLASS] = this->button_->get_device_class();
|
||||||
}
|
}
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
|
}
|
||||||
|
|
||||||
std::string MQTTButtonComponent::component_type() const { return "button"; }
|
std::string MQTTButtonComponent::component_type() const { return "button"; }
|
||||||
const EntityBase *MQTTButtonComponent::get_entity() const { return this->button_; }
|
const EntityBase *MQTTButtonComponent::get_entity() const { return this->button_; }
|
||||||
|
@ -92,10 +92,10 @@ void MQTTClientComponent::send_device_info_() {
|
|||||||
std::string topic = "esphome/discover/";
|
std::string topic = "esphome/discover/";
|
||||||
topic.append(App.get_name());
|
topic.append(App.get_name());
|
||||||
|
|
||||||
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
this->publish_json(
|
this->publish_json(
|
||||||
topic,
|
topic,
|
||||||
[](JsonObject root) {
|
[](JsonObject root) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
uint8_t index = 0;
|
uint8_t index = 0;
|
||||||
for (auto &ip : network::get_ip_addresses()) {
|
for (auto &ip : network::get_ip_addresses()) {
|
||||||
if (ip.is_set()) {
|
if (ip.is_set()) {
|
||||||
@ -148,6 +148,7 @@ void MQTTClientComponent::send_device_info_() {
|
|||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
2, this->discovery_info_.retain);
|
2, this->discovery_info_.retain);
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
|
|
||||||
void MQTTClientComponent::dump_config() {
|
void MQTTClientComponent::dump_config() {
|
||||||
|
@ -14,7 +14,7 @@ static const char *const TAG = "mqtt.climate";
|
|||||||
using namespace esphome::climate;
|
using namespace esphome::climate;
|
||||||
|
|
||||||
void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
auto traits = this->device_->get_traits();
|
auto traits = this->device_->get_traits();
|
||||||
// current_temperature_topic
|
// current_temperature_topic
|
||||||
if (traits.get_supports_current_temperature()) {
|
if (traits.get_supports_current_temperature()) {
|
||||||
@ -29,7 +29,6 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
|
|||||||
// mode_state_topic
|
// mode_state_topic
|
||||||
root[MQTT_MODE_STATE_TOPIC] = this->get_mode_state_topic();
|
root[MQTT_MODE_STATE_TOPIC] = this->get_mode_state_topic();
|
||||||
// modes
|
// modes
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
JsonArray modes = root[MQTT_MODES].to<JsonArray>();
|
JsonArray modes = root[MQTT_MODES].to<JsonArray>();
|
||||||
// sort array for nice UI in HA
|
// sort array for nice UI in HA
|
||||||
if (traits.supports_mode(CLIMATE_MODE_AUTO))
|
if (traits.supports_mode(CLIMATE_MODE_AUTO))
|
||||||
@ -165,6 +164,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
|
|||||||
|
|
||||||
config.state_topic = false;
|
config.state_topic = false;
|
||||||
config.command_topic = false;
|
config.command_topic = false;
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
void MQTTClimateComponent::setup() {
|
void MQTTClimateComponent::setup() {
|
||||||
auto traits = this->device_->get_traits();
|
auto traits = this->device_->get_traits();
|
||||||
|
@ -70,10 +70,10 @@ bool MQTTComponent::send_discovery_() {
|
|||||||
|
|
||||||
ESP_LOGV(TAG, "'%s': Sending discovery", this->friendly_name().c_str());
|
ESP_LOGV(TAG, "'%s': Sending discovery", this->friendly_name().c_str());
|
||||||
|
|
||||||
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
return global_mqtt_client->publish_json(
|
return global_mqtt_client->publish_json(
|
||||||
this->get_discovery_topic_(discovery_info),
|
this->get_discovery_topic_(discovery_info),
|
||||||
[this](JsonObject root) {
|
[this](JsonObject root) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
SendDiscoveryConfig config;
|
SendDiscoveryConfig config;
|
||||||
config.state_topic = true;
|
config.state_topic = true;
|
||||||
config.command_topic = true;
|
config.command_topic = true;
|
||||||
@ -189,11 +189,11 @@ bool MQTTComponent::send_discovery_() {
|
|||||||
device_info[MQTT_DEVICE_SUGGESTED_AREA] = node_area;
|
device_info[MQTT_DEVICE_SUGGESTED_AREA] = node_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
device_info[MQTT_DEVICE_CONNECTIONS][0][0] = "mac";
|
device_info[MQTT_DEVICE_CONNECTIONS][0][0] = "mac";
|
||||||
device_info[MQTT_DEVICE_CONNECTIONS][0][1] = mac;
|
device_info[MQTT_DEVICE_CONNECTIONS][0][1] = mac;
|
||||||
},
|
},
|
||||||
this->qos_, discovery_info.retain);
|
this->qos_, discovery_info.retain);
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t MQTTComponent::get_qos() const { return this->qos_; }
|
uint8_t MQTTComponent::get_qos() const { return this->qos_; }
|
||||||
|
@ -26,7 +26,7 @@ void MQTTDateComponent::setup() {
|
|||||||
if (root["month"].is<uint8_t>()) {
|
if (root["month"].is<uint8_t>()) {
|
||||||
call.set_month(root["month"]);
|
call.set_month(root["month"]);
|
||||||
}
|
}
|
||||||
if (root["day"].is<uint16_t>()) {
|
if (root["day"].is<uint8_t>()) {
|
||||||
call.set_day(root["day"]);
|
call.set_day(root["day"]);
|
||||||
}
|
}
|
||||||
call.perform();
|
call.perform();
|
||||||
|
@ -29,13 +29,13 @@ void MQTTDateTimeComponent::setup() {
|
|||||||
if (root["day"].is<uint8_t>()) {
|
if (root["day"].is<uint8_t>()) {
|
||||||
call.set_day(root["day"]);
|
call.set_day(root["day"]);
|
||||||
}
|
}
|
||||||
if (root["hour"].is<uint16_t>()) {
|
if (root["hour"].is<uint8_t>()) {
|
||||||
call.set_hour(root["hour"]);
|
call.set_hour(root["hour"]);
|
||||||
}
|
}
|
||||||
if (root["minute"].is<uint16_t>()) {
|
if (root["minute"].is<uint8_t>()) {
|
||||||
call.set_minute(root["minute"]);
|
call.set_minute(root["minute"]);
|
||||||
}
|
}
|
||||||
if (root["second"].is<uint16_t>()) {
|
if (root["second"].is<uint8_t>()) {
|
||||||
call.set_second(root["second"]);
|
call.set_second(root["second"]);
|
||||||
}
|
}
|
||||||
call.perform();
|
call.perform();
|
||||||
|
@ -45,6 +45,7 @@ void MQTTJSONLightComponent::send_discovery(JsonObject root, mqtt::SendDiscovery
|
|||||||
auto traits = this->state_->get_traits();
|
auto traits = this->state_->get_traits();
|
||||||
|
|
||||||
root[MQTT_COLOR_MODE] = true;
|
root[MQTT_COLOR_MODE] = true;
|
||||||
|
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
JsonArray color_modes = root["supported_color_modes"].to<JsonArray>();
|
JsonArray color_modes = root["supported_color_modes"].to<JsonArray>();
|
||||||
if (traits.supports_color_mode(ColorMode::ON_OFF))
|
if (traits.supports_color_mode(ColorMode::ON_OFF))
|
||||||
color_modes.add("onoff");
|
color_modes.add("onoff");
|
||||||
|
@ -38,9 +38,9 @@ std::string MQTTNumberComponent::component_type() const { return "number"; }
|
|||||||
const EntityBase *MQTTNumberComponent::get_entity() const { return this->number_; }
|
const EntityBase *MQTTNumberComponent::get_entity() const { return this->number_; }
|
||||||
|
|
||||||
void MQTTNumberComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
void MQTTNumberComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
const auto &traits = number_->traits;
|
const auto &traits = number_->traits;
|
||||||
// https://www.home-assistant.io/integrations/number.mqtt/
|
// https://www.home-assistant.io/integrations/number.mqtt/
|
||||||
|
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
root[MQTT_MIN] = traits.get_min_value();
|
root[MQTT_MIN] = traits.get_min_value();
|
||||||
root[MQTT_MAX] = traits.get_max_value();
|
root[MQTT_MAX] = traits.get_max_value();
|
||||||
root[MQTT_STEP] = traits.get_step();
|
root[MQTT_STEP] = traits.get_step();
|
||||||
|
@ -33,9 +33,9 @@ std::string MQTTSelectComponent::component_type() const { return "select"; }
|
|||||||
const EntityBase *MQTTSelectComponent::get_entity() const { return this->select_; }
|
const EntityBase *MQTTSelectComponent::get_entity() const { return this->select_; }
|
||||||
|
|
||||||
void MQTTSelectComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
void MQTTSelectComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
|
||||||
const auto &traits = select_->traits;
|
const auto &traits = select_->traits;
|
||||||
// https://www.home-assistant.io/integrations/select.mqtt/
|
// https://www.home-assistant.io/integrations/select.mqtt/
|
||||||
|
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
JsonArray options = root[MQTT_OPTIONS].to<JsonArray>();
|
JsonArray options = root[MQTT_OPTIONS].to<JsonArray>();
|
||||||
for (const auto &option : traits.get_options())
|
for (const auto &option : traits.get_options())
|
||||||
options.add(option);
|
options.add(option);
|
||||||
|
@ -20,13 +20,13 @@ MQTTTimeComponent::MQTTTimeComponent(TimeEntity *time) : time_(time) {}
|
|||||||
void MQTTTimeComponent::setup() {
|
void MQTTTimeComponent::setup() {
|
||||||
this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
|
this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
|
||||||
auto call = this->time_->make_call();
|
auto call = this->time_->make_call();
|
||||||
if (root["hour"].is<uint16_t>()) {
|
if (root["hour"].is<uint8_t>()) {
|
||||||
call.set_hour(root["hour"]);
|
call.set_hour(root["hour"]);
|
||||||
}
|
}
|
||||||
if (root["minute"].is<uint16_t>()) {
|
if (root["minute"].is<uint8_t>()) {
|
||||||
call.set_minute(root["minute"]);
|
call.set_minute(root["minute"]);
|
||||||
}
|
}
|
||||||
if (root["second"].is<uint16_t>()) {
|
if (root["second"].is<uint8_t>()) {
|
||||||
call.set_second(root["second"]);
|
call.set_second(root["second"]);
|
||||||
}
|
}
|
||||||
call.perform();
|
call.perform();
|
||||||
|
@ -1322,6 +1322,7 @@ std::string WebServer::climate_all_json_generator(WebServer *web_server, void *s
|
|||||||
return web_server->climate_json((climate::Climate *) (source), DETAIL_ALL);
|
return web_server->climate_json((climate::Climate *) (source), DETAIL_ALL);
|
||||||
}
|
}
|
||||||
std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_config) {
|
std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_config) {
|
||||||
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
return json::build_json([this, obj, start_config](JsonObject root) {
|
return json::build_json([this, obj, start_config](JsonObject root) {
|
||||||
set_json_id(root, obj, "climate-" + obj->get_object_id(), start_config);
|
set_json_id(root, obj, "climate-" + obj->get_object_id(), start_config);
|
||||||
const auto traits = obj->get_traits();
|
const auto traits = obj->get_traits();
|
||||||
@ -1407,6 +1408,7 @@ std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_conf
|
|||||||
root["state"] = root["target_temperature"];
|
root["state"] = root["target_temperature"];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1682,6 +1684,7 @@ std::string WebServer::update_all_json_generator(WebServer *web_server, void *so
|
|||||||
return web_server->update_json((update::UpdateEntity *) (source), DETAIL_STATE);
|
return web_server->update_json((update::UpdateEntity *) (source), DETAIL_STATE);
|
||||||
}
|
}
|
||||||
std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_config) {
|
std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_config) {
|
||||||
|
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||||
return json::build_json([this, obj, start_config](JsonObject root) {
|
return json::build_json([this, obj, start_config](JsonObject root) {
|
||||||
set_json_id(root, obj, "update-" + obj->get_object_id(), start_config);
|
set_json_id(root, obj, "update-" + obj->get_object_id(), start_config);
|
||||||
root["value"] = obj->update_info.latest_version;
|
root["value"] = obj->update_info.latest_version;
|
||||||
@ -1707,6 +1710,7 @@ std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_c
|
|||||||
this->add_sorting_info_(root, obj);
|
this->add_sorting_info_(root, obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user