From: Lennart Poettering Date: Wed, 28 Sep 2022 15:13:00 +0000 (+0200) Subject: json: add helper for json builder for octescape/base32hex X-Git-Tag: v252-rc1~53^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84738d864b6d96389ae6c5500be9a06f5a2d5927;p=thirdparty%2Fsystemd.git json: add helper for json builder for octescape/base32hex These encodings for binary data are mandated by DNS RFCs, so let's give make them nice and easy to use with json builder logic. --- diff --git a/src/shared/json.c b/src/shared/json.c index 87e87091b04..40c6f723eec 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -10,6 +10,7 @@ #include "alloc-util.h" #include "errno-util.h" +#include "escape.h" #include "fd-util.h" #include "fileio.h" #include "float.h" @@ -437,6 +438,19 @@ int json_variant_new_base64(JsonVariant **ret, const void *p, size_t n) { return json_variant_new_stringn(ret, s, k); } +int json_variant_new_base32hex(JsonVariant **ret, const void *p, size_t n) { + _cleanup_free_ char *s = NULL; + + assert_return(ret, -EINVAL); + assert_return(n == 0 || p, -EINVAL); + + s = base32hexmem(p, n, false); + if (!s) + return -ENOMEM; + + return json_variant_new_string(ret, s); +} + int json_variant_new_hex(JsonVariant **ret, const void *p, size_t n) { _cleanup_free_ char *s = NULL; @@ -450,6 +464,19 @@ int json_variant_new_hex(JsonVariant **ret, const void *p, size_t n) { return json_variant_new_stringn(ret, s, n*2); } +int json_variant_new_octescape(JsonVariant **ret, const void *p, size_t n) { + _cleanup_free_ char *s = NULL; + + assert_return(ret, -EINVAL); + assert_return(n == 0 || p, -EINVAL); + + s = octescape(p, n); + if (!s) + return -ENOMEM; + + return json_variant_new_string(ret, s); +} + int json_variant_new_id128(JsonVariant **ret, sd_id128_t id) { return json_variant_new_string(ret, SD_ID128_TO_STRING(id)); } @@ -3543,37 +3570,10 @@ int json_buildv(JsonVariant **ret, va_list ap) { break; } - case _JSON_BUILD_BASE64: { - const void *p; - size_t n; - - if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) { - r = -EINVAL; - goto finish; - } - - p = va_arg(ap, const void *); - n = va_arg(ap, size_t); - - if (current->n_suppress == 0) { - r = json_variant_new_base64(&add, p, n); - 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_HEX: { + case _JSON_BUILD_BASE64: + case _JSON_BUILD_BASE32HEX: + case _JSON_BUILD_HEX: + case _JSON_BUILD_OCTESCAPE: { const void *p; size_t n; @@ -3586,7 +3586,10 @@ int json_buildv(JsonVariant **ret, va_list ap) { n = va_arg(ap, size_t); if (current->n_suppress == 0) { - r = json_variant_new_hex(&add, p, n); + r = command == _JSON_BUILD_BASE64 ? json_variant_new_base64(&add, p, n) : + command == _JSON_BUILD_BASE32HEX ? json_variant_new_base32hex(&add, p, n) : + command == _JSON_BUILD_HEX ? json_variant_new_hex(&add, p, n) : + json_variant_new_octescape(&add, p, n); if (r < 0) goto finish; } diff --git a/src/shared/json.h b/src/shared/json.h index 06311cbf4b1..1992170ed7c 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -62,7 +62,9 @@ typedef enum JsonVariantType { int json_variant_new_stringn(JsonVariant **ret, const char *s, size_t n); int json_variant_new_base64(JsonVariant **ret, const void *p, size_t n); +int json_variant_new_base32hex(JsonVariant **ret, const void *p, size_t n); int json_variant_new_hex(JsonVariant **ret, const void *p, size_t n); +int json_variant_new_octescape(JsonVariant **ret, const void *p, size_t n); int json_variant_new_integer(JsonVariant **ret, int64_t i); int json_variant_new_unsigned(JsonVariant **ret, uint64_t u); int json_variant_new_real(JsonVariant **ret, double d); @@ -245,7 +247,9 @@ enum { _JSON_BUILD_LITERAL, _JSON_BUILD_STRV, _JSON_BUILD_BASE64, + _JSON_BUILD_BASE32HEX, _JSON_BUILD_HEX, + _JSON_BUILD_OCTESCAPE, _JSON_BUILD_ID128, _JSON_BUILD_BYTE_ARRAY, _JSON_BUILD_HW_ADDR, @@ -280,7 +284,9 @@ enum { #define JSON_BUILD_LITERAL(l) _JSON_BUILD_LITERAL, (const char*) { l } #define JSON_BUILD_STRV(l) _JSON_BUILD_STRV, (char**) { l } #define JSON_BUILD_BASE64(p, n) _JSON_BUILD_BASE64, (const void*) { p }, (size_t) { n } +#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 } #define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, (const sd_id128_t*) { &(id) } #define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, (const void*) { v }, (size_t) { n } #define JSON_BUILD_CONST_STRING(s) _JSON_BUILD_VARIANT, JSON_VARIANT_STRING_CONST(s)