From ed207e526117e39a3f3219b6c1d45c936ebce3e0 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 7 Aug 2024 09:45:44 +0200 Subject: [PATCH 01/11] json-util: Add JSON_BUILD_STRING_ORDERED_SET() --- src/libsystemd/sd-json/json-util.h | 3 +++ src/libsystemd/sd-json/sd-json.c | 37 ++++++++++++++++++++++++++++++ src/test/test-json.c | 14 +++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index fdfd5522db0..b6832bd59a2 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -138,6 +138,7 @@ enum { _JSON_BUILD_IOVEC_HEX, _JSON_BUILD_HW_ADDR, _JSON_BUILD_STRING_SET, + _JSON_BUILD_STRING_ORDERED_SET, _JSON_BUILD_STRING_UNDERSCORIFY, _JSON_BUILD_DUAL_TIMESTAMP, @@ -166,6 +167,7 @@ enum { #define JSON_BUILD_ETHER_ADDR(v) SD_JSON_BUILD_BYTE_ARRAY(((const struct ether_addr*) { v })->ether_addr_octet, sizeof(struct ether_addr)) #define JSON_BUILD_HW_ADDR(v) _JSON_BUILD_HW_ADDR, (const struct hw_addr_data*) { v } #define JSON_BUILD_STRING_SET(s) _JSON_BUILD_STRING_SET, (Set *) { s } +#define JSON_BUILD_STRING_ORDERED_SET(s) _JSON_BUILD_STRING_ORDERED_SET, (OrderedSet *) { s } #define JSON_BUILD_STRING_UNDERSCORIFY(s) _JSON_BUILD_STRING_UNDERSCORIFY, (const char *) { s } #define JSON_BUILD_DUAL_TIMESTAMP(t) _JSON_BUILD_DUAL_TIMESTAMP, (dual_timestamp*) { t } @@ -188,3 +190,4 @@ enum { #define JSON_BUILD_PAIR_ETHER_ADDR(name, v) SD_JSON_BUILD_PAIR(name, JSON_BUILD_ETHER_ADDR(v)) #define JSON_BUILD_PAIR_HW_ADDR(name, v) SD_JSON_BUILD_PAIR(name, JSON_BUILD_HW_ADDR(v)) #define JSON_BUILD_PAIR_STRING_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_SET(s)) +#define JSON_BUILD_PAIR_STRING_ORDERED_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_ORDERED_SET(s)) diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 589bbe3a46e..6391da65737 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -23,6 +23,7 @@ #include "iovec-util.h" #include "json-internal.h" #include "json-util.h" +#include "ordered-set.h" #include "macro.h" #include "math-util.h" #include "memory-util.h" @@ -4089,6 +4090,42 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } + case _JSON_BUILD_STRING_ORDERED_SET: { + OrderedSet *set; + + if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) { + r = -EINVAL; + goto finish; + } + + set = va_arg(ap, OrderedSet*); + + if (current->n_suppress == 0) { + _cleanup_free_ char **sv = NULL; + + sv = ordered_set_get_strv(set); + if (!sv) { + r = -ENOMEM; + goto finish; + } + + r = sd_json_variant_new_array_strv(&add, sv); + if (r < 0) + goto finish; + } + + n_subtract = 1; + + if (current->expect == EXPECT_TOPLEVEL) + current->expect = EXPECT_END; + else if (current->expect == EXPECT_OBJECT_VALUE) + current->expect = EXPECT_OBJECT_KEY; + else + assert(current->expect == EXPECT_ARRAY_ELEMENT); + + break; + } + case _JSON_BUILD_DUAL_TIMESTAMP: { dual_timestamp *ts; diff --git a/src/test/test-json.c b/src/test/test-json.c index aea4bbaf3ef..f9dc9e74c7b 100644 --- a/src/test/test-json.c +++ b/src/test/test-json.c @@ -12,6 +12,7 @@ #include "json-internal.h" #include "json-util.h" #include "math-util.h" +#include "ordered-set.h" #include "string-table.h" #include "string-util.h" #include "strv.h" @@ -414,6 +415,19 @@ TEST(build) { assert_se(sd_json_build(&ssv2, SD_JSON_BUILD_LITERAL("{\"zzz\":[\"kawumm\",\"pief\",\"xxxx\"]}")) >= 0); assert_se(sd_json_variant_equal(ssv, ssv2)); + + _cleanup_ordered_set_free_ OrderedSet *oss = NULL; + assert_se(ordered_set_ensure_put(&oss, &string_hash_ops_free, ASSERT_PTR(strdup("pief"))) >= 0); + assert_se(ordered_set_ensure_put(&oss, &string_hash_ops_free, ASSERT_PTR(strdup("xxxx"))) >= 0); + assert_se(ordered_set_ensure_put(&oss, &string_hash_ops_free, ASSERT_PTR(strdup("kawumm"))) >= 0); + + _cleanup_(sd_json_variant_unrefp) sd_json_variant *ossv = NULL; + assert_se(sd_json_build(&ossv, SD_JSON_BUILD_OBJECT(SD_JSON_BUILD_PAIR("zzz", JSON_BUILD_STRING_ORDERED_SET(oss)))) >= 0); + + _cleanup_(sd_json_variant_unrefp) sd_json_variant *ossv2 = NULL; + assert_se(sd_json_build(&ossv2, SD_JSON_BUILD_LITERAL("{\"zzz\":[\"pief\",\"xxxx\",\"kawumm\"]}")) >= 0); + + assert_se(sd_json_variant_equal(ossv, ossv2)); } TEST(json_buildo) { From 0e88e150c53859a77a283e040aa6f3a4dd277a55 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 8 Aug 2024 13:51:30 +0200 Subject: [PATCH 02/11] json-util: Add JSON_BUILD_RATELIMIT() --- src/libsystemd/sd-json/json-util.h | 5 +++ src/libsystemd/sd-json/sd-json.c | 64 ++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index b6832bd59a2..242668eccee 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -141,6 +141,7 @@ enum { _JSON_BUILD_STRING_ORDERED_SET, _JSON_BUILD_STRING_UNDERSCORIFY, _JSON_BUILD_DUAL_TIMESTAMP, + _JSON_BUILD_RATELIMIT, _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, _JSON_BUILD_PAIR_FINITE_USEC, @@ -153,6 +154,7 @@ enum { _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL, _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, + _JSON_BUILD_PAIR_RATELIMIT_ENABLED, _SD_JSON_BUILD_REALLYMAX, }; @@ -170,6 +172,7 @@ enum { #define JSON_BUILD_STRING_ORDERED_SET(s) _JSON_BUILD_STRING_ORDERED_SET, (OrderedSet *) { s } #define JSON_BUILD_STRING_UNDERSCORIFY(s) _JSON_BUILD_STRING_UNDERSCORIFY, (const char *) { s } #define JSON_BUILD_DUAL_TIMESTAMP(t) _JSON_BUILD_DUAL_TIMESTAMP, (dual_timestamp*) { t } +#define JSON_BUILD_RATELIMIT(rl) _JSON_BUILD_RATELIMIT, (const RateLimit*) { rl } #define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u } #define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u } @@ -181,6 +184,7 @@ enum { #define JSON_BUILD_PAIR_IN_ADDR_NON_NULL(name, v, f) _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, (const char*) { name }, (const union in_addr_union*) { v }, (int) { f } #define JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL, (const char*) { name }, (const struct ether_addr*) { v } #define JSON_BUILD_PAIR_HW_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, (const char*) { name }, (const struct hw_addr_data*) { v } +#define JSON_BUILD_PAIR_RATELIMIT_ENABLED(name, rl) _JSON_BUILD_PAIR_RATELIMIT_ENABLED, (const char*) { name }, (const RateLimit*) { rl } #define JSON_BUILD_PAIR_IOVEC_BASE64(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_BASE64(iov)) #define JSON_BUILD_PAIR_IOVEC_HEX(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_HEX(iov)) @@ -191,3 +195,4 @@ enum { #define JSON_BUILD_PAIR_HW_ADDR(name, v) SD_JSON_BUILD_PAIR(name, JSON_BUILD_HW_ADDR(v)) #define JSON_BUILD_PAIR_STRING_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_SET(s)) #define JSON_BUILD_PAIR_STRING_ORDERED_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_ORDERED_SET(s)) +#define JSON_BUILD_PAIR_RATELIMIT(name, rl) SD_JSON_BUILD_PAIR(name, JSON_BUILD_RATELIMIT(rl)) diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 6391da65737..a4d9c80f069 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4160,6 +4160,40 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } + case _JSON_BUILD_RATELIMIT: { + const RateLimit *rl; + + if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) { + r = -EINVAL; + goto finish; + } + + rl = va_arg(ap, const RateLimit*); + + if (current->n_suppress == 0) { + if (ratelimit_configured(rl)) { + r = sd_json_buildo( + &add, + SD_JSON_BUILD_PAIR("intervalUSec", SD_JSON_BUILD_UNSIGNED(rl->interval)), + SD_JSON_BUILD_PAIR("burst", SD_JSON_BUILD_UNSIGNED(rl->burst))); + if (r < 0) + goto finish; + } else + add = JSON_VARIANT_MAGIC_NULL; + } + + n_subtract = 1; + + if (current->expect == EXPECT_TOPLEVEL) + current->expect = EXPECT_END; + else if (current->expect == EXPECT_OBJECT_VALUE) + current->expect = EXPECT_OBJECT_KEY; + else + assert(current->expect == EXPECT_ARRAY_ELEMENT); + + break; + } + case _SD_JSON_BUILD_CALLBACK: { sd_json_build_callback_t cb; void *userdata; @@ -4574,6 +4608,36 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { current->expect = EXPECT_OBJECT_KEY; break; } + + case _JSON_BUILD_PAIR_RATELIMIT_ENABLED: { + const RateLimit *rl; + const char *n; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char*); + rl = va_arg(ap, const RateLimit*); + + if (rl && ratelimit_configured(rl) && current->n_suppress == 0) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + + r = sd_json_buildo(&add_more, + SD_JSON_BUILD_PAIR("intervalUSec", SD_JSON_BUILD_UNSIGNED(rl->interval)), + SD_JSON_BUILD_PAIR("burst", SD_JSON_BUILD_UNSIGNED(rl->burst))); + if (r < 0) + goto finish; + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } } /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */ From 95e2f04144c6dfd9ecf8dbaa8414fdd0d5236b1e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 8 Aug 2024 13:43:05 +0200 Subject: [PATCH 03/11] json-util: Add JSON_BUILD_PAIR_DUAL_TIMESTAMP() --- src/libsystemd/sd-json/json-util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 242668eccee..585547c91d4 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -195,4 +195,5 @@ enum { #define JSON_BUILD_PAIR_HW_ADDR(name, v) SD_JSON_BUILD_PAIR(name, JSON_BUILD_HW_ADDR(v)) #define JSON_BUILD_PAIR_STRING_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_SET(s)) #define JSON_BUILD_PAIR_STRING_ORDERED_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_ORDERED_SET(s)) +#define JSON_BUILD_PAIR_DUAL_TIMESTAMP(name, t) SD_JSON_BUILD_PAIR(name, JSON_BUILD_DUAL_TIMESTAMP(t)) #define JSON_BUILD_PAIR_RATELIMIT(name, rl) SD_JSON_BUILD_PAIR(name, JSON_BUILD_RATELIMIT(rl)) From 5b5579066d3eb63d6c2c09839f0501475b95b548 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 8 Aug 2024 14:16:01 +0200 Subject: [PATCH 04/11] json-util: Add JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL() --- src/libsystemd/sd-json/json-util.h | 2 ++ src/libsystemd/sd-json/sd-json.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 585547c91d4..3be5f75878c 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -154,6 +154,7 @@ enum { _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL, _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, + _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL, _JSON_BUILD_PAIR_RATELIMIT_ENABLED, _SD_JSON_BUILD_REALLYMAX, @@ -184,6 +185,7 @@ enum { #define JSON_BUILD_PAIR_IN_ADDR_NON_NULL(name, v, f) _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, (const char*) { name }, (const union in_addr_union*) { v }, (int) { f } #define JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL, (const char*) { name }, (const struct ether_addr*) { v } #define JSON_BUILD_PAIR_HW_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, (const char*) { name }, (const struct hw_addr_data*) { v } +#define JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL(name, t) _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL, (const char*) { name }, (dual_timestamp*) { t } #define JSON_BUILD_PAIR_RATELIMIT_ENABLED(name, rl) _JSON_BUILD_PAIR_RATELIMIT_ENABLED, (const char*) { name }, (const RateLimit*) { rl } #define JSON_BUILD_PAIR_IOVEC_BASE64(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_BASE64(iov)) diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index a4d9c80f069..62f0f3dcb1c 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4609,6 +4609,36 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } + case _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL: { + const dual_timestamp *ts; + const char *n; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char*); + ts = va_arg(ap, const dual_timestamp*); + + if (ts && dual_timestamp_is_set(ts) && current->n_suppress == 0) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + + r = sd_json_buildo(&add_more, + SD_JSON_BUILD_PAIR("realtime", SD_JSON_BUILD_UNSIGNED(ts->realtime)), + SD_JSON_BUILD_PAIR("monotonic", SD_JSON_BUILD_UNSIGNED(ts->monotonic))); + if (r < 0) + goto finish; + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } + case _JSON_BUILD_PAIR_RATELIMIT_ENABLED: { const RateLimit *rl; const char *n; From 9ba489c7f6d6da48772ed3f7862c781340aecda7 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 9 Aug 2024 13:40:43 +0200 Subject: [PATCH 05/11] json-util: Add JSON_BUILD_PAIR_CALLBACK_NON_NULL() Like JSON_BUILD_PAIR_CALLBACK(), but doesn't add anything to the variant if the callback doesn't put anything in the return argument. --- src/libsystemd/sd-json/json-util.h | 2 ++ src/libsystemd/sd-json/sd-json.c | 34 ++++++++++++++++++++++++++++++ src/test/test-json.c | 12 +++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 3be5f75878c..2d8322ab387 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -156,6 +156,7 @@ enum { _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL, _JSON_BUILD_PAIR_RATELIMIT_ENABLED, + _JSON_BUILD_PAIR_CALLBACK_NON_NULL, _SD_JSON_BUILD_REALLYMAX, }; @@ -187,6 +188,7 @@ enum { #define JSON_BUILD_PAIR_HW_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, (const char*) { name }, (const struct hw_addr_data*) { v } #define JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL(name, t) _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL, (const char*) { name }, (dual_timestamp*) { t } #define JSON_BUILD_PAIR_RATELIMIT_ENABLED(name, rl) _JSON_BUILD_PAIR_RATELIMIT_ENABLED, (const char*) { name }, (const RateLimit*) { rl } +#define JSON_BUILD_PAIR_CALLBACK_NON_NULL(name, c, u) _JSON_BUILD_PAIR_CALLBACK_NON_NULL, (const char*) { name }, (sd_json_build_callback_t) { c }, (void*) { u } #define JSON_BUILD_PAIR_IOVEC_BASE64(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_BASE64(iov)) #define JSON_BUILD_PAIR_IOVEC_HEX(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_HEX(iov)) diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 62f0f3dcb1c..17d24f4844b 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4668,6 +4668,40 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { current->expect = EXPECT_OBJECT_KEY; break; } + + case _JSON_BUILD_PAIR_CALLBACK_NON_NULL: { + sd_json_build_callback_t cb; + void *userdata; + const char *n; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char*); + cb = va_arg(ap, sd_json_build_callback_t); + userdata = va_arg(ap, void*); + + if (current->n_suppress == 0) { + if (cb) { + r = cb(&add_more, n, userdata); + if (r < 0) + goto finish; + } + + if (add_more) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + } + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } } /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */ diff --git a/src/test/test-json.c b/src/test/test-json.c index f9dc9e74c7b..378a3d0d8de 100644 --- a/src/test/test-json.c +++ b/src/test/test-json.c @@ -281,6 +281,8 @@ static int test_callback(sd_json_variant **ret, const char *name, void *userdata assert_se(PTR_TO_INT(userdata) == 4711); else if (streq_ptr(name, "mypid2")) assert_se(PTR_TO_INT(userdata) == 4712); + else if (streq_ptr(name, "mypid3")) + return 0; else assert_not_reached(); @@ -402,6 +404,16 @@ TEST(build) { assert_se(sd_json_variant_format(y, /* flags= */ 0, &f2)); ASSERT_STREQ(f1, f2); + _cleanup_(sd_json_variant_unrefp) sd_json_variant *z = NULL; + ASSERT_OK(sd_json_build(&z, SD_JSON_BUILD_OBJECT(JSON_BUILD_PAIR_CALLBACK_NON_NULL("mypid3", test_callback, INT_TO_PTR(4713))))); + ASSERT_TRUE(sd_json_variant_is_blank_object(z)); + z = sd_json_variant_unref(z); + f2 = mfree(f2); + ASSERT_OK(sd_json_build(&z, SD_JSON_BUILD_OBJECT(JSON_BUILD_PAIR_CALLBACK_NON_NULL("mypid1", test_callback, INT_TO_PTR(4711)), + JSON_BUILD_PAIR_CALLBACK_NON_NULL("mypid2", test_callback, INT_TO_PTR(4712))))); + ASSERT_OK(sd_json_variant_format(z, /* flags= */ 0, &f2)); + ASSERT_STREQ(f1, f2); + _cleanup_set_free_ Set *ss = NULL; assert_se(set_ensure_put(&ss, &string_hash_ops_free, ASSERT_PTR(strdup("pief"))) >= 0); assert_se(set_ensure_put(&ss, &string_hash_ops_free, ASSERT_PTR(strdup("xxxx"))) >= 0); From ab8a5e1f99456d6da658af35e4bdbf539580dd0e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 9 Aug 2024 15:12:22 +0200 Subject: [PATCH 06/11] json-util: Add JSON_BUILD_PAIR_INTEGER_NON_ZERO() --- src/libsystemd/sd-json/json-util.h | 2 ++ src/libsystemd/sd-json/sd-json.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 2d8322ab387..aafa8ca0b90 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -143,6 +143,7 @@ enum { _JSON_BUILD_DUAL_TIMESTAMP, _JSON_BUILD_RATELIMIT, + _JSON_BUILD_PAIR_INTEGER_NON_ZERO, _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, _JSON_BUILD_PAIR_FINITE_USEC, _JSON_BUILD_PAIR_STRING_NON_EMPTY, @@ -176,6 +177,7 @@ enum { #define JSON_BUILD_DUAL_TIMESTAMP(t) _JSON_BUILD_DUAL_TIMESTAMP, (dual_timestamp*) { t } #define JSON_BUILD_RATELIMIT(rl) _JSON_BUILD_RATELIMIT, (const RateLimit*) { rl } +#define JSON_BUILD_PAIR_INTEGER_NON_ZERO(name, i) _JSON_BUILD_PAIR_INTEGER_NON_ZERO, (const char*) { name }, (int64_t) { i } #define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u } #define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u } #define JSON_BUILD_PAIR_STRING_NON_EMPTY(name, s) _JSON_BUILD_PAIR_STRING_NON_EMPTY, (const char*) { name }, (const char*) { s } diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 17d24f4844b..c3e409bee15 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4330,6 +4330,34 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } + case _JSON_BUILD_PAIR_INTEGER_NON_ZERO: { + const char *n; + int64_t i; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char*); + i = va_arg(ap, int64_t); + + if (i != 0 && current->n_suppress == 0) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + + r = sd_json_variant_new_integer(&add_more, i); + if (r < 0) + goto finish; + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } + case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO: { const char *n; uint64_t u; From 7606139e61b566852dcdd3748d1b893edee38d4d Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 9 Aug 2024 16:25:32 +0200 Subject: [PATCH 07/11] json-util: Add JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE() --- src/libsystemd/sd-json/json-util.h | 2 ++ src/libsystemd/sd-json/sd-json.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index aafa8ca0b90..2403945f1f8 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -144,6 +144,7 @@ enum { _JSON_BUILD_RATELIMIT, _JSON_BUILD_PAIR_INTEGER_NON_ZERO, + _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE, _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, _JSON_BUILD_PAIR_FINITE_USEC, _JSON_BUILD_PAIR_STRING_NON_EMPTY, @@ -178,6 +179,7 @@ enum { #define JSON_BUILD_RATELIMIT(rl) _JSON_BUILD_RATELIMIT, (const RateLimit*) { rl } #define JSON_BUILD_PAIR_INTEGER_NON_ZERO(name, i) _JSON_BUILD_PAIR_INTEGER_NON_ZERO, (const char*) { name }, (int64_t) { i } +#define JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE(name, i) _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE, (const char*) { name }, (int64_t) { i } #define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u } #define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u } #define JSON_BUILD_PAIR_STRING_NON_EMPTY(name, s) _JSON_BUILD_PAIR_STRING_NON_EMPTY, (const char*) { name }, (const char*) { s } diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index c3e409bee15..7340b064eb1 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4330,9 +4330,11 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } - case _JSON_BUILD_PAIR_INTEGER_NON_ZERO: { + case _JSON_BUILD_PAIR_INTEGER_NON_ZERO: + case _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE: { const char *n; int64_t i; + bool include; if (current->expect != EXPECT_OBJECT_KEY) { r = -EINVAL; @@ -4342,7 +4344,14 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { n = va_arg(ap, const char*); i = va_arg(ap, int64_t); - if (i != 0 && current->n_suppress == 0) { + if (command == _JSON_BUILD_PAIR_INTEGER_NON_ZERO) + include = i != 0; + else if (command == _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE) + include = i >= 0; + else + assert_not_reached(); + + if (include && current->n_suppress == 0) { r = sd_json_variant_new_string(&add, n); if (r < 0) goto finish; From a85e9670f6380de24d6716adfb3e64eebec3c7e9 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sat, 10 Aug 2024 13:42:32 +0200 Subject: [PATCH 08/11] json-util: Add JSON_BUILD_PAIR_BYTE_ARRAY_NON_EMPTY() --- src/libsystemd/sd-json/json-util.h | 2 ++ src/libsystemd/sd-json/sd-json.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 2403945f1f8..3c32197bf17 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -151,6 +151,7 @@ enum { _JSON_BUILD_PAIR_STRV_NON_EMPTY, _JSON_BUILD_PAIR_VARIANT_NON_NULL, /* _SD_JSON_BUILD_PAIR_VARIANT_ARRAY_NON_EMPTY, */ + _JSON_BUILD_PAIR_BYTE_ARRAY_NON_EMPTY, _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL, _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL, _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, @@ -185,6 +186,7 @@ enum { #define JSON_BUILD_PAIR_STRING_NON_EMPTY(name, s) _JSON_BUILD_PAIR_STRING_NON_EMPTY, (const char*) { name }, (const char*) { s } #define JSON_BUILD_PAIR_STRV_NON_EMPTY(name, l) _JSON_BUILD_PAIR_STRV_NON_EMPTY, (const char*) { name }, (char**) { l } #define JSON_BUILD_PAIR_VARIANT_NON_NULL(name, v) _JSON_BUILD_PAIR_VARIANT_NON_NULL, (const char*) { name }, (sd_json_variant*) { v } +#define JSON_BUILD_PAIR_BYTE_ARRAY_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_BYTE_ARRAY_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } #define JSON_BUILD_PAIR_IN4_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL, (const char*) { name }, (const struct in_addr*) { v } #define JSON_BUILD_PAIR_IN6_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL, (const char*) { name }, (const struct in6_addr*) { v } #define JSON_BUILD_PAIR_IN_ADDR_NON_NULL(name, v, f) _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, (const char*) { name }, (const union in_addr_union*) { v }, (int) { f } diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 7340b064eb1..4c47008194b 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4504,6 +4504,36 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } + case _JSON_BUILD_PAIR_BYTE_ARRAY_NON_EMPTY: { + const void *array; + size_t sz; + const char *n; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char *); + array = va_arg(ap, const void*); + sz = va_arg(ap, size_t); + + if (sz > 0 && current->n_suppress == 0) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + + r = sd_json_variant_new_array_bytes(&add_more, array, sz); + if (r < 0) + goto finish; + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } + case _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL: { const struct in_addr *a; const char *n; From 6647bbeab13fb115ecd0b389963001e978da1fce Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 13 Aug 2024 13:04:06 +0200 Subject: [PATCH 09/11] json-util: Add JSON_BUILD_PAIR_BASE64_NON_EMPTY() and friends --- src/libsystemd/sd-json/json-util.h | 8 +++++++ src/libsystemd/sd-json/sd-json.c | 36 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 3c32197bf17..b4ce43761af 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -160,6 +160,10 @@ enum { _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL, _JSON_BUILD_PAIR_RATELIMIT_ENABLED, _JSON_BUILD_PAIR_CALLBACK_NON_NULL, + _JSON_BUILD_PAIR_BASE64_NON_EMPTY, + _JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY, + _JSON_BUILD_PAIR_HEX_NON_EMPTY, + _JSON_BUILD_PAIR_OCTESCAPE_NON_EMPTY, _SD_JSON_BUILD_REALLYMAX, }; @@ -195,6 +199,10 @@ enum { #define JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL(name, t) _JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL, (const char*) { name }, (dual_timestamp*) { t } #define JSON_BUILD_PAIR_RATELIMIT_ENABLED(name, rl) _JSON_BUILD_PAIR_RATELIMIT_ENABLED, (const char*) { name }, (const RateLimit*) { rl } #define JSON_BUILD_PAIR_CALLBACK_NON_NULL(name, c, u) _JSON_BUILD_PAIR_CALLBACK_NON_NULL, (const char*) { name }, (sd_json_build_callback_t) { c }, (void*) { u } +#define JSON_BUILD_PAIR_BASE64_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_BASE64_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } +#define JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } +#define JSON_BUILD_PAIR_HEX_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_HEX_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } +#define JSON_BUILD_PAIR_OCTESCAPE_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_HEX_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } #define JSON_BUILD_PAIR_IOVEC_BASE64(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_BASE64(iov)) #define JSON_BUILD_PAIR_IOVEC_HEX(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_HEX(iov)) diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 4c47008194b..7e26ef73e74 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4769,6 +4769,42 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { current->expect = EXPECT_OBJECT_KEY; break; } + + case _JSON_BUILD_PAIR_BASE64_NON_EMPTY: + case _JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY: + case _JSON_BUILD_PAIR_HEX_NON_EMPTY: + case _JSON_BUILD_PAIR_OCTESCAPE_NON_EMPTY: { + const void *p; + size_t sz; + const char *n; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char*); + p = va_arg(ap, const void *); + sz = va_arg(ap, size_t); + + if (sz > 0 && current->n_suppress == 0) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + + r = command == _SD_JSON_BUILD_BASE64 ? sd_json_variant_new_base64(&add_more, p, sz) : + command == _SD_JSON_BUILD_BASE32HEX ? sd_json_variant_new_base32hex(&add_more, p, sz) : + command == _SD_JSON_BUILD_HEX ? sd_json_variant_new_hex(&add_more, p, sz) : + sd_json_variant_new_octescape(&add_more, p, sz); + if (r < 0) + goto finish; + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } } /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */ From 0ea8d4bc8c0aef8ea1a9e1264b8670a2fc946335 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 13 Aug 2024 16:39:04 +0200 Subject: [PATCH 10/11] json-util: Add JSON_BUILD_TRISTATE() and friends --- src/libsystemd/sd-json/json-util.h | 5 +++ src/libsystemd/sd-json/sd-json.c | 59 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index b4ce43761af..ba9539d341e 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -142,6 +142,7 @@ enum { _JSON_BUILD_STRING_UNDERSCORIFY, _JSON_BUILD_DUAL_TIMESTAMP, _JSON_BUILD_RATELIMIT, + _JSON_BUILD_TRISTATE, _JSON_BUILD_PAIR_INTEGER_NON_ZERO, _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE, @@ -164,6 +165,7 @@ enum { _JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY, _JSON_BUILD_PAIR_HEX_NON_EMPTY, _JSON_BUILD_PAIR_OCTESCAPE_NON_EMPTY, + _JSON_BUILD_PAIR_TRISTATE_NON_NULL, _SD_JSON_BUILD_REALLYMAX, }; @@ -182,6 +184,7 @@ enum { #define JSON_BUILD_STRING_UNDERSCORIFY(s) _JSON_BUILD_STRING_UNDERSCORIFY, (const char *) { s } #define JSON_BUILD_DUAL_TIMESTAMP(t) _JSON_BUILD_DUAL_TIMESTAMP, (dual_timestamp*) { t } #define JSON_BUILD_RATELIMIT(rl) _JSON_BUILD_RATELIMIT, (const RateLimit*) { rl } +#define JSON_BUILD_TRISTATE(i) _JSON_BUILD_TRISTATE, (int) { i } #define JSON_BUILD_PAIR_INTEGER_NON_ZERO(name, i) _JSON_BUILD_PAIR_INTEGER_NON_ZERO, (const char*) { name }, (int64_t) { i } #define JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE(name, i) _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE, (const char*) { name }, (int64_t) { i } @@ -203,6 +206,7 @@ enum { #define JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_BASE32HEX_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } #define JSON_BUILD_PAIR_HEX_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_HEX_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } #define JSON_BUILD_PAIR_OCTESCAPE_NON_EMPTY(name, v, n) _JSON_BUILD_PAIR_HEX_NON_EMPTY, (const char*) { name }, (const void*) { v }, (size_t) { n } +#define JSON_BUILD_PAIR_TRISTATE_NON_NULL(name, i) _JSON_BUILD_PAIR_TRISTATE_NON_NULL, (const char*) { name }, (int) { i } #define JSON_BUILD_PAIR_IOVEC_BASE64(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_BASE64(iov)) #define JSON_BUILD_PAIR_IOVEC_HEX(name, iov) SD_JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_HEX(iov)) @@ -215,3 +219,4 @@ enum { #define JSON_BUILD_PAIR_STRING_ORDERED_SET(name, s) SD_JSON_BUILD_PAIR(name, JSON_BUILD_STRING_ORDERED_SET(s)) #define JSON_BUILD_PAIR_DUAL_TIMESTAMP(name, t) SD_JSON_BUILD_PAIR(name, JSON_BUILD_DUAL_TIMESTAMP(t)) #define JSON_BUILD_PAIR_RATELIMIT(name, rl) SD_JSON_BUILD_PAIR(name, JSON_BUILD_RATELIMIT(rl)) +#define JSON_BUILD_PAIR_TRISTATE(name, i) SD_JSON_BUILD_PAIR(name, JSON_BUILD_TRISTATE(i)) diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 7e26ef73e74..9bb35b2bbb6 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4194,6 +4194,37 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } + case _JSON_BUILD_TRISTATE: { + int tristate; + + if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) { + r = -EINVAL; + goto finish; + } + + tristate = va_arg(ap, int); + + if (current->n_suppress == 0) { + if (tristate >= 0) { + r = sd_json_variant_new_boolean(&add, tristate); + if (r < 0) + goto finish; + } else + add = JSON_VARIANT_MAGIC_NULL; + } + + n_subtract = 1; + + if (current->expect == EXPECT_TOPLEVEL) + current->expect = EXPECT_END; + else if (current->expect == EXPECT_OBJECT_VALUE) + current->expect = EXPECT_OBJECT_KEY; + else + assert(current->expect == EXPECT_ARRAY_ELEMENT); + + break; + } + case _SD_JSON_BUILD_CALLBACK: { sd_json_build_callback_t cb; void *userdata; @@ -4805,6 +4836,34 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { current->expect = EXPECT_OBJECT_KEY; break; } + + case _JSON_BUILD_PAIR_TRISTATE_NON_NULL: { + int tristate; + const char *n; + + if (current->expect != EXPECT_OBJECT_KEY) { + r = -EINVAL; + goto finish; + } + + n = va_arg(ap, const char*); + tristate = va_arg(ap, int); + + if (tristate >= 0 && current->n_suppress == 0) { + r = sd_json_variant_new_string(&add, n); + if (r < 0) + goto finish; + + r = sd_json_variant_new_boolean(&add_more, tristate); + if (r < 0) + goto finish; + } + + n_subtract = 2; /* we generated two item */ + + current->expect = EXPECT_OBJECT_KEY; + break; + } } /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */ From eabff5267ebe003a82e37bda5cd589a746e1183f Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 23 Aug 2024 14:57:12 +0200 Subject: [PATCH 11/11] json-util: Add JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL() --- src/libsystemd/sd-json/json-util.h | 2 ++ src/libsystemd/sd-json/sd-json.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index ba9539d341e..3823eb32ddb 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -147,6 +147,7 @@ enum { _JSON_BUILD_PAIR_INTEGER_NON_ZERO, _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE, _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, + _JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL, _JSON_BUILD_PAIR_FINITE_USEC, _JSON_BUILD_PAIR_STRING_NON_EMPTY, _JSON_BUILD_PAIR_STRV_NON_EMPTY, @@ -189,6 +190,7 @@ enum { #define JSON_BUILD_PAIR_INTEGER_NON_ZERO(name, i) _JSON_BUILD_PAIR_INTEGER_NON_ZERO, (const char*) { name }, (int64_t) { i } #define JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE(name, i) _JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE, (const char*) { name }, (int64_t) { i } #define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u } +#define JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL(name, u, eq) _JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL, (const char*) { name }, (uint64_t) { u }, (uint64_t) { eq } #define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u } #define JSON_BUILD_PAIR_STRING_NON_EMPTY(name, s) _JSON_BUILD_PAIR_STRING_NON_EMPTY, (const char*) { name }, (const char*) { s } #define JSON_BUILD_PAIR_STRV_NON_EMPTY(name, l) _JSON_BUILD_PAIR_STRV_NON_EMPTY, (const char*) { name }, (char**) { l } diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 9bb35b2bbb6..20599114ab5 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -4398,9 +4398,10 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { break; } - case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO: { + case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO: + case _JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL: { const char *n; - uint64_t u; + uint64_t u, eq; if (current->expect != EXPECT_OBJECT_KEY) { r = -EINVAL; @@ -4409,8 +4410,9 @@ _public_ int sd_json_buildv(sd_json_variant **ret, va_list ap) { n = va_arg(ap, const char *); u = va_arg(ap, uint64_t); + eq = command == _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO ? 0 : va_arg(ap, uint64_t); - if (u != 0 && current->n_suppress == 0) { + if (u != eq && current->n_suppress == 0) { r = sd_json_variant_new_string(&add, n); if (r < 0) goto finish;