]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
json: free array in json_variant_unref_many()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 12 Jul 2023 12:10:47 +0000 (14:10 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 12 Jul 2023 18:05:20 +0000 (20:05 +0200)
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.

src/busctl/busctl.c
src/network/networkd-json.c
src/shared/format-table.c
src/shared/json.c
src/shared/logs-show.c
src/shared/tpm2-util.c

index eab0c72707e0ea1982455cc8524ffe5fcfd9504e..748902093dddafe31017f1568a8d80f1e747fd47 100644 (file)
@@ -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) {
index d9679719938d8ab06326810e51517a7e5c66aecd..c32642205ef1260b18af9da44741dde7184018df 100644 (file)
@@ -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) {
index df79a424500ec37f2dc8ff370c170e6de560fecd..679e835db5b15342304da74c07579bca20595bdc 100644 (file)
@@ -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) {
index 417d17df347bc39f35c9e91c972fe260f26083fe..a6e23d82cd2e6ce32209473418fea5eda5fe8959 100644 (file)
@@ -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(
index f467d844aa43fd01f9ef74410ca511de726afcdc..1c5b212b01e7fb5d641fb8402287dd84136ea99b 100644 (file)
@@ -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(
index 9166b6593ffb0527e8cea640dd55bd7fa72fcce8..2d18a7e8e171c135c7748c76105279452a91d4e5 100644 (file)
@@ -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;
 }