]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/json: add helper to ref first, unref second
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 9 May 2022 13:10:36 +0000 (15:10 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 10 May 2022 15:08:34 +0000 (17:08 +0200)
This normally wouldn't happen, but if some of those places were called
with lhs and rhs being the same object, we could unref the last ref first,
and then try to take the ref again. It's easier to be safe, and with the
helper we save some lines too.

src/shared/json.c
src/shared/json.h

index 2e52443dde2b6b68006948711c849c51320963ae..b7978c35561036d39e6048a1995f1c7e4165eceb 100644 (file)
@@ -1847,9 +1847,7 @@ int json_variant_filter(JsonVariant **v, char **to_remove) {
                 return r;
 
         json_variant_propagate_sensitive(*v, w);
-
-        json_variant_unref(*v);
-        *v = TAKE_PTR(w);
+        JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
 
         return (int) n;
 }
@@ -1918,9 +1916,7 @@ int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *valu
                 return r;
 
         json_variant_propagate_sensitive(*v, w);
-
-        json_variant_unref(*v);
-        *v = TAKE_PTR(w);
+        JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
 
         return 1;
 }
@@ -2001,8 +1997,7 @@ int json_variant_merge(JsonVariant **v, JsonVariant *m) {
                 return 0; /* nothing to do */
 
         if (v_blank) {
-                json_variant_unref(*v);
-                *v = json_variant_ref(m);
+                JSON_VARIANT_REPLACE(*v, json_variant_ref(m));
                 return 1;
         }
 
@@ -2039,9 +2034,7 @@ int json_variant_merge(JsonVariant **v, JsonVariant *m) {
 
         json_variant_propagate_sensitive(*v, w);
         json_variant_propagate_sensitive(m, w);
-
-        json_variant_unref(*v);
-        *v = TAKE_PTR(w);
+        JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
 
         return 1;
 }
@@ -2081,9 +2074,7 @@ int json_variant_append_array(JsonVariant **v, JsonVariant *element) {
                 return r;
 
         json_variant_propagate_sensitive(*v, nv);
-
-        json_variant_unref(*v);
-        *v = TAKE_PTR(nv);
+        JSON_VARIANT_REPLACE(*v, TAKE_PTR(nv));
 
         return 0;
 }
@@ -2297,8 +2288,7 @@ static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned
         w->line = line;
         w->column = column;
 
-        json_variant_unref(*v);
-        *v = w;
+        JSON_VARIANT_REPLACE(*v, w);
 
         return 1;
 }
@@ -4499,14 +4489,10 @@ int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags
 }
 
 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
-        JsonVariant **p = userdata;
-
+        JsonVariant **p = ASSERT_PTR(userdata);
         assert(variant);
-        assert(p);
-
-        json_variant_unref(*p);
-        *p = json_variant_ref(variant);
 
+        JSON_VARIANT_REPLACE(*p, json_variant_ref(variant));
         return 0;
 }
 
@@ -4628,8 +4614,7 @@ int json_variant_sort(JsonVariant **v) {
         if (!n->sorted) /* Check if this worked. This will fail if there are multiple identical keys used. */
                 return -ENOTUNIQ;
 
-        json_variant_unref(*v);
-        *v = n;
+        JSON_VARIANT_REPLACE(*v, n);
 
         return 1;
 }
@@ -4684,8 +4669,7 @@ int json_variant_normalize(JsonVariant **v) {
                 goto finish;
         }
 
-        json_variant_unref(*v);
-        *v = n;
+        JSON_VARIANT_REPLACE(*v, n);
 
         r = 1;
 
index 91d02a911e19588199abf0c7bf477e9fa40c308d..98d184c3097905896e0e9a215f55b9a88941dc76 100644 (file)
@@ -82,6 +82,14 @@ JsonVariant *json_variant_ref(JsonVariant *v);
 JsonVariant *json_variant_unref(JsonVariant *v);
 void json_variant_unref_many(JsonVariant **array, size_t n);
 
+#define JSON_VARIANT_REPLACE(v, q)        \
+        do {                              \
+                typeof(v)* _v = &(v);     \
+                typeof(q) _q = (q);       \
+                json_variant_unref(*_v);  \
+                *_v = _q;                 \
+        } while(0)
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonVariant *, json_variant_unref);
 
 const char *json_variant_string(JsonVariant *v);