You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.4 KiB
142 lines
4.4 KiB
2 years ago
|
From fb195ccc27d1643d4152ee874144c36c0104c56d Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||
|
Date: Mon, 9 May 2022 15:10:36 +0200
|
||
|
Subject: [PATCH] shared/json: add helper to ref first, unref second
|
||
|
|
||
|
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.
|
||
|
|
||
|
(cherry picked from commit ce913e0ec4c97651c7c1509b72fb81ee61d80c6a)
|
||
|
Related: #2087652
|
||
|
---
|
||
|
src/shared/json.c | 36 ++++++++++--------------------------
|
||
|
src/shared/json.h | 8 ++++++++
|
||
|
2 files changed, 18 insertions(+), 26 deletions(-)
|
||
|
|
||
|
diff --git a/src/shared/json.c b/src/shared/json.c
|
||
|
index fe05657dad..bb2363fd98 100644
|
||
|
--- a/src/shared/json.c
|
||
|
+++ b/src/shared/json.c
|
||
|
@@ -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;
|
||
|
|
||
|
diff --git a/src/shared/json.h b/src/shared/json.h
|
||
|
index 8760354b66..dd73c1e497 100644
|
||
|
--- a/src/shared/json.h
|
||
|
+++ b/src/shared/json.h
|
||
|
@@ -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);
|