]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
json: add helper for json builder for octescape/base32hex
authorLennart Poettering <lennart@poettering.net>
Wed, 28 Sep 2022 15:13:00 +0000 (17:13 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 30 Sep 2022 12:16:23 +0000 (14:16 +0200)
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.

src/shared/json.c
src/shared/json.h

index 87e87091b047add18a0dabc5d914a8d1650dbd1b..40c6f723eecaf8498d598a79347db1f0af25cfee 100644 (file)
@@ -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;
                         }
index 06311cbf4b129c0b1bf8b312206d1186699e3a55..1992170ed7c2a522ce2f421189666010ca838545 100644 (file)
@@ -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)