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.
141 lines
4.4 KiB
141 lines
4.4 KiB
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);
|
|
|