From: Daan De Meyer Date: Wed, 12 Jul 2023 12:10:47 +0000 (+0200) Subject: json: free array in json_variant_unref_many() X-Git-Tag: v254-rc2~36^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ee9d31a6085faf1870db5f956f402b15be5a9703;p=thirdparty%2Fsystemd.git json: free array in json_variant_unref_many() This allows using it with CLEANUP_ARRAY(). For the 2 call sites where we don't need to free the array, we do a regular for loop calling json_variant_unref() instead. --- diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index eab0c72707e..748902093dd 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -1679,34 +1679,26 @@ static int json_transform_array_or_struct(sd_bus_message *m, JsonVariant **ret) assert(m); assert(ret); + CLEANUP_ARRAY(elements, n_elements, json_variant_unref_many); + for (;;) { r = sd_bus_message_at_end(m, false); - if (r < 0) { - bus_log_parse_error(r); - goto finish; - } + if (r < 0) + return bus_log_parse_error(r); if (r > 0) break; - if (!GREEDY_REALLOC(elements, n_elements + 1)) { - r = log_oom(); - goto finish; - } + if (!GREEDY_REALLOC(elements, n_elements + 1)) + return log_oom(); r = json_transform_one(m, elements + n_elements); if (r < 0) - goto finish; + return r; n_elements++; } - r = json_variant_new_array(ret, elements, n_elements); - -finish: - json_variant_unref_many(elements, n_elements); - free(elements); - - return r; + return json_variant_new_array(ret, elements, n_elements); } static int json_transform_variant(sd_bus_message *m, const char *contents, JsonVariant **ret) { @@ -1737,15 +1729,15 @@ static int json_transform_dict_array(sd_bus_message *m, JsonVariant **ret) { assert(m); assert(ret); + CLEANUP_ARRAY(elements, n_elements, json_variant_unref_many); + for (;;) { const char *contents; char type; r = sd_bus_message_at_end(m, false); - if (r < 0) { - bus_log_parse_error(r); - goto finish; - } + if (r < 0) + return bus_log_parse_error(r); if (r > 0) break; @@ -1755,43 +1747,31 @@ static int json_transform_dict_array(sd_bus_message *m, JsonVariant **ret) { assert(type == 'e'); - if (!GREEDY_REALLOC(elements, n_elements + 2)) { - r = log_oom(); - goto finish; - } + if (!GREEDY_REALLOC(elements, n_elements + 2)) + return log_oom(); r = sd_bus_message_enter_container(m, type, contents); - if (r < 0) { - bus_log_parse_error(r); - goto finish; - } + if (r < 0) + return bus_log_parse_error(r); r = json_transform_one(m, elements + n_elements); if (r < 0) - goto finish; + return r; n_elements++; r = json_transform_one(m, elements + n_elements); if (r < 0) - goto finish; + return r; n_elements++; r = sd_bus_message_exit_container(m); - if (r < 0) { - bus_log_parse_error(r); - goto finish; - } + if (r < 0) + return bus_log_parse_error(r); } - r = json_variant_new_object(ret, elements, n_elements); - -finish: - json_variant_unref_many(elements, n_elements); - free(elements); - - return r; + return json_variant_new_object(ret, elements, n_elements); } static int json_transform_one(sd_bus_message *m, JsonVariant **ret) { diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index d9679719938..c32642205ef 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -67,13 +67,15 @@ static int address_build_json(Address *address, JsonVariant **ret) { } static int addresses_build_json(Set *addresses, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; Address *address; size_t n = 0; int r; assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (set_isempty(addresses)) { *ret = NULL; return 0; @@ -86,16 +88,11 @@ static int addresses_build_json(Set *addresses, JsonVariant **ret) { SET_FOREACH(address, addresses) { r = address_build_json(address, elements + n); if (r < 0) - goto finalize; + return r; n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Addresses", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Addresses", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int neighbor_build_json(Neighbor *n, JsonVariant **ret) { @@ -124,13 +121,15 @@ static int neighbor_build_json(Neighbor *n, JsonVariant **ret) { } static int neighbors_build_json(Set *neighbors, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; Neighbor *neighbor; size_t n = 0; int r; assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (set_isempty(neighbors)) { *ret = NULL; return 0; @@ -143,20 +142,15 @@ static int neighbors_build_json(Set *neighbors, JsonVariant **ret) { SET_FOREACH(neighbor, neighbors) { r = neighbor_build_json(neighbor, elements + n); if (r < 0) - goto finalize; + return r; n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Neighbors", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Neighbors", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int nexthop_group_build_json(NextHop *nexthop, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; struct nexthop_grp *g; size_t n = 0; int r; @@ -164,6 +158,8 @@ static int nexthop_group_build_json(NextHop *nexthop, JsonVariant **ret) { assert(nexthop); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (hashmap_isempty(nexthop->group)) { *ret = NULL; return 0; @@ -178,17 +174,12 @@ static int nexthop_group_build_json(NextHop *nexthop, JsonVariant **ret) { JSON_BUILD_PAIR_UNSIGNED("ID", g->id), JSON_BUILD_PAIR_UNSIGNED("Weight", g->weight+1))); if (r < 0) - goto failure; + return r; n++; } - r = json_variant_new_array(ret, elements, n); - -failure: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_variant_new_array(ret, elements, n); } static int nexthop_build_json(NextHop *n, JsonVariant **ret) { @@ -234,13 +225,15 @@ static int nexthop_build_json(NextHop *n, JsonVariant **ret) { } static int nexthops_build_json(Set *nexthops, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; NextHop *nexthop; size_t n = 0; int r; assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (set_isempty(nexthops)) { *ret = NULL; return 0; @@ -253,16 +246,11 @@ static int nexthops_build_json(Set *nexthops, JsonVariant **ret) { SET_FOREACH(nexthop, nexthops) { r = nexthop_build_json(nexthop, elements + n); if (r < 0) - goto finalize; + return r; n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NextHops", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NextHops", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int route_build_json(Route *route, JsonVariant **ret) { @@ -332,13 +320,15 @@ static int route_build_json(Route *route, JsonVariant **ret) { } static int routes_build_json(Set *routes, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; Route *route; size_t n = 0; int r; assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (set_isempty(routes)) { *ret = NULL; return 0; @@ -351,16 +341,11 @@ static int routes_build_json(Set *routes, JsonVariant **ret) { SET_FOREACH(route, routes) { r = route_build_json(route, elements + n); if (r < 0) - goto finalize; + return r; n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Routes", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Routes", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int routing_policy_rule_build_json(RoutingPolicyRule *rule, JsonVariant **ret) { @@ -427,13 +412,15 @@ static int routing_policy_rule_build_json(RoutingPolicyRule *rule, JsonVariant * } static int routing_policy_rules_build_json(Set *rules, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; RoutingPolicyRule *rule; size_t n = 0; int r; assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (set_isempty(rules)) { *ret = NULL; return 0; @@ -446,16 +433,11 @@ static int routing_policy_rules_build_json(Set *rules, JsonVariant **ret) { SET_FOREACH(rule, rules) { r = routing_policy_rule_build_json(rule, elements + n); if (r < 0) - goto finalize; + return r; n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("RoutingPolicyRules", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("RoutingPolicyRules", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int network_build_json(Network *network, JsonVariant **ret) { @@ -551,6 +533,8 @@ static int dns_build_json(Link *link, JsonVariant **ret) { assert(link); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (!link->network) { *ret = NULL; return 0; @@ -558,27 +542,23 @@ static int dns_build_json(Link *link, JsonVariant **ret) { if (link->n_dns != UINT_MAX) { for (unsigned i = 0; i < link->n_dns; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = dns_build_json_one(link, link->dns[i], NETWORK_CONFIG_SOURCE_RUNTIME, NULL, elements + n); if (r < 0) - goto finalize; + return r; if (r > 0) n++; } } else { for (unsigned i = 0; i < link->network->n_dns; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = dns_build_json_one(link, link->network->dns[i], NETWORK_CONFIG_SOURCE_STATIC, NULL, elements + n); if (r < 0) - goto finalize; + return r; if (r > 0) n++; } @@ -590,14 +570,12 @@ static int dns_build_json(Link *link, JsonVariant **ret) { r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); if (r < 0) - goto finalize; + return r; n_dns = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns); for (int i = 0; i < n_dns; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = dns_build_json_one(link, &(struct in_addr_full) { .family = AF_INET, .address.in = dns[i], }, @@ -605,7 +583,7 @@ static int dns_build_json(Link *link, JsonVariant **ret) { &s, elements + n); if (r < 0) - goto finalize; + return r; if (r > 0) n++; } @@ -618,14 +596,12 @@ static int dns_build_json(Link *link, JsonVariant **ret) { r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); if (r < 0) - goto finalize; + return r; n_dns = sd_dhcp6_lease_get_dns(link->dhcp6_lease, &dns); for (int i = 0; i < n_dns; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = dns_build_json_one(link, &(struct in_addr_full) { .family = AF_INET6, .address.in6 = dns[i], }, @@ -633,7 +609,7 @@ static int dns_build_json(Link *link, JsonVariant **ret) { &s, elements + n); if (r < 0) - goto finalize; + return r; if (r > 0) n++; } @@ -643,10 +619,8 @@ static int dns_build_json(Link *link, JsonVariant **ret) { NDiscRDNSS *a; SET_FOREACH(a, link->ndisc_rdnss) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = dns_build_json_one(link, &(struct in_addr_full) { .family = AF_INET6, .address.in6 = a->address, }, @@ -654,7 +628,7 @@ static int dns_build_json(Link *link, JsonVariant **ret) { &(union in_addr_union) { .in6 = a->router }, elements + n); if (r < 0) - goto finalize; + return r; if (r > 0) n++; } @@ -663,16 +637,10 @@ static int dns_build_json(Link *link, JsonVariant **ret) { if (n == 0) { *ret = NULL; - r = 0; - goto finalize; + return 0; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNS", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNS", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int server_build_json_one_addr(int family, const union in_addr_union *a, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) { @@ -719,20 +687,20 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { assert(link); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (!link->network) { *ret = NULL; return 0; } STRV_FOREACH(p, link->ntp ?: link->network->ntp) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = server_build_json_one_string(*p, NETWORK_CONFIG_SOURCE_RUNTIME, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -745,14 +713,12 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); if (r < 0) - goto finalize; + return r; n_ntp = sd_dhcp_lease_get_ntp(link->dhcp_lease, &ntp); for (int i = 0; i < n_ntp; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = server_build_json_one_addr(AF_INET, &(union in_addr_union) { .in = ntp[i], }, @@ -760,7 +726,7 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { &s, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -774,14 +740,12 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); if (r < 0) - goto finalize; + return r; n_ntp = sd_dhcp6_lease_get_ntp_addrs(link->dhcp6_lease, &ntp_addr); for (int i = 0; i < n_ntp; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = server_build_json_one_addr(AF_INET6, &(union in_addr_union) { .in6 = ntp_addr[i], }, @@ -789,17 +753,15 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { &s, elements + n); if (r < 0) - goto finalize; + return r; n++; } n_ntp = sd_dhcp6_lease_get_ntp_fqdn(link->dhcp6_lease, &ntp_fqdn); for (int i = 0; i < n_ntp; i++) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = server_build_json_one_fqdn(AF_INET6, ntp_fqdn[i], @@ -807,7 +769,7 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { &s, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -819,17 +781,12 @@ static int ntp_build_json(Link *link, JsonVariant **ret) { return 0; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NTP", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NTP", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int sip_build_json(Link *link, JsonVariant **ret) { const struct in_addr *sip; - JsonVariant **elements; + JsonVariant **elements = NULL; union in_addr_union s; size_t n = 0; int n_sip, r; @@ -837,6 +794,8 @@ static int sip_build_json(Link *link, JsonVariant **ret) { assert(link); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (!link->network || !link->network->dhcp_use_sip || !link->dhcp_lease) { *ret = NULL; return 0; @@ -863,17 +822,12 @@ static int sip_build_json(Link *link, JsonVariant **ret) { &s, elements + n); if (r < 0) - goto finalize; + return r; if (r > 0) n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("SIP", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("SIP", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int captive_portal_build_json(Link *link, JsonVariant **ret) { @@ -919,6 +873,8 @@ static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { assert(link); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (!link->network) { *ret = NULL; return 0; @@ -929,16 +885,14 @@ static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { use_domains = is_route ? DHCP_USE_DOMAINS_ROUTE : DHCP_USE_DOMAINS_YES; ORDERED_SET_FOREACH(domain, link_domains ?: network_domains) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = domain_build_json(AF_UNSPEC, domain, link_domains ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC, NULL, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -948,31 +902,27 @@ static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { link->network->dhcp_use_domains == use_domains) { r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); if (r < 0) - goto finalize; + return r; if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domain) >= 0) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = domain_build_json(AF_INET, domain, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n); if (r < 0) - goto finalize; + return r; n++; } if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0) { STRV_FOREACH(p, domains) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = domain_build_json(AF_INET, *p, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -983,18 +933,16 @@ static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { link->network->dhcp6_use_domains == use_domains) { r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); if (r < 0) - goto finalize; + return r; if (sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains) >= 0) { STRV_FOREACH(p, domains) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = domain_build_json(AF_INET6, *p, NETWORK_CONFIG_SOURCE_DHCP6, &s, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -1005,16 +953,14 @@ static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { NDiscDNSSL *a; SET_FOREACH(a, link->ndisc_dnssl) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = domain_build_json(AF_INET6, NDISC_DNSSL_DOMAIN(a), NETWORK_CONFIG_SOURCE_NDISC, &(union in_addr_union) { .in6 = a->router }, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -1026,13 +972,8 @@ static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { return 0; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(is_route ? "RouteDomains" : "SearchDomains", - JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(is_route ? "RouteDomains" : "SearchDomains", + JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int nta_build_json(const char *nta, NetworkConfigSource s, JsonVariant **ret) { @@ -1053,22 +994,22 @@ static int ntas_build_json(Link *link, JsonVariant **ret) { assert(link); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (!link->network) { *ret = NULL; return 0; } SET_FOREACH(nta, link->dnssec_negative_trust_anchors ?: link->network->dnssec_negative_trust_anchors) { - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = nta_build_json(nta, link->dnssec_negative_trust_anchors ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC, elements + n); if (r < 0) - goto finalize; + return r; n++; } @@ -1078,13 +1019,8 @@ static int ntas_build_json(Link *link, JsonVariant **ret) { return 0; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSECNegativeTrustAnchors", - JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSECNegativeTrustAnchors", + JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int dns_misc_build_json(Link *link, JsonVariant **ret) { @@ -1098,6 +1034,8 @@ static int dns_misc_build_json(Link *link, JsonVariant **ret) { assert(link); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + if (!link->network) { *ret = NULL; return 0; @@ -1107,16 +1045,14 @@ static int dns_misc_build_json(Link *link, JsonVariant **ret) { if (resolve_support >= 0) { source = link->llmnr >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = json_build(elements + n, JSON_BUILD_OBJECT( JSON_BUILD_PAIR_STRING("LLMNR", resolve_support_to_string(resolve_support)), JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); if (r < 0) - goto finalize; + return r; n++; } @@ -1125,16 +1061,14 @@ static int dns_misc_build_json(Link *link, JsonVariant **ret) { if (resolve_support >= 0) { source = link->mdns >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = json_build(elements + n, JSON_BUILD_OBJECT( JSON_BUILD_PAIR_STRING("MDNS", resolve_support_to_string(resolve_support)), JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); if (r < 0) - goto finalize; + return r; n++; } @@ -1143,16 +1077,14 @@ static int dns_misc_build_json(Link *link, JsonVariant **ret) { if (t >= 0) { source = link->dns_default_route >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = json_build(elements + n, JSON_BUILD_OBJECT( JSON_BUILD_PAIR_BOOLEAN("DNSDefaultRoute", t), JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); if (r < 0) - goto finalize; + return r; n++; } @@ -1161,27 +1093,20 @@ static int dns_misc_build_json(Link *link, JsonVariant **ret) { if (mode >= 0) { source = link->dns_over_tls_mode >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; - if (!GREEDY_REALLOC(elements, n + 1)) { - r = -ENOMEM; - goto finalize; - } + if (!GREEDY_REALLOC(elements, n + 1)) + return -ENOMEM; r = json_build(elements + n, JSON_BUILD_OBJECT( JSON_BUILD_PAIR_STRING("DNSOverTLS", dns_over_tls_mode_to_string(mode)), JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); if (r < 0) - goto finalize; + return r; n++; } - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSettings", - JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSettings", + JSON_BUILD_VARIANT_ARRAY(elements, n)))); } static int dhcp_server_offered_leases_build_json(Link *link, JsonVariant **ret) { @@ -1527,7 +1452,7 @@ static int link_json_compare(JsonVariant * const *a, JsonVariant * const *b) { } static int links_build_json(Manager *manager, JsonVariant **ret) { - JsonVariant **elements; + JsonVariant **elements = NULL; Link *link; size_t n = 0; int r; @@ -1535,6 +1460,8 @@ static int links_build_json(Manager *manager, JsonVariant **ret) { assert(manager); assert(ret); + CLEANUP_ARRAY(elements, n, json_variant_unref_many); + elements = new(JsonVariant*, hashmap_size(manager->links_by_index)); if (!elements) return -ENOMEM; @@ -1542,18 +1469,13 @@ static int links_build_json(Manager *manager, JsonVariant **ret) { HASHMAP_FOREACH(link, manager->links_by_index) { r = link_build_json(link, elements + n); if (r < 0) - goto finalize; + return r; n++; } typesafe_qsort(elements, n, link_json_compare); - r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Interfaces", JSON_BUILD_VARIANT_ARRAY(elements, n)))); - -finalize: - json_variant_unref_many(elements, n); - free(elements); - return r; + return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Interfaces", JSON_BUILD_VARIANT_ARRAY(elements, n)))); } int manager_build_json(Manager *manager, JsonVariant **ret) { diff --git a/src/shared/format-table.c b/src/shared/format-table.c index df79a424500..679e835db5b 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -2828,10 +2828,8 @@ static int table_to_json_regular(Table *t, JsonVariant **ret) { /* If sorting is requested, let's calculate an index table we use to lookup the actual index to display with. */ sorted = new(size_t, n_rows); - if (!sorted) { - r = -ENOMEM; - goto finish; - } + if (!sorted) + return -ENOMEM; for (size_t i = 0; i < n_rows; i++) sorted[i] = i * t->n_columns; @@ -2846,10 +2844,10 @@ static int table_to_json_regular(Table *t, JsonVariant **ret) { assert(display_columns > 0); elements = new0(JsonVariant*, display_columns * 2); - if (!elements) { - r = -ENOMEM; - goto finish; - } + if (!elements) + return -ENOMEM; + + CLEANUP_ARRAY(elements, (size_t) { display_columns * 2 }, json_variant_unref_many); for (size_t j = 0; j < display_columns; j++) { _cleanup_free_ char *mangled = NULL; @@ -2863,21 +2861,21 @@ static int table_to_json_regular(Table *t, JsonVariant **ret) { if (!n) { r = table_make_json_field_name(t, ASSERT_PTR(t->data[c]), &mangled); if (r < 0) - goto finish; + return r; n = mangled; } r = json_variant_new_string(elements + j*2, n); if (r < 0) - goto finish; + return r; } rows = new0(JsonVariant*, n_rows-1); - if (!rows) { - r = -ENOMEM; - goto finish; - } + if (!rows) + return -ENOMEM; + + CLEANUP_ARRAY(rows, (size_t) { n_rows - 1 }, json_variant_unref_many); for (size_t i = 1; i < n_rows; i++) { TableData **row; @@ -2898,28 +2896,15 @@ static int table_to_json_regular(Table *t, JsonVariant **ret) { r = table_data_to_json(d, elements + k); if (r < 0) - goto finish; + return r; } r = json_variant_new_object(rows + i - 1, elements, display_columns * 2); if (r < 0) - goto finish; - } - - r = json_variant_new_array(ret, rows, n_rows - 1); - -finish: - if (rows) { - json_variant_unref_many(rows, n_rows-1); - free(rows); - } - - if (elements) { - json_variant_unref_many(elements, display_columns*2); - free(elements); + return r; } - return r; + return json_variant_new_array(ret, rows, n_rows - 1); } static int table_to_json_vertical(Table *t, JsonVariant **ret) { @@ -2937,10 +2922,10 @@ static int table_to_json_vertical(Table *t, JsonVariant **ret) { assert(t->n_cells % t->n_columns == 0); elements = new0(JsonVariant *, t->n_cells); - if (!elements) { - r = -ENOMEM; - goto finish; - } + if (!elements) + return -ENOMEM; + + CLEANUP_ARRAY(elements, n_elements, json_variant_unref_many); for (size_t i = t->n_columns; i < t->n_cells; i++) { @@ -2952,7 +2937,7 @@ static int table_to_json_vertical(Table *t, JsonVariant **ret) { if (!n) { r = table_make_json_field_name(t, ASSERT_PTR(t->data[i]), &mangled); if (r < 0) - goto finish; + return r; n = mangled; } @@ -2961,20 +2946,12 @@ static int table_to_json_vertical(Table *t, JsonVariant **ret) { } else r = table_data_to_json(t->data[i], elements + n_elements); if (r < 0) - goto finish; + return r; n_elements++; } - r = json_variant_new_object(ret, elements, n_elements); - -finish: - if (elements) { - json_variant_unref_many(elements, n_elements); - free(elements); - } - - return r; + return json_variant_new_object(ret, elements, n_elements); } int table_to_json(Table *t, JsonVariant **ret) { diff --git a/src/shared/json.c b/src/shared/json.c index 417d17df347..a6e23d82cd2 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -881,6 +881,8 @@ void json_variant_unref_many(JsonVariant **array, size_t n) { for (size_t i = 0; i < n; i++) json_variant_unref(array[i]); + + free(array); } const char *json_variant_string(JsonVariant *v) { @@ -2879,8 +2881,7 @@ typedef struct JsonStack { static void json_stack_release(JsonStack *s) { assert(s); - json_variant_unref_many(s->elements, s->n_elements); - s->elements = mfree(s->elements); + CLEANUP_ARRAY(s->elements, s->n_elements, json_variant_unref_many); } static int json_parse_internal( diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index f467d844aa4..1c5b212b01e 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -942,6 +942,22 @@ struct json_data { JsonVariant* values[]; }; +static struct json_data* json_data_free(struct json_data *d) { + if (!d) + return NULL; + + json_variant_unref(d->name); + + FOREACH_ARRAY(v, d->values, d->n_values) + json_variant_unref(*v); + + return mfree(d); +} + +DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(json_data_hash_ops_free, + char, string_hash_func, string_compare_func, + struct json_data, json_data_free); + static int update_json_data( Hashmap *h, OutputFlags flags, @@ -950,7 +966,7 @@ static int update_json_data( size_t size) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; - struct json_data *d; + struct json_data *d = NULL; int r; assert(name); @@ -1049,12 +1065,12 @@ static int output_json( char usecbuf[CONST_MAX(DECIMAL_STR_MAX(usec_t), DECIMAL_STR_MAX(uint64_t))]; _cleanup_(json_variant_unrefp) JsonVariant *object = NULL; + _cleanup_hashmap_free_ Hashmap *h = NULL; sd_id128_t journal_boot_id, seqnum_id; _cleanup_free_ char *cursor = NULL; usec_t realtime, monotonic; JsonVariant **array = NULL; struct json_data *d; - Hashmap *h = NULL; uint64_t seqnum; size_t n = 0; int r; @@ -1083,36 +1099,36 @@ static int output_json( if (r < 0) return log_error_errno(r, "Failed to get seqnum: %m"); - h = hashmap_new(&string_hash_ops); + h = hashmap_new(&json_data_hash_ops_free); if (!h) return log_oom(); r = update_json_data(h, flags, "__CURSOR", cursor, SIZE_MAX); if (r < 0) - goto finish; + return r; xsprintf(usecbuf, USEC_FMT, realtime); r = update_json_data(h, flags, "__REALTIME_TIMESTAMP", usecbuf, SIZE_MAX); if (r < 0) - goto finish; + return r; xsprintf(usecbuf, USEC_FMT, monotonic); r = update_json_data(h, flags, "__MONOTONIC_TIMESTAMP", usecbuf, SIZE_MAX); if (r < 0) - goto finish; + return r; r = update_json_data(h, flags, "_BOOT_ID", SD_ID128_TO_STRING(journal_boot_id), SIZE_MAX); if (r < 0) - goto finish; + return r; xsprintf(usecbuf, USEC_FMT, seqnum); r = update_json_data(h, flags, "__SEQNUM", usecbuf, SIZE_MAX); if (r < 0) - goto finish; + return r; r = update_json_data(h, flags, "__SEQNUM_ID", SD_ID128_TO_STRING(seqnum_id), SIZE_MAX); if (r < 0) - goto finish; + return r; for (;;) { const void *data; @@ -1121,26 +1137,23 @@ static int output_json( r = sd_journal_enumerate_data(j, &data, &size); if (IN_SET(r, -EBADMSG, -EADDRNOTAVAIL)) { log_debug_errno(r, "Skipping message we can't read: %m"); - r = 0; - goto finish; - } - if (r < 0) { - log_error_errno(r, "Failed to read journal: %m"); - goto finish; + return 0; } + if (r < 0) + return log_error_errno(r, "Failed to read journal: %m"); if (r == 0) break; r = update_json_data_split(h, flags, output_fields, data, size); if (r < 0) - goto finish; + return r; } array = new(JsonVariant*, hashmap_size(h)*2); - if (!array) { - r = log_oom(); - goto finish; - } + if (!array) + return log_oom(); + + CLEANUP_ARRAY(array, n, json_variant_unref_many); HASHMAP_FOREACH(d, h) { assert(d->n_values > 0); @@ -1153,41 +1166,22 @@ static int output_json( _cleanup_(json_variant_unrefp) JsonVariant *q = NULL; r = json_variant_new_array(&q, d->values, d->n_values); - if (r < 0) { - log_error_errno(r, "Failed to create JSON array: %m"); - goto finish; - } + if (r < 0) + return log_error_errno(r, "Failed to create JSON array: %m"); array[n++] = TAKE_PTR(q); } } r = json_variant_new_object(&object, array, n); - if (r < 0) { - log_error_errno(r, "Failed to allocate JSON object: %m"); - goto finish; - } - - json_variant_dump(object, - output_mode_to_json_format_flags(mode) | - (FLAGS_SET(flags, OUTPUT_COLOR) ? JSON_FORMAT_COLOR : 0), - f, NULL); - - r = 0; - -finish: - while ((d = hashmap_steal_first(h))) { - json_variant_unref(d->name); - json_variant_unref_many(d->values, d->n_values); - free(d); - } - - hashmap_free(h); + if (r < 0) + return log_error_errno(r, "Failed to allocate JSON object: %m"); - json_variant_unref_many(array, n); - free(array); - return r; + return json_variant_dump(object, + output_mode_to_json_format_flags(mode) | + (FLAGS_SET(flags, OUTPUT_COLOR) ? JSON_FORMAT_COLOR : 0), + f, NULL); } static int output_cat_field( diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 9166b6593ff..2d18a7e8e17 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -3862,7 +3862,9 @@ int tpm2_make_pcr_json_array(uint32_t pcr_mask, JsonVariant **ret) { r = 0; finish: - json_variant_unref_many(pcr_array, n_pcrs); + FOREACH_ARRAY(v, pcr_array, n_pcrs) + json_variant_unref(*v); + return r; }