From: Lennart Poettering Date: Thu, 19 Oct 2023 15:41:01 +0000 (+0200) Subject: json: add helpers for dispatching/building JSON with base64 struct iovecs X-Git-Tag: v255-rc1~181^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=034277203190195ae2759fa2ec76b29e3269b27c;p=thirdparty%2Fsystemd.git json: add helpers for dispatching/building JSON with base64 struct iovecs --- diff --git a/src/shared/json.c b/src/shared/json.c index f7e61f1676c..c3e34ecaa3d 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -3788,6 +3788,34 @@ int json_buildv(JsonVariant **ret, va_list ap) { break; } + case _JSON_BUILD_IOVEC_BASE64: { + const struct iovec *iov; + + if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) { + r = -EINVAL; + goto finish; + } + + iov = ASSERT_PTR(va_arg(ap, const struct iovec*)); + + if (current->n_suppress == 0) { + r = json_variant_new_base64(&add, iov->iov_base, iov->iov_len); + 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_ID128: case _JSON_BUILD_UUID: { const sd_id128_t *id; @@ -4792,6 +4820,24 @@ int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispat return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not allowed in this object.", strna(name)); } +int json_dispatch_unbase64_iovec(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) { + _cleanup_free_ void *buffer = NULL; + struct iovec *iov = ASSERT_PTR(userdata); + size_t sz; + int r; + + if (!json_variant_is_string(variant)) + return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name)); + + r = json_variant_unbase64(variant, &buffer, &sz); + if (r < 0) + return json_log(variant, flags, r, "JSON field '%s' is not valid Base64 data.", strna(name)); + + free_and_replace(iov->iov_base, buffer); + iov->iov_len = sz; + return 0; +} + static int json_cmp_strings(const void *x, const void *y) { JsonVariant *const *a = x, *const *b = y; diff --git a/src/shared/json.h b/src/shared/json.h index 8ddff6be982..1f0d6803529 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -268,6 +268,7 @@ enum { _JSON_BUILD_STRV, _JSON_BUILD_STRV_ENV_PAIR, _JSON_BUILD_BASE64, + _JSON_BUILD_IOVEC_BASE64, _JSON_BUILD_BASE32HEX, _JSON_BUILD_HEX, _JSON_BUILD_OCTESCAPE, @@ -307,6 +308,7 @@ enum { #define JSON_BUILD_STRV(l) _JSON_BUILD_STRV, (char**) { l } #define JSON_BUILD_STRV_ENV_PAIR(l) _JSON_BUILD_STRV_ENV_PAIR, (char**) { l } #define JSON_BUILD_BASE64(p, n) _JSON_BUILD_BASE64, (const void*) { p }, (size_t) { n } +#define JSON_BUILD_IOVEC_BASE64(iov) _JSON_BUILD_IOVEC_BASE64, (const struct iovec*) { iov } #define JSON_BUILD_BASE32HEX(p, n) _JSON_BUILD_BASE32HEX, (const void*) { p }, (size_t) { n } #define JSON_BUILD_HEX(p, n) _JSON_BUILD_HEX, (const void*) { p }, (size_t) { n } #define JSON_BUILD_OCTESCAPE(p, n) _JSON_BUILD_OCTESCAPE, (const void*) { p }, (size_t) { n } @@ -335,6 +337,7 @@ enum { #define JSON_BUILD_PAIR_LITERAL(name, l) JSON_BUILD_PAIR(name, JSON_BUILD_LITERAL(l)) #define JSON_BUILD_PAIR_STRV(name, l) JSON_BUILD_PAIR(name, JSON_BUILD_STRV(l)) #define JSON_BUILD_PAIR_BASE64(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_BASE64(p, n)) +#define JSON_BUILD_PAIR_IOVEC_BASE64(name, iov) JSON_BUILD_PAIR(name, JSON_BUILD_IOVEC_BASE64(iov)) #define JSON_BUILD_PAIR_HEX(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_HEX(p, n)) #define JSON_BUILD_PAIR_ID128(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_ID128(id)) #define JSON_BUILD_PAIR_UUID(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_UUID(id)) @@ -404,6 +407,7 @@ int json_dispatch_uid_gid(const char *name, JsonVariant *variant, JsonDispatchFl int json_dispatch_user_group_name(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); int json_dispatch_id128(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); +int json_dispatch_unbase64_iovec(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); assert_cc(sizeof(uint32_t) == sizeof(unsigned)); #define json_dispatch_uint json_dispatch_uint32