1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
9 #include "sd-messages.h"
11 #include "alloc-util.h"
12 #include "errno-util.h"
17 #include "hexdecoct.h"
18 #include "json-internal.h"
21 #include "math-util.h"
22 #include "memory-util.h"
23 #include "memstream-util.h"
25 #include "string-table.h"
26 #include "string-util.h"
28 #include "terminal-util.h"
29 #include "user-util.h"
32 /* Refuse putting together variants with a larger depth than 2K by default (as a protection against overflowing stacks
33 * if code processes JSON objects recursively. Note that we store the depth in an uint16_t, hence make sure this
36 * The value first was 16k, but it was discovered to be too high on llvm/x86-64. See also:
37 * https://github.com/systemd/systemd/issues/10738
39 * The value then was 4k, but it was discovered to be too high on s390x/aarch64. See also:
40 * https://github.com/systemd/systemd/issues/14396 */
42 #define DEPTH_MAX (2U*1024U)
43 assert_cc(DEPTH_MAX
<= UINT16_MAX
);
45 typedef struct JsonSource
{
46 /* When we parse from a file or similar, encodes the filename, to indicate the source of a json variant */
53 /* On x86-64 this whole structure should have a size of 6 * 64 bit = 48 bytes */
56 /* We either maintain a reference counter for this variant itself, or we are embedded into an
57 * array/object, in which case only that surrounding object is ref-counted. (If 'embedded' is false,
61 /* If this JsonVariant is part of an array/object, then this field points to the surrounding
62 * JSON_VARIANT_ARRAY/JSON_VARIANT_OBJECT object. (If 'embedded' is true, see below.) */
66 /* If this was parsed from some file or buffer, this stores where from, as well as the source line/column */
68 unsigned line
, column
;
70 /* The current 'depth' of the JsonVariant, i.e. how many levels of member variants this has */
73 JsonVariantType type
:8;
75 /* A marker whether this variant is embedded into in array/object or not. If true, the 'parent' pointer above
76 * is valid. If false, the 'n_ref' field above is valid instead. */
79 /* In some conditions (for example, if this object is part of an array of strings or objects), we don't store
80 * any data inline, but instead simply reference an external object and act as surrogate of it. In that case
81 * this bool is set, and the external object is referenced through the .reference field below. */
84 /* While comparing two arrays, we use this for marking what we already have seen */
87 /* Erase from memory when freeing */
90 /* If this is an object the fields are strictly ordered by name */
93 /* If in addition to this object all objects referenced by it are also ordered strictly by name */
97 /* For simple types we store the value in-line. */
100 /* For objects and arrays we store the number of elements immediately following */
103 /* If is_reference as indicated above is set, this is where the reference object is actually stored. */
104 JsonVariant
*reference
;
106 /* Strings are placed immediately after the structure. Note that when this is a JsonVariant
107 * embedded into an array we might encode strings up to INLINE_STRING_LENGTH characters
108 * directly inside the element, while longer strings are stored as references. When this
109 * object is not embedded into an array, but stand-alone, we allocate the right size for the
110 * whole structure, i.e. the array might be much larger than INLINE_STRING_LENGTH. */
111 DECLARE_FLEX_ARRAY(char, string
);
115 /* Inside string arrays we have a series of JsonVariant structures one after the other. In this case, strings longer
116 * than INLINE_STRING_MAX are stored as references, and all shorter ones inline. (This means — on x86-64 — strings up
117 * to 7 chars are stored within the array elements, and all others in separate allocations) */
118 #define INLINE_STRING_MAX (sizeof(JsonVariant) - offsetof(JsonVariant, string) - 1U)
120 /* Let's make sure this structure isn't increased in size accidentally. This check is only for our most relevant arch
122 #if defined(__x86_64__) && __SIZEOF_POINTER__ == 8
123 assert_cc(sizeof(JsonVariant
) == 40U);
124 assert_cc(INLINE_STRING_MAX
== 7U);
127 static JsonSource
* json_source_new(const char *name
) {
132 s
= malloc(offsetof(JsonSource
, name
) + strlen(name
) + 1);
139 strcpy(s
->name
, name
);
144 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(JsonSource
, json_source
, mfree
);
146 static bool json_source_equal(JsonSource
*a
, JsonSource
*b
) {
153 return streq(a
->name
, b
->name
);
156 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonSource
*, json_source_unref
);
158 /* There are four kind of JsonVariant* pointers:
161 * 2. A 'regular' one, i.e. pointing to malloc() memory
162 * 3. A 'magic' one, i.e. one of the special JSON_VARIANT_MAGIC_XYZ values, that encode a few very basic values directly in the pointer.
163 * 4. A 'const string' one, i.e. a pointer to a const string.
165 * The four kinds of pointers can be discerned like this:
167 * Detecting #1 is easy, just compare with NULL. Detecting #3 is similarly easy: all magic pointers are below
168 * _JSON_VARIANT_MAGIC_MAX (which is pretty low, within the first memory page, which is special on Linux and other
169 * OSes, as it is a faulting page). In order to discern #2 and #4 we check the lowest bit. If it's off it's #2,
170 * otherwise #4. This makes use of the fact that malloc() will return "maximum aligned" memory, which definitely
171 * means the pointer is even. This means we can use the uneven pointers to reference static strings, as long as we
172 * make sure that all static strings used like this are aligned to 2 (or higher), and that we mask the bit on
173 * access. The JSON_VARIANT_STRING_CONST() macro encodes strings as JsonVariant* pointers, with the bit set. */
175 static bool json_variant_is_magic(const JsonVariant
*v
) {
179 return v
< _JSON_VARIANT_MAGIC_MAX
;
182 static bool json_variant_is_const_string(const JsonVariant
*v
) {
184 if (v
< _JSON_VARIANT_MAGIC_MAX
)
187 /* A proper JsonVariant is aligned to whatever malloc() aligns things too, which is definitely not uneven. We
188 * hence use all uneven pointers as indicators for const strings. */
190 return (((uintptr_t) v
) & 1) != 0;
193 static bool json_variant_is_regular(const JsonVariant
*v
) {
195 if (v
< _JSON_VARIANT_MAGIC_MAX
)
198 return (((uintptr_t) v
) & 1) == 0;
201 static JsonVariant
*json_variant_dereference(JsonVariant
*v
) {
203 /* Recursively dereference variants that are references to other variants */
208 if (!json_variant_is_regular(v
))
211 if (!v
->is_reference
)
214 return json_variant_dereference(v
->reference
);
217 static uint16_t json_variant_depth(JsonVariant
*v
) {
219 v
= json_variant_dereference(v
);
223 if (!json_variant_is_regular(v
))
229 static JsonVariant
*json_variant_formalize(JsonVariant
*v
) {
231 /* Converts json variant pointers to their normalized form, i.e. fully dereferenced and wherever
232 * possible converted to the "magic" version if there is one */
237 v
= json_variant_dereference(v
);
239 switch (json_variant_type(v
)) {
241 case JSON_VARIANT_BOOLEAN
:
242 return json_variant_boolean(v
) ? JSON_VARIANT_MAGIC_TRUE
: JSON_VARIANT_MAGIC_FALSE
;
244 case JSON_VARIANT_NULL
:
245 return JSON_VARIANT_MAGIC_NULL
;
247 case JSON_VARIANT_INTEGER
:
248 return json_variant_integer(v
) == 0 ? JSON_VARIANT_MAGIC_ZERO_INTEGER
: v
;
250 case JSON_VARIANT_UNSIGNED
:
251 return json_variant_unsigned(v
) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED
: v
;
253 case JSON_VARIANT_REAL
:
254 return iszero_safe(json_variant_real(v
)) ? JSON_VARIANT_MAGIC_ZERO_REAL
: v
;
256 case JSON_VARIANT_STRING
:
257 return isempty(json_variant_string(v
)) ? JSON_VARIANT_MAGIC_EMPTY_STRING
: v
;
259 case JSON_VARIANT_ARRAY
:
260 return json_variant_elements(v
) == 0 ? JSON_VARIANT_MAGIC_EMPTY_ARRAY
: v
;
262 case JSON_VARIANT_OBJECT
:
263 return json_variant_elements(v
) == 0 ? JSON_VARIANT_MAGIC_EMPTY_OBJECT
: v
;
270 static JsonVariant
*json_variant_conservative_formalize(JsonVariant
*v
) {
272 /* Much like json_variant_formalize(), but won't simplify if the variant has a source/line location
273 * attached to it, in order not to lose context */
278 if (!json_variant_is_regular(v
))
281 if (v
->source
|| v
->line
> 0 || v
->column
> 0)
284 return json_variant_formalize(v
);
287 static int json_variant_new(JsonVariant
**ret
, JsonVariantType type
, size_t space
) {
290 assert_return(ret
, -EINVAL
);
292 v
= malloc0(MAX(sizeof(JsonVariant
),
293 offsetof(JsonVariant
, value
) + space
));
304 int json_variant_new_integer(JsonVariant
**ret
, int64_t i
) {
308 assert_return(ret
, -EINVAL
);
311 *ret
= JSON_VARIANT_MAGIC_ZERO_INTEGER
;
315 r
= json_variant_new(&v
, JSON_VARIANT_INTEGER
, sizeof(i
));
319 v
->value
.integer
= i
;
325 int json_variant_new_unsigned(JsonVariant
**ret
, uint64_t u
) {
329 assert_return(ret
, -EINVAL
);
331 *ret
= JSON_VARIANT_MAGIC_ZERO_UNSIGNED
;
335 r
= json_variant_new(&v
, JSON_VARIANT_UNSIGNED
, sizeof(u
));
345 int json_variant_new_real(JsonVariant
**ret
, double d
) {
349 assert_return(ret
, -EINVAL
);
355 /* JSON doesn't know NaN, +Infinity or -Infinity. Let's silently convert to 'null'. */
356 *ret
= JSON_VARIANT_MAGIC_NULL
;
360 *ret
= JSON_VARIANT_MAGIC_ZERO_REAL
;
364 r
= json_variant_new(&v
, JSON_VARIANT_REAL
, sizeof(d
));
374 int json_variant_new_boolean(JsonVariant
**ret
, bool b
) {
375 assert_return(ret
, -EINVAL
);
378 *ret
= JSON_VARIANT_MAGIC_TRUE
;
380 *ret
= JSON_VARIANT_MAGIC_FALSE
;
385 int json_variant_new_null(JsonVariant
**ret
) {
386 assert_return(ret
, -EINVAL
);
388 *ret
= JSON_VARIANT_MAGIC_NULL
;
392 int json_variant_new_stringn(JsonVariant
**ret
, const char *s
, size_t n
) {
396 assert_return(ret
, -EINVAL
);
398 assert_return(IN_SET(n
, 0, SIZE_MAX
), -EINVAL
);
399 return json_variant_new_null(ret
);
401 if (n
== SIZE_MAX
) /* determine length automatically */
403 else if (memchr(s
, 0, n
)) /* don't allow embedded NUL, as we can't express that in JSON */
406 *ret
= JSON_VARIANT_MAGIC_EMPTY_STRING
;
410 if (!utf8_is_valid_n(s
, n
)) /* JSON strings must be valid UTF-8 */
413 r
= json_variant_new(&v
, JSON_VARIANT_STRING
, n
+ 1);
417 memcpy(v
->string
, s
, n
);
424 int json_variant_new_base64(JsonVariant
**ret
, const void *p
, size_t n
) {
425 _cleanup_free_
char *s
= NULL
;
428 assert_return(ret
, -EINVAL
);
429 assert_return(n
== 0 || p
, -EINVAL
);
431 k
= base64mem(p
, n
, &s
);
435 return json_variant_new_stringn(ret
, s
, k
);
438 int json_variant_new_base32hex(JsonVariant
**ret
, const void *p
, size_t n
) {
439 _cleanup_free_
char *s
= NULL
;
441 assert_return(ret
, -EINVAL
);
442 assert_return(n
== 0 || p
, -EINVAL
);
444 s
= base32hexmem(p
, n
, false);
448 return json_variant_new_string(ret
, s
);
451 int json_variant_new_hex(JsonVariant
**ret
, const void *p
, size_t n
) {
452 _cleanup_free_
char *s
= NULL
;
454 assert_return(ret
, -EINVAL
);
455 assert_return(n
== 0 || p
, -EINVAL
);
461 return json_variant_new_stringn(ret
, s
, n
*2);
464 int json_variant_new_octescape(JsonVariant
**ret
, const void *p
, size_t n
) {
465 _cleanup_free_
char *s
= NULL
;
467 assert_return(ret
, -EINVAL
);
468 assert_return(n
== 0 || p
, -EINVAL
);
474 return json_variant_new_string(ret
, s
);
477 int json_variant_new_id128(JsonVariant
**ret
, sd_id128_t id
) {
478 return json_variant_new_string(ret
, SD_ID128_TO_STRING(id
));
481 int json_variant_new_uuid(JsonVariant
**ret
, sd_id128_t id
) {
482 return json_variant_new_string(ret
, SD_ID128_TO_UUID_STRING(id
));
485 static void json_variant_set(JsonVariant
*a
, JsonVariant
*b
) {
488 b
= json_variant_dereference(b
);
490 a
->type
= JSON_VARIANT_NULL
;
494 a
->type
= json_variant_type(b
);
497 case JSON_VARIANT_INTEGER
:
498 a
->value
.integer
= json_variant_integer(b
);
501 case JSON_VARIANT_UNSIGNED
:
502 a
->value
.unsig
= json_variant_unsigned(b
);
505 case JSON_VARIANT_REAL
:
506 a
->value
.real
= json_variant_real(b
);
509 case JSON_VARIANT_BOOLEAN
:
510 a
->value
.boolean
= json_variant_boolean(b
);
513 case JSON_VARIANT_STRING
: {
516 assert_se(s
= json_variant_string(b
));
518 /* Short strings we can store inline */
519 if (strnlen(s
, INLINE_STRING_MAX
+1) <= INLINE_STRING_MAX
) {
520 strcpy(a
->string
, s
);
524 /* For longer strings, use a reference… */
528 case JSON_VARIANT_ARRAY
:
529 case JSON_VARIANT_OBJECT
:
530 a
->is_reference
= true;
531 a
->reference
= json_variant_ref(json_variant_conservative_formalize(b
));
534 case JSON_VARIANT_NULL
:
538 assert_not_reached();
542 static void json_variant_copy_source(JsonVariant
*v
, JsonVariant
*from
) {
545 if (!json_variant_is_regular(from
))
548 v
->line
= from
->line
;
549 v
->column
= from
->column
;
550 v
->source
= json_source_ref(from
->source
);
553 static int _json_variant_array_put_element(JsonVariant
*array
, JsonVariant
*element
) {
555 JsonVariant
*w
= array
+ 1 + array
->n_elements
;
557 uint16_t d
= json_variant_depth(element
);
558 if (d
>= DEPTH_MAX
) /* Refuse too deep nesting */
560 if (d
>= array
->depth
)
561 array
->depth
= d
+ 1;
569 json_variant_set(w
, element
);
570 json_variant_copy_source(w
, element
);
572 if (!json_variant_is_normalized(element
))
573 array
->normalized
= false;
578 int json_variant_new_array(JsonVariant
**ret
, JsonVariant
**array
, size_t n
) {
579 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
582 assert_return(ret
, -EINVAL
);
584 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
587 assert_return(array
, -EINVAL
);
589 v
= new(JsonVariant
, n
+ 1);
595 .type
= JSON_VARIANT_ARRAY
,
599 while (v
->n_elements
< n
) {
600 r
= _json_variant_array_put_element(v
, array
[v
->n_elements
]);
609 int json_variant_new_array_bytes(JsonVariant
**ret
, const void *p
, size_t n
) {
610 assert_return(ret
, -EINVAL
);
612 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
615 assert_return(p
, -EINVAL
);
617 JsonVariant
*v
= new(JsonVariant
, n
+ 1);
623 .type
= JSON_VARIANT_ARRAY
,
628 for (size_t i
= 0; i
< n
; i
++) {
629 JsonVariant
*w
= v
+ 1 + i
;
634 .type
= JSON_VARIANT_UNSIGNED
,
635 .value
.unsig
= ((const uint8_t*) p
)[i
],
639 v
->normalized
= true;
645 int json_variant_new_array_strv(JsonVariant
**ret
, char **l
) {
646 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
654 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
658 v
= new(JsonVariant
, n
+ 1);
664 .type
= JSON_VARIANT_ARRAY
,
668 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
669 JsonVariant
*w
= v
+ 1 + v
->n_elements
;
675 .type
= JSON_VARIANT_STRING
,
678 k
= strlen(l
[v
->n_elements
]);
680 if (k
> INLINE_STRING_MAX
) {
681 /* If string is too long, store it as reference. */
683 r
= json_variant_new_string(&w
->reference
, l
[v
->n_elements
]);
687 w
->is_reference
= true;
689 if (!utf8_is_valid_n(l
[v
->n_elements
], k
)) /* JSON strings must be valid UTF-8 */
692 memcpy(w
->string
, l
[v
->n_elements
], k
+1);
696 v
->normalized
= true;
702 int json_variant_new_object(JsonVariant
**ret
, JsonVariant
**array
, size_t n
) {
703 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
704 const char *prev
= NULL
;
705 bool sorted
= true, normalized
= true;
707 assert_return(ret
, -EINVAL
);
709 *ret
= JSON_VARIANT_MAGIC_EMPTY_OBJECT
;
712 assert_return(array
, -EINVAL
);
713 assert_return(n
% 2 == 0, -EINVAL
);
715 v
= new(JsonVariant
, n
+ 1);
721 .type
= JSON_VARIANT_OBJECT
,
724 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
725 JsonVariant
*w
= v
+ 1 + v
->n_elements
,
726 *c
= array
[v
->n_elements
];
729 if ((v
->n_elements
& 1) == 0) {
732 if (!json_variant_is_string(c
))
733 return -EINVAL
; /* Every second one needs to be a string, as it is the key name */
735 assert_se(k
= json_variant_string(c
));
737 if (prev
&& strcmp(k
, prev
) <= 0)
738 sorted
= normalized
= false;
741 } else if (!json_variant_is_normalized(c
))
744 d
= json_variant_depth(c
);
745 if (d
>= DEPTH_MAX
) /* Refuse too deep nesting */
755 json_variant_set(w
, c
);
756 json_variant_copy_source(w
, c
);
759 v
->normalized
= normalized
;
766 static size_t json_variant_size(JsonVariant
* v
) {
767 if (!json_variant_is_regular(v
))
771 return offsetof(JsonVariant
, reference
) + sizeof(JsonVariant
*);
775 case JSON_VARIANT_STRING
:
776 return offsetof(JsonVariant
, string
) + strlen(v
->string
) + 1;
778 case JSON_VARIANT_REAL
:
779 return offsetof(JsonVariant
, value
) + sizeof(double);
781 case JSON_VARIANT_UNSIGNED
:
782 return offsetof(JsonVariant
, value
) + sizeof(uint64_t);
784 case JSON_VARIANT_INTEGER
:
785 return offsetof(JsonVariant
, value
) + sizeof(int64_t);
787 case JSON_VARIANT_BOOLEAN
:
788 return offsetof(JsonVariant
, value
) + sizeof(bool);
790 case JSON_VARIANT_ARRAY
:
791 case JSON_VARIANT_OBJECT
:
792 return offsetof(JsonVariant
, n_elements
) + sizeof(size_t);
794 case JSON_VARIANT_NULL
:
795 return offsetof(JsonVariant
, value
);
798 assert_not_reached();
802 static void json_variant_free_inner(JsonVariant
*v
, bool force_sensitive
) {
807 if (!json_variant_is_regular(v
))
810 json_source_unref(v
->source
);
812 sensitive
= v
->sensitive
|| force_sensitive
;
814 if (v
->is_reference
) {
816 json_variant_sensitive(v
->reference
);
818 json_variant_unref(v
->reference
);
822 if (IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
823 for (size_t i
= 0; i
< v
->n_elements
; i
++)
824 json_variant_free_inner(v
+ 1 + i
, sensitive
);
827 explicit_bzero_safe(v
, json_variant_size(v
));
830 static unsigned json_variant_n_ref(const JsonVariant
*v
) {
831 /* Return the number of references to v.
832 * 0 => NULL or not a regular object or embedded.
833 * >0 => number of references
836 if (!v
|| !json_variant_is_regular(v
) || v
->is_embedded
)
839 assert(v
->n_ref
> 0);
843 JsonVariant
*json_variant_ref(JsonVariant
*v
) {
846 if (!json_variant_is_regular(v
))
850 json_variant_ref(v
->parent
); /* ref the compounding variant instead */
852 assert(v
->n_ref
> 0);
859 JsonVariant
*json_variant_unref(JsonVariant
*v
) {
862 if (!json_variant_is_regular(v
))
866 json_variant_unref(v
->parent
);
868 assert(v
->n_ref
> 0);
872 json_variant_free_inner(v
, false);
880 void json_variant_unref_many(JsonVariant
**array
, size_t n
) {
881 assert(array
|| n
== 0);
883 for (size_t i
= 0; i
< n
; i
++)
884 json_variant_unref(array
[i
]);
889 const char *json_variant_string(JsonVariant
*v
) {
892 if (v
== JSON_VARIANT_MAGIC_EMPTY_STRING
)
894 if (json_variant_is_magic(v
))
896 if (json_variant_is_const_string(v
)) {
897 uintptr_t p
= (uintptr_t) v
;
899 assert((p
& 1) != 0);
900 return (const char*) (p
^ 1U);
904 return json_variant_string(v
->reference
);
905 if (v
->type
!= JSON_VARIANT_STRING
)
911 log_debug("Non-string JSON variant requested as string, returning NULL.");
915 bool json_variant_boolean(JsonVariant
*v
) {
918 if (v
== JSON_VARIANT_MAGIC_TRUE
)
920 if (v
== JSON_VARIANT_MAGIC_FALSE
)
922 if (!json_variant_is_regular(v
))
924 if (v
->type
!= JSON_VARIANT_BOOLEAN
)
927 return json_variant_boolean(v
->reference
);
929 return v
->value
.boolean
;
932 log_debug("Non-boolean JSON variant requested as boolean, returning false.");
936 int64_t json_variant_integer(JsonVariant
*v
) {
939 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
940 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
941 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
943 if (!json_variant_is_regular(v
))
946 return json_variant_integer(v
->reference
);
950 case JSON_VARIANT_INTEGER
:
951 return v
->value
.integer
;
953 case JSON_VARIANT_UNSIGNED
:
954 if (v
->value
.unsig
<= INT64_MAX
)
955 return (int64_t) v
->value
.unsig
;
957 log_debug("Unsigned integer %" PRIu64
" requested as signed integer and out of range, returning 0.", v
->value
.unsig
);
960 case JSON_VARIANT_REAL
: {
963 converted
= (int64_t) v
->value
.real
;
965 if (fp_equal((double) converted
, v
->value
.real
))
968 log_debug("Real %g requested as integer, and cannot be converted losslessly, returning 0.", v
->value
.real
);
977 log_debug("Non-integer JSON variant requested as integer, returning 0.");
981 uint64_t json_variant_unsigned(JsonVariant
*v
) {
984 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
985 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
986 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
988 if (!json_variant_is_regular(v
))
991 return json_variant_integer(v
->reference
);
995 case JSON_VARIANT_INTEGER
:
996 if (v
->value
.integer
>= 0)
997 return (uint64_t) v
->value
.integer
;
999 log_debug("Signed integer %" PRIi64
" requested as unsigned integer and out of range, returning 0.", v
->value
.integer
);
1002 case JSON_VARIANT_UNSIGNED
:
1003 return v
->value
.unsig
;
1005 case JSON_VARIANT_REAL
: {
1008 converted
= (uint64_t) v
->value
.real
;
1010 if (fp_equal((double) converted
, v
->value
.real
))
1013 log_debug("Real %g requested as unsigned integer, and cannot be converted losslessly, returning 0.", v
->value
.real
);
1022 log_debug("Non-integer JSON variant requested as unsigned, returning 0.");
1026 double json_variant_real(JsonVariant
*v
) {
1029 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
1030 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
1031 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1033 if (!json_variant_is_regular(v
))
1035 if (v
->is_reference
)
1036 return json_variant_real(v
->reference
);
1040 case JSON_VARIANT_REAL
:
1041 return v
->value
.real
;
1043 case JSON_VARIANT_INTEGER
: {
1044 double converted
= (double) v
->value
.integer
;
1046 if ((int64_t) converted
== v
->value
.integer
)
1049 log_debug("Signed integer %" PRIi64
" requested as real, and cannot be converted losslessly, returning 0.", v
->value
.integer
);
1053 case JSON_VARIANT_UNSIGNED
: {
1054 double converted
= (double) v
->value
.unsig
;
1056 if ((uint64_t) converted
== v
->value
.unsig
)
1059 log_debug("Unsigned integer %" PRIu64
" requested as real, and cannot be converted losslessly, returning 0.", v
->value
.unsig
);
1068 log_debug("Non-integer JSON variant requested as integer, returning 0.");
1072 bool json_variant_is_negative(JsonVariant
*v
) {
1075 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
1076 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
1077 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1079 if (!json_variant_is_regular(v
))
1081 if (v
->is_reference
)
1082 return json_variant_is_negative(v
->reference
);
1084 /* This function is useful as checking whether numbers are negative is pretty complex since we have three types
1085 * of numbers. And some JSON code (OCI for example) uses negative numbers to mark "not defined" numeric
1090 case JSON_VARIANT_REAL
:
1091 return v
->value
.real
< 0;
1093 case JSON_VARIANT_INTEGER
:
1094 return v
->value
.integer
< 0;
1096 case JSON_VARIANT_UNSIGNED
:
1104 log_debug("Non-integer JSON variant tested for negativity, returning false.");
1108 bool json_variant_is_blank_object(JsonVariant
*v
) {
1109 /* Returns true if the specified object is null or empty */
1111 json_variant_is_null(v
) ||
1112 (json_variant_is_object(v
) && json_variant_elements(v
) == 0);
1115 bool json_variant_is_blank_array(JsonVariant
*v
) {
1117 json_variant_is_null(v
) ||
1118 (json_variant_is_array(v
) && json_variant_elements(v
) == 0);
1121 JsonVariantType
json_variant_type(JsonVariant
*v
) {
1124 return _JSON_VARIANT_TYPE_INVALID
;
1126 if (json_variant_is_const_string(v
))
1127 return JSON_VARIANT_STRING
;
1129 if (v
== JSON_VARIANT_MAGIC_TRUE
|| v
== JSON_VARIANT_MAGIC_FALSE
)
1130 return JSON_VARIANT_BOOLEAN
;
1132 if (v
== JSON_VARIANT_MAGIC_NULL
)
1133 return JSON_VARIANT_NULL
;
1135 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
)
1136 return JSON_VARIANT_INTEGER
;
1138 if (v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
)
1139 return JSON_VARIANT_UNSIGNED
;
1141 if (v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1142 return JSON_VARIANT_REAL
;
1144 if (v
== JSON_VARIANT_MAGIC_EMPTY_STRING
)
1145 return JSON_VARIANT_STRING
;
1147 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
)
1148 return JSON_VARIANT_ARRAY
;
1150 if (v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1151 return JSON_VARIANT_OBJECT
;
1156 _function_no_sanitize_float_cast_overflow_
1157 bool json_variant_has_type(JsonVariant
*v
, JsonVariantType type
) {
1160 /* Note: we turn off ubsan float cast overflow detection for this function, since it would complain
1161 * about our float casts but we do them explicitly to detect conversion errors. */
1163 v
= json_variant_dereference(v
);
1167 rt
= json_variant_type(v
);
1171 /* If it's a const string, then it only can be a string, and if it is not, it's not */
1172 if (json_variant_is_const_string(v
))
1175 /* All three magic zeroes qualify as integer, unsigned and as real */
1176 if ((v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
|| v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
|| v
== JSON_VARIANT_MAGIC_ZERO_REAL
) &&
1177 IN_SET(type
, JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
, JSON_VARIANT_NUMBER
))
1180 /* All other magic variant types are only equal to themselves */
1181 if (json_variant_is_magic(v
))
1184 /* Handle the "number" pseudo type */
1185 if (type
== JSON_VARIANT_NUMBER
)
1186 return IN_SET(rt
, JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
);
1188 /* Integer conversions are OK in many cases */
1189 if (rt
== JSON_VARIANT_INTEGER
&& type
== JSON_VARIANT_UNSIGNED
)
1190 return v
->value
.integer
>= 0;
1191 if (rt
== JSON_VARIANT_UNSIGNED
&& type
== JSON_VARIANT_INTEGER
)
1192 return v
->value
.unsig
<= INT64_MAX
;
1194 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1195 if (rt
== JSON_VARIANT_INTEGER
&& type
== JSON_VARIANT_REAL
)
1196 return (int64_t) (double) v
->value
.integer
== v
->value
.integer
;
1197 if (rt
== JSON_VARIANT_UNSIGNED
&& type
== JSON_VARIANT_REAL
)
1198 return (uint64_t) (double) v
->value
.unsig
== v
->value
.unsig
;
1200 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1201 if (rt
== JSON_VARIANT_REAL
&& type
== JSON_VARIANT_INTEGER
)
1202 return fp_equal((double) (int64_t) v
->value
.real
, v
->value
.real
);
1203 if (rt
== JSON_VARIANT_REAL
&& type
== JSON_VARIANT_UNSIGNED
)
1204 return fp_equal((double) (uint64_t) v
->value
.real
, v
->value
.real
);
1209 size_t json_variant_elements(JsonVariant
*v
) {
1212 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
||
1213 v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1215 if (!json_variant_is_regular(v
))
1217 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1219 if (v
->is_reference
)
1220 return json_variant_elements(v
->reference
);
1222 return v
->n_elements
;
1225 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1229 JsonVariant
*json_variant_by_index(JsonVariant
*v
, size_t idx
) {
1232 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
||
1233 v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1235 if (!json_variant_is_regular(v
))
1237 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1239 if (v
->is_reference
)
1240 return json_variant_by_index(v
->reference
, idx
);
1241 if (idx
>= v
->n_elements
)
1244 return json_variant_conservative_formalize(v
+ 1 + idx
);
1247 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1251 JsonVariant
*json_variant_by_key_full(JsonVariant
*v
, const char *key
, JsonVariant
**ret_key
) {
1256 if (v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1258 if (!json_variant_is_regular(v
))
1260 if (v
->type
!= JSON_VARIANT_OBJECT
)
1262 if (v
->is_reference
)
1263 return json_variant_by_key(v
->reference
, key
);
1266 size_t a
= 0, b
= v
->n_elements
/2;
1268 /* If the variant is sorted we can use bisection to find the entry we need in O(log(n)) time */
1277 p
= json_variant_dereference(v
+ 1 + i
*2);
1279 assert_se(f
= json_variant_string(p
));
1284 *ret_key
= json_variant_conservative_formalize(v
+ 1 + i
*2);
1286 return json_variant_conservative_formalize(v
+ 1 + i
*2 + 1);
1296 /* The variant is not sorted, hence search for the field linearly */
1297 for (size_t i
= 0; i
< v
->n_elements
; i
+= 2) {
1300 p
= json_variant_dereference(v
+ 1 + i
);
1302 if (!json_variant_has_type(p
, JSON_VARIANT_STRING
))
1305 if (streq(json_variant_string(p
), key
)) {
1308 *ret_key
= json_variant_conservative_formalize(v
+ 1 + i
);
1310 return json_variant_conservative_formalize(v
+ 1 + i
+ 1);
1321 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1328 JsonVariant
*json_variant_by_key(JsonVariant
*v
, const char *key
) {
1329 return json_variant_by_key_full(v
, key
, NULL
);
1332 bool json_variant_equal(JsonVariant
*a
, JsonVariant
*b
) {
1335 a
= json_variant_formalize(a
);
1336 b
= json_variant_formalize(b
);
1341 t
= json_variant_type(a
);
1342 if (!json_variant_has_type(b
, t
))
1347 case JSON_VARIANT_STRING
:
1348 return streq(json_variant_string(a
), json_variant_string(b
));
1350 case JSON_VARIANT_INTEGER
:
1351 return json_variant_integer(a
) == json_variant_integer(b
);
1353 case JSON_VARIANT_UNSIGNED
:
1354 return json_variant_unsigned(a
) == json_variant_unsigned(b
);
1356 case JSON_VARIANT_REAL
:
1357 return fp_equal(json_variant_real(a
), json_variant_real(b
));
1359 case JSON_VARIANT_BOOLEAN
:
1360 return json_variant_boolean(a
) == json_variant_boolean(b
);
1362 case JSON_VARIANT_NULL
:
1365 case JSON_VARIANT_ARRAY
: {
1366 size_t n
= json_variant_elements(a
);
1367 if (n
!= json_variant_elements(b
))
1370 for (size_t i
= 0; i
< n
; i
++)
1371 if (!json_variant_equal(json_variant_by_index(a
, i
), json_variant_by_index(b
, i
)))
1377 case JSON_VARIANT_OBJECT
: {
1378 size_t n
= json_variant_elements(a
);
1379 if (n
!= json_variant_elements(b
))
1382 /* Iterate through all keys in 'a' */
1383 for (size_t i
= 0; i
< n
; i
+= 2) {
1386 /* Match them against all keys in 'b' */
1387 for (size_t j
= 0; j
< n
; j
+= 2) {
1390 key_b
= json_variant_by_index(b
, j
);
1392 /* During the first iteration unmark everything */
1394 key_b
->is_marked
= false;
1395 else if (key_b
->is_marked
) /* In later iterations if we already marked something, don't bother with it again */
1401 if (json_variant_equal(json_variant_by_index(a
, i
), key_b
) &&
1402 json_variant_equal(json_variant_by_index(a
, i
+1), json_variant_by_index(b
, j
+1))) {
1403 /* Key and values match! */
1404 key_b
->is_marked
= found
= true;
1406 /* In the first iteration we continue the inner loop since we want to mark
1407 * everything, otherwise exit the loop quickly after we found what we were
1422 assert_not_reached();
1426 void json_variant_sensitive(JsonVariant
*v
) {
1429 /* Marks a variant as "sensitive", so that it is erased from memory when it is destroyed. This is a
1430 * one-way operation: as soon as it is marked this way it remains marked this way until it's
1431 * destroyed. A magic variant is never sensitive though, even when asked, since it's too
1432 * basic. Similar, const string variant are never sensitive either, after all they are included in
1433 * the source code as they are, which is not suitable for inclusion of secrets.
1435 * Note that this flag has a recursive effect: when we destroy an object or array we'll propagate the
1436 * flag to all contained variants. And if those are then destroyed this is propagated further down,
1439 v
= json_variant_formalize(v
);
1440 if (!json_variant_is_regular(v
))
1443 v
->sensitive
= true;
1446 bool json_variant_is_sensitive(JsonVariant
*v
) {
1447 v
= json_variant_formalize(v
);
1448 if (!json_variant_is_regular(v
))
1451 return v
->sensitive
;
1454 static void json_variant_propagate_sensitive(JsonVariant
*from
, JsonVariant
*to
) {
1455 if (json_variant_is_sensitive(from
))
1456 json_variant_sensitive(to
);
1459 int json_variant_get_source(JsonVariant
*v
, const char **ret_source
, unsigned *ret_line
, unsigned *ret_column
) {
1460 assert_return(v
, -EINVAL
);
1463 *ret_source
= json_variant_is_regular(v
) && v
->source
? v
->source
->name
: NULL
;
1466 *ret_line
= json_variant_is_regular(v
) ? v
->line
: 0;
1469 *ret_column
= json_variant_is_regular(v
) ? v
->column
: 0;
1474 static int print_source(FILE *f
, JsonVariant
*v
, JsonFormatFlags flags
, bool whitespace
) {
1477 if (!FLAGS_SET(flags
, JSON_FORMAT_SOURCE
|JSON_FORMAT_PRETTY
))
1480 if (!json_variant_is_regular(v
))
1483 if (!v
->source
&& v
->line
== 0 && v
->column
== 0)
1486 /* The max width we need to format the line numbers for this source file */
1487 w
= (v
->source
&& v
->source
->max_line
> 0) ?
1488 DECIMAL_STR_WIDTH(v
->source
->max_line
) :
1489 DECIMAL_STR_MAX(unsigned)-1;
1490 k
= (v
->source
&& v
->source
->max_column
> 0) ?
1491 DECIMAL_STR_WIDTH(v
->source
->max_column
) :
1492 DECIMAL_STR_MAX(unsigned) -1;
1495 size_t n
= 1 + (v
->source
? strlen(v
->source
->name
) : 0) +
1496 ((v
->source
&& (v
->line
> 0 || v
->column
> 0)) ? 1 : 0) +
1497 (v
->line
> 0 ? w
: 0) +
1498 (((v
->source
|| v
->line
> 0) && v
->column
> 0) ? 1 : 0) +
1499 (v
->column
> 0 ? k
: 0) +
1502 for (size_t i
= 0; i
< n
; i
++)
1508 fputs(v
->source
->name
, f
);
1509 if (v
->source
&& (v
->line
> 0 || v
->column
> 0))
1512 fprintf(f
, "%*u", (int) w
, v
->line
);
1513 if ((v
->source
|| v
->line
> 0) || v
->column
> 0)
1516 fprintf(f
, "%*u", (int) k
, v
->column
);
1525 static void json_format_string(FILE *f
, const char *q
, JsonFormatFlags flags
) {
1530 if (flags
& JSON_FORMAT_COLOR
)
1531 fputs(ansi_green(), f
);
1564 if ((signed char) *q
>= 0 && *q
< ' ')
1565 fprintf(f
, "\\u%04x", (unsigned) *q
);
1571 if (flags
& JSON_FORMAT_COLOR
)
1572 fputs(ANSI_NORMAL
, f
);
1577 static int json_format(FILE *f
, JsonVariant
*v
, JsonFormatFlags flags
, const char *prefix
) {
1583 switch (json_variant_type(v
)) {
1585 case JSON_VARIANT_REAL
: {
1586 locale_t loc
, old_loc
;
1588 loc
= newlocale(LC_NUMERIC_MASK
, "C", (locale_t
) 0);
1589 if (loc
== (locale_t
) 0)
1592 if (flags
& JSON_FORMAT_COLOR
)
1593 fputs(ansi_highlight_blue(), f
);
1595 old_loc
= uselocale(loc
);
1596 fprintf(f
, "%.*e", DECIMAL_DIG
, json_variant_real(v
));
1599 if (flags
& JSON_FORMAT_COLOR
)
1600 fputs(ANSI_NORMAL
, f
);
1606 case JSON_VARIANT_INTEGER
:
1607 if (flags
& JSON_FORMAT_COLOR
)
1608 fputs(ansi_highlight_blue(), f
);
1610 fprintf(f
, "%" PRIdMAX
, json_variant_integer(v
));
1612 if (flags
& JSON_FORMAT_COLOR
)
1613 fputs(ANSI_NORMAL
, f
);
1616 case JSON_VARIANT_UNSIGNED
:
1617 if (flags
& JSON_FORMAT_COLOR
)
1618 fputs(ansi_highlight_blue(), f
);
1620 fprintf(f
, "%" PRIuMAX
, json_variant_unsigned(v
));
1622 if (flags
& JSON_FORMAT_COLOR
)
1623 fputs(ANSI_NORMAL
, f
);
1626 case JSON_VARIANT_BOOLEAN
:
1628 if (flags
& JSON_FORMAT_COLOR
)
1629 fputs(ANSI_HIGHLIGHT
, f
);
1631 if (json_variant_boolean(v
))
1636 if (flags
& JSON_FORMAT_COLOR
)
1637 fputs(ANSI_NORMAL
, f
);
1641 case JSON_VARIANT_NULL
:
1642 if (flags
& JSON_FORMAT_COLOR
)
1643 fputs(ANSI_HIGHLIGHT
, f
);
1647 if (flags
& JSON_FORMAT_COLOR
)
1648 fputs(ANSI_NORMAL
, f
);
1651 case JSON_VARIANT_STRING
:
1652 json_format_string(f
, json_variant_string(v
), flags
);
1655 case JSON_VARIANT_ARRAY
: {
1656 size_t n
= json_variant_elements(v
);
1660 _cleanup_free_
char *joined
= NULL
;
1661 const char *prefix2
;
1663 if (flags
& JSON_FORMAT_PRETTY
) {
1664 joined
= strjoin(strempty(prefix
), "\t");
1671 prefix2
= strempty(prefix
);
1675 for (size_t i
= 0; i
< n
; i
++) {
1678 assert_se(e
= json_variant_by_index(v
, i
));
1681 if (flags
& JSON_FORMAT_PRETTY
)
1687 if (flags
& JSON_FORMAT_PRETTY
) {
1688 print_source(f
, e
, flags
, false);
1692 r
= json_format(f
, e
, flags
, prefix2
);
1697 if (flags
& JSON_FORMAT_PRETTY
) {
1699 print_source(f
, v
, flags
, true);
1700 fputs(strempty(prefix
), f
);
1708 case JSON_VARIANT_OBJECT
: {
1709 size_t n
= json_variant_elements(v
);
1713 _cleanup_free_
char *joined
= NULL
;
1714 const char *prefix2
;
1716 if (flags
& JSON_FORMAT_PRETTY
) {
1717 joined
= strjoin(strempty(prefix
), "\t");
1724 prefix2
= strempty(prefix
);
1728 for (size_t i
= 0; i
< n
; i
+= 2) {
1731 e
= json_variant_by_index(v
, i
);
1734 if (flags
& JSON_FORMAT_PRETTY
)
1740 if (flags
& JSON_FORMAT_PRETTY
) {
1741 print_source(f
, e
, flags
, false);
1745 r
= json_format(f
, e
, flags
, prefix2
);
1749 fputs(flags
& JSON_FORMAT_PRETTY
? " : " : ":", f
);
1751 r
= json_format(f
, json_variant_by_index(v
, i
+1), flags
, prefix2
);
1756 if (flags
& JSON_FORMAT_PRETTY
) {
1758 print_source(f
, v
, flags
, true);
1759 fputs(strempty(prefix
), f
);
1768 assert_not_reached();
1774 static bool json_variant_is_sensitive_recursive(JsonVariant
*v
) {
1777 if (json_variant_is_sensitive(v
))
1779 if (!json_variant_is_regular(v
))
1781 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1783 if (v
->is_reference
)
1784 return json_variant_is_sensitive_recursive(v
->reference
);
1786 for (size_t i
= 0; i
< json_variant_elements(v
); i
++)
1787 if (json_variant_is_sensitive_recursive(json_variant_by_index(v
, i
)))
1793 int json_variant_format(JsonVariant
*v
, JsonFormatFlags flags
, char **ret
) {
1794 _cleanup_(memstream_done
) MemStream m
= {};
1799 /* Returns the length of the generated string (without the terminating NUL),
1800 * or negative on error. */
1802 assert_return(v
, -EINVAL
);
1803 assert_return(ret
, -EINVAL
);
1805 if (flags
& JSON_FORMAT_OFF
)
1808 if ((flags
& JSON_FORMAT_REFUSE_SENSITIVE
))
1809 if (json_variant_is_sensitive_recursive(v
))
1812 f
= memstream_init(&m
);
1816 r
= json_variant_dump(v
, flags
, f
, NULL
);
1820 r
= memstream_finalize(&m
, ret
, &sz
);
1827 int json_variant_dump(JsonVariant
*v
, JsonFormatFlags flags
, FILE *f
, const char *prefix
) {
1829 if (flags
& JSON_FORMAT_EMPTY_ARRAY
)
1830 v
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
1838 print_source(f
, v
, flags
, false);
1840 if (((flags
& (JSON_FORMAT_COLOR_AUTO
|JSON_FORMAT_COLOR
)) == JSON_FORMAT_COLOR_AUTO
) && colors_enabled())
1841 flags
|= JSON_FORMAT_COLOR
;
1843 if (((flags
& (JSON_FORMAT_PRETTY_AUTO
|JSON_FORMAT_PRETTY
)) == JSON_FORMAT_PRETTY_AUTO
))
1844 flags
|= on_tty() ? JSON_FORMAT_PRETTY
: JSON_FORMAT_NEWLINE
;
1846 if (flags
& JSON_FORMAT_SSE
)
1848 if (flags
& JSON_FORMAT_SEQ
)
1849 fputc('\x1e', f
); /* ASCII Record Separator */
1851 json_format(f
, v
, flags
, prefix
);
1853 if (flags
& (JSON_FORMAT_PRETTY
|JSON_FORMAT_SEQ
|JSON_FORMAT_SSE
|JSON_FORMAT_NEWLINE
))
1855 if (flags
& JSON_FORMAT_SSE
)
1856 fputc('\n', f
); /* In case of SSE add a second newline */
1858 if (flags
& JSON_FORMAT_FLUSH
)
1859 return fflush_and_check(f
);
1863 int json_variant_filter(JsonVariant
**v
, char **to_remove
) {
1864 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
1865 _cleanup_free_ JsonVariant
**array
= NULL
;
1866 size_t n
= 0, k
= 0;
1871 if (json_variant_is_blank_object(*v
))
1873 if (!json_variant_is_object(*v
))
1876 if (strv_isempty(to_remove
))
1879 for (size_t i
= 0; i
< json_variant_elements(*v
); i
+= 2) {
1882 p
= json_variant_by_index(*v
, i
);
1883 if (!json_variant_has_type(p
, JSON_VARIANT_STRING
))
1886 if (strv_contains(to_remove
, json_variant_string(p
))) {
1888 array
= new(JsonVariant
*, json_variant_elements(*v
) - 2);
1892 for (k
= 0; k
< i
; k
++)
1893 array
[k
] = json_variant_by_index(*v
, k
);
1899 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
1906 r
= json_variant_new_object(&w
, array
, k
);
1910 json_variant_propagate_sensitive(*v
, w
);
1911 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(w
));
1916 int json_variant_set_field(JsonVariant
**v
, const char *field
, JsonVariant
*value
) {
1917 _cleanup_(json_variant_unrefp
) JsonVariant
*field_variant
= NULL
, *w
= NULL
;
1918 _cleanup_free_ JsonVariant
**array
= NULL
;
1925 if (json_variant_is_blank_object(*v
)) {
1926 array
= new(JsonVariant
*, 2);
1931 if (!json_variant_is_object(*v
))
1934 for (size_t i
= 0; i
< json_variant_elements(*v
); i
+= 2) {
1937 p
= json_variant_by_index(*v
, i
);
1938 if (!json_variant_is_string(p
))
1941 if (streq(json_variant_string(p
), field
)) {
1944 array
= new(JsonVariant
*, json_variant_elements(*v
));
1948 for (k
= 0; k
< i
; k
++)
1949 array
[k
] = json_variant_by_index(*v
, k
);
1954 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
1959 array
= new(JsonVariant
*, json_variant_elements(*v
) + 2);
1963 for (k
= 0; k
< json_variant_elements(*v
); k
++)
1964 array
[k
] = json_variant_by_index(*v
, k
);
1968 r
= json_variant_new_string(&field_variant
, field
);
1972 array
[k
++] = field_variant
;
1975 r
= json_variant_new_object(&w
, array
, k
);
1979 json_variant_propagate_sensitive(*v
, w
);
1980 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(w
));
1985 int json_variant_set_fieldb(JsonVariant
**v
, const char *field
, ...) {
1986 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
1990 va_start(ap
, field
);
1991 r
= json_buildv(&w
, ap
);
1996 return json_variant_set_field(v
, field
, w
);
1999 int json_variant_set_field_string(JsonVariant
**v
, const char *field
, const char *value
) {
2000 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2003 r
= json_variant_new_string(&m
, value
);
2007 return json_variant_set_field(v
, field
, m
);
2010 int json_variant_set_field_integer(JsonVariant
**v
, const char *field
, int64_t i
) {
2011 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2014 r
= json_variant_new_integer(&m
, i
);
2018 return json_variant_set_field(v
, field
, m
);
2021 int json_variant_set_field_unsigned(JsonVariant
**v
, const char *field
, uint64_t u
) {
2022 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2025 r
= json_variant_new_unsigned(&m
, u
);
2029 return json_variant_set_field(v
, field
, m
);
2032 int json_variant_set_field_boolean(JsonVariant
**v
, const char *field
, bool b
) {
2033 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2036 r
= json_variant_new_boolean(&m
, b
);
2040 return json_variant_set_field(v
, field
, m
);
2043 int json_variant_set_field_strv(JsonVariant
**v
, const char *field
, char **l
) {
2044 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2047 r
= json_variant_new_array_strv(&m
, l
);
2051 return json_variant_set_field(v
, field
, m
);
2054 int json_variant_merge_object(JsonVariant
**v
, JsonVariant
*m
) {
2055 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2056 _cleanup_free_ JsonVariant
**array
= NULL
;
2057 size_t v_elements
, m_elements
, k
;
2058 bool v_blank
, m_blank
;
2061 m
= json_variant_dereference(m
);
2063 v_blank
= json_variant_is_blank_object(*v
);
2064 m_blank
= json_variant_is_blank_object(m
);
2066 if (!v_blank
&& !json_variant_is_object(*v
))
2068 if (!m_blank
&& !json_variant_is_object(m
))
2072 return 0; /* nothing to do */
2075 JSON_VARIANT_REPLACE(*v
, json_variant_ref(m
));
2079 v_elements
= json_variant_elements(*v
);
2080 m_elements
= json_variant_elements(m
);
2081 if (v_elements
> SIZE_MAX
- m_elements
) /* overflow check */
2084 array
= new(JsonVariant
*, v_elements
+ m_elements
);
2089 for (size_t i
= 0; i
< v_elements
; i
+= 2) {
2092 u
= json_variant_by_index(*v
, i
);
2093 if (!json_variant_is_string(u
))
2096 if (json_variant_by_key(m
, json_variant_string(u
)))
2097 continue; /* skip if exists in second variant */
2100 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
2103 for (size_t i
= 0; i
< m_elements
; i
++)
2104 array
[k
++] = json_variant_by_index(m
, i
);
2106 r
= json_variant_new_object(&w
, array
, k
);
2110 json_variant_propagate_sensitive(*v
, w
);
2111 json_variant_propagate_sensitive(m
, w
);
2112 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(w
));
2117 int json_variant_merge_objectb(JsonVariant
**v
, ...) {
2118 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2123 r
= json_buildv(&w
, ap
);
2128 return json_variant_merge_object(v
, w
);
2131 int json_variant_append_array(JsonVariant
**v
, JsonVariant
*element
) {
2132 _cleanup_(json_variant_unrefp
) JsonVariant
*nv
= NULL
;
2139 if (!*v
|| json_variant_is_null(*v
))
2141 else if (json_variant_is_array(*v
))
2142 blank
= json_variant_elements(*v
) == 0;
2147 r
= json_variant_new_array(&nv
, (JsonVariant
*[]) { element
}, 1);
2150 } else if (json_variant_n_ref(*v
) == 1) {
2151 /* Let's bump the reference count on element. We can't do the realloc if we're appending *v
2152 * to itself, or one of the objects embedded in *v to *v. If the reference count grows, we
2153 * need to fall back to the other method below. */
2155 _unused_
_cleanup_(json_variant_unrefp
) JsonVariant
*dummy
= json_variant_ref(element
);
2156 if (json_variant_n_ref(*v
) == 1) {
2157 /* We hold the only reference. Let's mutate the object. */
2158 size_t size
= json_variant_elements(*v
);
2161 if (!GREEDY_REALLOC(*v
, size
+ 1 + 1))
2165 /* Readjust the parent pointers to the new address */
2166 for (size_t i
= 1; i
< size
; i
++)
2167 (*v
)[1 + i
].parent
= *v
;
2169 return _json_variant_array_put_element(*v
, element
);
2174 size_t size
= json_variant_elements(*v
);
2176 _cleanup_free_ JsonVariant
**array
= new(JsonVariant
*, size
+ 1);
2180 for (size_t i
= 0; i
< size
; i
++)
2181 array
[i
] = json_variant_by_index(*v
, i
);
2183 array
[size
] = element
;
2185 r
= json_variant_new_array(&nv
, array
, size
+ 1);
2190 json_variant_propagate_sensitive(*v
, nv
);
2191 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(nv
));
2196 int json_variant_append_arrayb(JsonVariant
**v
, ...) {
2197 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2202 r
= json_buildv(&w
, ap
);
2207 return json_variant_append_array(v
, w
);
2210 JsonVariant
*json_variant_find(JsonVariant
*haystack
, JsonVariant
*needle
) {
2213 /* Find a json object in an array. Returns NULL if not found, or if the array is not actually an array. */
2215 JSON_VARIANT_ARRAY_FOREACH(i
, haystack
)
2216 if (json_variant_equal(i
, needle
))
2222 int json_variant_append_array_nodup(JsonVariant
**v
, JsonVariant
*element
) {
2225 if (json_variant_find(*v
, element
))
2228 return json_variant_append_array(v
, element
);
2231 int json_variant_strv(JsonVariant
*v
, char ***ret
) {
2238 if (!v
|| json_variant_is_null(v
)) {
2247 if (!json_variant_is_array(v
))
2250 sensitive
= json_variant_is_sensitive(v
);
2252 size_t n
= json_variant_elements(v
);
2253 l
= new(char*, n
+1);
2257 for (size_t i
= 0; i
< n
; i
++) {
2260 assert_se(e
= json_variant_by_index(v
, i
));
2261 sensitive
= sensitive
|| json_variant_is_sensitive(e
);
2263 if (!json_variant_is_string(e
)) {
2269 l
[i
] = strdup(json_variant_string(e
));
2290 static int json_variant_copy(JsonVariant
**nv
, JsonVariant
*v
) {
2300 /* Let's copy the simple types literally, and the larger types by references */
2301 t
= json_variant_type(v
);
2303 case JSON_VARIANT_INTEGER
:
2304 k
= sizeof(int64_t);
2305 value
.integer
= json_variant_integer(v
);
2309 case JSON_VARIANT_UNSIGNED
:
2310 k
= sizeof(uint64_t);
2311 value
.unsig
= json_variant_unsigned(v
);
2315 case JSON_VARIANT_REAL
:
2317 value
.real
= json_variant_real(v
);
2321 case JSON_VARIANT_BOOLEAN
:
2323 value
.boolean
= json_variant_boolean(v
);
2327 case JSON_VARIANT_NULL
:
2332 case JSON_VARIANT_STRING
:
2333 source
= json_variant_string(v
);
2334 k
= strnlen(source
, INLINE_STRING_MAX
+ 1);
2335 if (k
<= INLINE_STRING_MAX
) {
2343 /* Everything else copy by reference */
2345 c
= malloc0(MAX(sizeof(JsonVariant
),
2346 offsetof(JsonVariant
, reference
) + sizeof(JsonVariant
*)));
2352 c
->is_reference
= true;
2353 c
->reference
= json_variant_ref(json_variant_formalize(v
));
2359 c
= malloc0(MAX(sizeof(JsonVariant
),
2360 offsetof(JsonVariant
, value
) + k
));
2367 memcpy_safe(&c
->value
, source
, k
);
2369 json_variant_propagate_sensitive(v
, c
);
2375 static bool json_single_ref(JsonVariant
*v
) {
2377 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
2379 if (!json_variant_is_regular(v
))
2383 return json_single_ref(v
->parent
);
2385 assert(v
->n_ref
> 0);
2386 return v
->n_ref
== 1;
2389 static int json_variant_set_source(JsonVariant
**v
, JsonSource
*source
, unsigned line
, unsigned column
) {
2395 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole
2396 * referencer of the object. If not, allocates a new object, possibly a surrogate for the original
2402 if (source
&& line
> source
->max_line
)
2403 source
->max_line
= line
;
2404 if (source
&& column
> source
->max_column
)
2405 source
->max_column
= column
;
2407 if (!json_variant_is_regular(*v
)) {
2409 if (!source
&& line
== 0 && column
== 0)
2413 if (json_source_equal((*v
)->source
, source
) &&
2414 (*v
)->line
== line
&&
2415 (*v
)->column
== column
)
2418 if (json_single_ref(*v
)) { /* Sole reference? */
2419 json_source_unref((*v
)->source
);
2420 (*v
)->source
= json_source_ref(source
);
2422 (*v
)->column
= column
;
2427 r
= json_variant_copy(&w
, *v
);
2431 assert(json_variant_is_regular(w
));
2432 assert(!w
->is_embedded
);
2433 assert(w
->n_ref
== 1);
2436 w
->source
= json_source_ref(source
);
2440 JSON_VARIANT_REPLACE(*v
, w
);
2445 static void inc_lines_columns(unsigned *line
, unsigned *column
, const char *s
, size_t n
) {
2448 assert(s
|| n
== 0);
2454 } else if ((signed char) *s
>= 0 && *s
< 127) /* Process ASCII chars quickly */
2459 w
= utf8_encoded_valid_unichar(s
, n
);
2460 if (w
< 0) /* count invalid unichars as normal characters */
2462 else if ((size_t) w
> n
) /* never read more than the specified number of characters */
2477 static int unhex_ucs2(const char *c
, uint16_t *ret
) {
2484 aa
= unhexchar(c
[0]);
2488 bb
= unhexchar(c
[1]);
2492 cc
= unhexchar(c
[2]);
2496 dd
= unhexchar(c
[3]);
2500 x
= ((uint16_t) aa
<< 12) |
2501 ((uint16_t) bb
<< 8) |
2502 ((uint16_t) cc
<< 4) |
2513 static int json_parse_string(const char **p
, char **ret
) {
2514 _cleanup_free_
char *s
= NULL
;
2536 /* Check for control characters 0x00..0x1f */
2537 if (*c
> 0 && *c
< ' ')
2540 /* Check for control character 0x7f */
2555 return JSON_TOKEN_STRING
;
2565 if (IN_SET(*c
, '"', '\\', '/'))
2577 else if (*c
== 'u') {
2581 r
= unhex_ucs2(c
+ 1, &x
);
2587 if (!GREEDY_REALLOC(s
, n
+ 5))
2590 if (!utf16_is_surrogate(x
))
2591 n
+= utf8_encode_unichar(s
+ n
, (char32_t
) x
);
2592 else if (utf16_is_trailing_surrogate(x
))
2597 if (c
[0] != '\\' || c
[1] != 'u')
2600 r
= unhex_ucs2(c
+ 2, &y
);
2606 if (!utf16_is_trailing_surrogate(y
))
2609 n
+= utf8_encode_unichar(s
+ n
, utf16_surrogate_pair_to_unichar(x
, y
));
2616 if (!GREEDY_REALLOC(s
, n
+ 2))
2624 len
= utf8_encoded_valid_unichar(c
, SIZE_MAX
);
2628 if (!GREEDY_REALLOC(s
, n
+ len
+ 1))
2631 memcpy(s
+ n
, c
, len
);
2637 static int json_parse_number(const char **p
, JsonValue
*ret
) {
2638 bool negative
= false, exponent_negative
= false, is_real
= false;
2639 double x
= 0.0, y
= 0.0, exponent
= 0.0, shift
= 1.0;
2658 if (!strchr("123456789", *c
) || *c
== 0)
2665 if (i
< INT64_MIN
/ 10) /* overflow */
2670 if (t
< INT64_MIN
+ (*c
- '0')) /* overflow */
2676 if (u
> UINT64_MAX
/ 10) /* overflow */
2679 uint64_t t
= 10 * u
;
2681 if (t
> UINT64_MAX
- (*c
- '0')) /* overflow */
2689 x
= 10.0 * x
+ (*c
- '0');
2692 } while (strchr("0123456789", *c
) && *c
!= 0);
2699 if (!strchr("0123456789", *c
) || *c
== 0)
2703 y
= 10.0 * y
+ (*c
- '0');
2704 shift
= 10.0 * shift
;
2706 } while (strchr("0123456789", *c
) && *c
!= 0);
2709 if (IN_SET(*c
, 'e', 'E')) {
2714 exponent_negative
= true;
2716 } else if (*c
== '+')
2719 if (!strchr("0123456789", *c
) || *c
== 0)
2723 exponent
= 10.0 * exponent
+ (*c
- '0');
2725 } while (strchr("0123456789", *c
) && *c
!= 0);
2731 ret
->real
= ((negative
? -1.0 : 1.0) * (x
+ (y
/ shift
))) * exp10((exponent_negative
? -1.0 : 1.0) * exponent
);
2732 return JSON_TOKEN_REAL
;
2733 } else if (negative
) {
2735 return JSON_TOKEN_INTEGER
;
2738 return JSON_TOKEN_UNSIGNED
;
2745 JsonValue
*ret_value
,
2746 unsigned *ret_line
, /* 'ret_line' returns the line at the beginning of this token */
2747 unsigned *ret_column
,
2749 unsigned *line
, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2752 unsigned start_line
, start_column
;
2753 const char *start
, *c
;
2773 t
= PTR_TO_INT(*state
);
2774 if (t
== STATE_NULL
) {
2780 /* Skip over the whitespace */
2781 n
= strspn(*p
, WHITESPACE
);
2782 inc_lines_columns(line
, column
, *p
, n
);
2785 /* Remember where we started processing this token */
2788 start_column
= *column
;
2792 *ret_value
= JSON_VALUE_NULL
;
2803 *state
= INT_TO_PTR(STATE_VALUE
);
2804 r
= JSON_TOKEN_OBJECT_OPEN
;
2807 } else if (*c
== '}') {
2809 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2810 r
= JSON_TOKEN_OBJECT_CLOSE
;
2813 } else if (*c
== '[') {
2815 *state
= INT_TO_PTR(STATE_VALUE
);
2816 r
= JSON_TOKEN_ARRAY_OPEN
;
2819 } else if (*c
== ']') {
2821 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2822 r
= JSON_TOKEN_ARRAY_CLOSE
;
2825 } else if (*c
== '"') {
2827 r
= json_parse_string(&c
, ret_string
);
2831 *ret_value
= JSON_VALUE_NULL
;
2832 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2835 } else if (strchr("-0123456789", *c
)) {
2837 r
= json_parse_number(&c
, ret_value
);
2842 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2845 } else if (startswith(c
, "true")) {
2847 ret_value
->boolean
= true;
2849 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2850 r
= JSON_TOKEN_BOOLEAN
;
2853 } else if (startswith(c
, "false")) {
2855 ret_value
->boolean
= false;
2857 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2858 r
= JSON_TOKEN_BOOLEAN
;
2861 } else if (startswith(c
, "null")) {
2863 *ret_value
= JSON_VALUE_NULL
;
2865 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2866 r
= JSON_TOKEN_NULL
;
2873 case STATE_VALUE_POST
:
2877 *state
= INT_TO_PTR(STATE_VALUE
);
2878 r
= JSON_TOKEN_COLON
;
2881 } else if (*c
== ',') {
2883 *state
= INT_TO_PTR(STATE_VALUE
);
2884 r
= JSON_TOKEN_COMMA
;
2887 } else if (*c
== '}') {
2889 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2890 r
= JSON_TOKEN_OBJECT_CLOSE
;
2893 } else if (*c
== ']') {
2895 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2896 r
= JSON_TOKEN_ARRAY_CLOSE
;
2903 assert_not_reached();
2908 *ret_value
= JSON_VALUE_NULL
;
2911 inc_lines_columns(line
, column
, start
, c
- start
);
2914 *ret_line
= start_line
;
2915 *ret_column
= start_column
;
2920 typedef enum JsonExpect
{
2921 /* The following values are used by json_parse() */
2924 EXPECT_OBJECT_FIRST_KEY
,
2925 EXPECT_OBJECT_NEXT_KEY
,
2926 EXPECT_OBJECT_COLON
,
2927 EXPECT_OBJECT_VALUE
,
2928 EXPECT_OBJECT_COMMA
,
2929 EXPECT_ARRAY_FIRST_ELEMENT
,
2930 EXPECT_ARRAY_NEXT_ELEMENT
,
2933 /* And these are used by json_build() */
2934 EXPECT_ARRAY_ELEMENT
,
2938 typedef struct JsonStack
{
2940 JsonVariant
**elements
;
2942 unsigned line_before
;
2943 unsigned column_before
;
2944 size_t n_suppress
; /* When building: if > 0, suppress this many subsequent elements. If == SIZE_MAX, suppress all subsequent elements */
2947 static void json_stack_release(JsonStack
*s
) {
2950 CLEANUP_ARRAY(s
->elements
, s
->n_elements
, json_variant_unref_many
);
2953 static int json_parse_internal(
2956 JsonParseFlags flags
,
2960 bool continue_end
) {
2963 unsigned line_buffer
= 0, column_buffer
= 0;
2964 void *tokenizer_state
= NULL
;
2965 JsonStack
*stack
= NULL
;
2969 assert_return(input
, -EINVAL
);
2970 assert_return(ret
, -EINVAL
);
2974 if (!GREEDY_REALLOC(stack
, n_stack
))
2977 stack
[0] = (JsonStack
) {
2978 .expect
= EXPECT_TOPLEVEL
,
2982 line
= &line_buffer
;
2984 column
= &column_buffer
;
2987 _cleanup_(json_variant_unrefp
) JsonVariant
*add
= NULL
;
2988 _cleanup_free_
char *string
= NULL
;
2989 unsigned line_token
, column_token
;
2994 assert(n_stack
> 0);
2995 current
= stack
+ n_stack
- 1;
2997 if (continue_end
&& current
->expect
== EXPECT_END
)
3000 token
= json_tokenize(&p
, &string
, &value
, &line_token
, &column_token
, &tokenizer_state
, line
, column
);
3008 case JSON_TOKEN_END
:
3009 if (current
->expect
!= EXPECT_END
) {
3014 assert(current
->n_elements
== 1);
3015 assert(n_stack
== 1);
3018 case JSON_TOKEN_COLON
:
3020 if (current
->expect
!= EXPECT_OBJECT_COLON
) {
3025 current
->expect
= EXPECT_OBJECT_VALUE
;
3028 case JSON_TOKEN_COMMA
:
3030 if (current
->expect
== EXPECT_OBJECT_COMMA
)
3031 current
->expect
= EXPECT_OBJECT_NEXT_KEY
;
3032 else if (current
->expect
== EXPECT_ARRAY_COMMA
)
3033 current
->expect
= EXPECT_ARRAY_NEXT_ELEMENT
;
3041 case JSON_TOKEN_OBJECT_OPEN
:
3043 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3048 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
3052 current
= stack
+ n_stack
- 1;
3054 /* Prepare the expect for when we return from the child */
3055 if (current
->expect
== EXPECT_TOPLEVEL
)
3056 current
->expect
= EXPECT_END
;
3057 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3058 current
->expect
= EXPECT_OBJECT_COMMA
;
3060 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3061 current
->expect
= EXPECT_ARRAY_COMMA
;
3064 stack
[n_stack
++] = (JsonStack
) {
3065 .expect
= EXPECT_OBJECT_FIRST_KEY
,
3066 .line_before
= line_token
,
3067 .column_before
= column_token
,
3070 current
= stack
+ n_stack
- 1;
3073 case JSON_TOKEN_OBJECT_CLOSE
:
3074 if (!IN_SET(current
->expect
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_COMMA
)) {
3079 assert(n_stack
> 1);
3081 r
= json_variant_new_object(&add
, current
->elements
, current
->n_elements
);
3085 line_token
= current
->line_before
;
3086 column_token
= current
->column_before
;
3088 json_stack_release(current
);
3089 n_stack
--, current
--;
3093 case JSON_TOKEN_ARRAY_OPEN
:
3094 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3099 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
3103 current
= stack
+ n_stack
- 1;
3105 /* Prepare the expect for when we return from the child */
3106 if (current
->expect
== EXPECT_TOPLEVEL
)
3107 current
->expect
= EXPECT_END
;
3108 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3109 current
->expect
= EXPECT_OBJECT_COMMA
;
3111 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3112 current
->expect
= EXPECT_ARRAY_COMMA
;
3115 stack
[n_stack
++] = (JsonStack
) {
3116 .expect
= EXPECT_ARRAY_FIRST_ELEMENT
,
3117 .line_before
= line_token
,
3118 .column_before
= column_token
,
3123 case JSON_TOKEN_ARRAY_CLOSE
:
3124 if (!IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_COMMA
)) {
3129 assert(n_stack
> 1);
3131 r
= json_variant_new_array(&add
, current
->elements
, current
->n_elements
);
3135 line_token
= current
->line_before
;
3136 column_token
= current
->column_before
;
3138 json_stack_release(current
);
3139 n_stack
--, current
--;
3142 case JSON_TOKEN_STRING
:
3143 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_NEXT_KEY
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3148 r
= json_variant_new_string(&add
, string
);
3152 if (current
->expect
== EXPECT_TOPLEVEL
)
3153 current
->expect
= EXPECT_END
;
3154 else if (IN_SET(current
->expect
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_NEXT_KEY
))
3155 current
->expect
= EXPECT_OBJECT_COLON
;
3156 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3157 current
->expect
= EXPECT_OBJECT_COMMA
;
3159 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3160 current
->expect
= EXPECT_ARRAY_COMMA
;
3165 case JSON_TOKEN_REAL
:
3166 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3171 r
= json_variant_new_real(&add
, value
.real
);
3175 if (current
->expect
== EXPECT_TOPLEVEL
)
3176 current
->expect
= EXPECT_END
;
3177 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3178 current
->expect
= EXPECT_OBJECT_COMMA
;
3180 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3181 current
->expect
= EXPECT_ARRAY_COMMA
;
3186 case JSON_TOKEN_INTEGER
:
3187 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3192 r
= json_variant_new_integer(&add
, value
.integer
);
3196 if (current
->expect
== EXPECT_TOPLEVEL
)
3197 current
->expect
= EXPECT_END
;
3198 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3199 current
->expect
= EXPECT_OBJECT_COMMA
;
3201 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3202 current
->expect
= EXPECT_ARRAY_COMMA
;
3207 case JSON_TOKEN_UNSIGNED
:
3208 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3213 r
= json_variant_new_unsigned(&add
, value
.unsig
);
3217 if (current
->expect
== EXPECT_TOPLEVEL
)
3218 current
->expect
= EXPECT_END
;
3219 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3220 current
->expect
= EXPECT_OBJECT_COMMA
;
3222 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3223 current
->expect
= EXPECT_ARRAY_COMMA
;
3228 case JSON_TOKEN_BOOLEAN
:
3229 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3234 r
= json_variant_new_boolean(&add
, value
.boolean
);
3238 if (current
->expect
== EXPECT_TOPLEVEL
)
3239 current
->expect
= EXPECT_END
;
3240 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3241 current
->expect
= EXPECT_OBJECT_COMMA
;
3243 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3244 current
->expect
= EXPECT_ARRAY_COMMA
;
3249 case JSON_TOKEN_NULL
:
3250 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3255 r
= json_variant_new_null(&add
);
3259 if (current
->expect
== EXPECT_TOPLEVEL
)
3260 current
->expect
= EXPECT_END
;
3261 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3262 current
->expect
= EXPECT_OBJECT_COMMA
;
3264 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3265 current
->expect
= EXPECT_ARRAY_COMMA
;
3271 assert_not_reached();
3275 /* If we are asked to make this parsed object sensitive, then let's apply this
3276 * immediately after allocating each variant, so that when we abort half-way
3277 * everything we already allocated that is then freed is correctly marked. */
3278 if (FLAGS_SET(flags
, JSON_PARSE_SENSITIVE
))
3279 json_variant_sensitive(add
);
3281 (void) json_variant_set_source(&add
, source
, line_token
, column_token
);
3283 if (!GREEDY_REALLOC(current
->elements
, current
->n_elements
+ 1)) {
3288 current
->elements
[current
->n_elements
++] = TAKE_PTR(add
);
3293 assert(n_stack
== 1);
3294 assert(stack
[0].n_elements
== 1);
3296 *ret
= json_variant_ref(stack
[0].elements
[0]);
3301 for (size_t i
= 0; i
< n_stack
; i
++)
3302 json_stack_release(stack
+ i
);
3309 int json_parse_with_source(
3312 JsonParseFlags flags
,
3315 unsigned *ret_column
) {
3317 _cleanup_(json_source_unrefp
) JsonSource
*s
= NULL
;
3320 s
= json_source_new(source
);
3325 return json_parse_internal(&input
, s
, flags
, ret
, ret_line
, ret_column
, false);
3328 int json_parse_with_source_continue(
3331 JsonParseFlags flags
,
3334 unsigned *ret_column
) {
3336 _cleanup_(json_source_unrefp
) JsonSource
*s
= NULL
;
3339 s
= json_source_new(source
);
3344 return json_parse_internal(p
, s
, flags
, ret
, ret_line
, ret_column
, true);
3347 int json_parse_file_at(
3351 JsonParseFlags flags
,
3354 unsigned *ret_column
) {
3356 _cleanup_free_
char *text
= NULL
;
3360 r
= read_full_stream(f
, &text
, NULL
);
3362 r
= read_full_file_full(dir_fd
, path
, UINT64_MAX
, SIZE_MAX
, 0, NULL
, &text
, NULL
);
3371 return json_parse_with_source(text
, path
, flags
, ret
, ret_line
, ret_column
);
3374 int json_buildv(JsonVariant
**ret
, va_list ap
) {
3375 JsonStack
*stack
= NULL
;
3377 const char *name
= NULL
;
3380 assert_return(ret
, -EINVAL
);
3382 if (!GREEDY_REALLOC(stack
, n_stack
))
3385 stack
[0] = (JsonStack
) {
3386 .expect
= EXPECT_TOPLEVEL
,
3390 _cleanup_(json_variant_unrefp
) JsonVariant
*add
= NULL
, *add_more
= NULL
;
3391 size_t n_subtract
= 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
3392 * have been added to the current variant */
3396 assert(n_stack
> 0);
3397 current
= stack
+ n_stack
- 1;
3399 if (current
->expect
== EXPECT_END
)
3402 command
= va_arg(ap
, int);
3406 case _JSON_BUILD_STRING
: {
3409 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3414 p
= va_arg(ap
, const char *);
3416 if (current
->n_suppress
== 0) {
3417 r
= json_variant_new_string(&add
, p
);
3424 if (current
->expect
== EXPECT_TOPLEVEL
)
3425 current
->expect
= EXPECT_END
;
3426 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3427 current
->expect
= EXPECT_OBJECT_KEY
;
3429 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3434 case _JSON_BUILD_INTEGER
: {
3437 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3442 j
= va_arg(ap
, int64_t);
3444 if (current
->n_suppress
== 0) {
3445 r
= json_variant_new_integer(&add
, j
);
3452 if (current
->expect
== EXPECT_TOPLEVEL
)
3453 current
->expect
= EXPECT_END
;
3454 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3455 current
->expect
= EXPECT_OBJECT_KEY
;
3457 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3462 case _JSON_BUILD_UNSIGNED
: {
3465 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3470 j
= va_arg(ap
, uint64_t);
3472 if (current
->n_suppress
== 0) {
3473 r
= json_variant_new_unsigned(&add
, j
);
3480 if (current
->expect
== EXPECT_TOPLEVEL
)
3481 current
->expect
= EXPECT_END
;
3482 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3483 current
->expect
= EXPECT_OBJECT_KEY
;
3485 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3490 case _JSON_BUILD_REAL
: {
3493 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3498 d
= va_arg(ap
, double);
3500 if (current
->n_suppress
== 0) {
3501 r
= json_variant_new_real(&add
, d
);
3508 if (current
->expect
== EXPECT_TOPLEVEL
)
3509 current
->expect
= EXPECT_END
;
3510 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3511 current
->expect
= EXPECT_OBJECT_KEY
;
3513 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3518 case _JSON_BUILD_BOOLEAN
: {
3521 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3526 b
= va_arg(ap
, int);
3528 if (current
->n_suppress
== 0) {
3529 r
= json_variant_new_boolean(&add
, b
);
3536 if (current
->expect
== EXPECT_TOPLEVEL
)
3537 current
->expect
= EXPECT_END
;
3538 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3539 current
->expect
= EXPECT_OBJECT_KEY
;
3541 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3546 case _JSON_BUILD_NULL
:
3548 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3553 if (current
->n_suppress
== 0) {
3554 r
= json_variant_new_null(&add
);
3561 if (current
->expect
== EXPECT_TOPLEVEL
)
3562 current
->expect
= EXPECT_END
;
3563 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3564 current
->expect
= EXPECT_OBJECT_KEY
;
3566 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3570 case _JSON_BUILD_VARIANT
:
3572 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3577 /* Note that we don't care for current->n_suppress here, after all the variant is already
3578 * allocated anyway... */
3579 add
= va_arg(ap
, JsonVariant
*);
3581 add
= JSON_VARIANT_MAGIC_NULL
;
3583 json_variant_ref(add
);
3587 if (current
->expect
== EXPECT_TOPLEVEL
)
3588 current
->expect
= EXPECT_END
;
3589 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3590 current
->expect
= EXPECT_OBJECT_KEY
;
3592 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3596 case _JSON_BUILD_VARIANT_ARRAY
: {
3597 JsonVariant
**array
;
3600 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3605 array
= va_arg(ap
, JsonVariant
**);
3606 n
= va_arg(ap
, size_t);
3608 if (current
->n_suppress
== 0) {
3609 r
= json_variant_new_array(&add
, array
, n
);
3616 if (current
->expect
== EXPECT_TOPLEVEL
)
3617 current
->expect
= EXPECT_END
;
3618 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3619 current
->expect
= EXPECT_OBJECT_KEY
;
3621 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3626 case _JSON_BUILD_LITERAL
: {
3629 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3634 l
= va_arg(ap
, const char *);
3637 /* Note that we don't care for current->n_suppress here, we should generate parsing
3638 * errors even in suppressed object properties */
3640 r
= json_parse(l
, 0, &add
, NULL
, NULL
);
3644 add
= JSON_VARIANT_MAGIC_NULL
;
3648 if (current
->expect
== EXPECT_TOPLEVEL
)
3649 current
->expect
= EXPECT_END
;
3650 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3651 current
->expect
= EXPECT_OBJECT_KEY
;
3653 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3658 case _JSON_BUILD_ARRAY_BEGIN
:
3660 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3665 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
3669 current
= stack
+ n_stack
- 1;
3671 if (current
->expect
== EXPECT_TOPLEVEL
)
3672 current
->expect
= EXPECT_END
;
3673 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3674 current
->expect
= EXPECT_OBJECT_KEY
;
3676 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3678 stack
[n_stack
++] = (JsonStack
) {
3679 .expect
= EXPECT_ARRAY_ELEMENT
,
3680 .n_suppress
= current
->n_suppress
!= 0 ? SIZE_MAX
: 0, /* if we shall suppress the
3681 * new array, then we should
3682 * also suppress all array
3688 case _JSON_BUILD_ARRAY_END
:
3689 if (current
->expect
!= EXPECT_ARRAY_ELEMENT
) {
3694 assert(n_stack
> 1);
3696 if (current
->n_suppress
== 0) {
3697 r
= json_variant_new_array(&add
, current
->elements
, current
->n_elements
);
3704 json_stack_release(current
);
3705 n_stack
--, current
--;
3709 case _JSON_BUILD_STRV
: {
3712 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3717 l
= va_arg(ap
, char **);
3719 if (current
->n_suppress
== 0) {
3720 r
= json_variant_new_array_strv(&add
, l
);
3727 if (current
->expect
== EXPECT_TOPLEVEL
)
3728 current
->expect
= EXPECT_END
;
3729 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3730 current
->expect
= EXPECT_OBJECT_KEY
;
3732 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3737 case _JSON_BUILD_STRV_ENV_PAIR
: {
3740 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3745 l
= va_arg(ap
, char **);
3747 _cleanup_strv_free_
char **el
= NULL
;
3748 STRV_FOREACH_PAIR(x
, y
, l
) {
3751 n
= strjoin(*x
, "=", *y
);
3757 r
= strv_consume(&el
, n
);
3762 if (current
->n_suppress
== 0) {
3763 r
= json_variant_new_array_strv(&add
, el
);
3770 if (current
->expect
== EXPECT_TOPLEVEL
)
3771 current
->expect
= EXPECT_END
;
3772 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3773 current
->expect
= EXPECT_OBJECT_KEY
;
3775 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3780 case _JSON_BUILD_BASE64
:
3781 case _JSON_BUILD_BASE32HEX
:
3782 case _JSON_BUILD_HEX
:
3783 case _JSON_BUILD_OCTESCAPE
: {
3787 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3792 p
= va_arg(ap
, const void *);
3793 n
= va_arg(ap
, size_t);
3795 if (current
->n_suppress
== 0) {
3796 r
= command
== _JSON_BUILD_BASE64
? json_variant_new_base64(&add
, p
, n
) :
3797 command
== _JSON_BUILD_BASE32HEX
? json_variant_new_base32hex(&add
, p
, n
) :
3798 command
== _JSON_BUILD_HEX
? json_variant_new_hex(&add
, p
, n
) :
3799 json_variant_new_octescape(&add
, p
, n
);
3806 if (current
->expect
== EXPECT_TOPLEVEL
)
3807 current
->expect
= EXPECT_END
;
3808 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3809 current
->expect
= EXPECT_OBJECT_KEY
;
3811 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3816 case _JSON_BUILD_IOVEC_BASE64
:
3817 case _JSON_BUILD_IOVEC_HEX
: {
3818 const struct iovec
*iov
;
3820 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3825 iov
= va_arg(ap
, const struct iovec
*);
3827 if (current
->n_suppress
== 0) {
3829 r
= command
== _JSON_BUILD_IOVEC_BASE64
? json_variant_new_base64(&add
, iov
->iov_base
, iov
->iov_len
) :
3830 json_variant_new_hex(&add
, iov
->iov_base
, iov
->iov_len
);
3832 r
= json_variant_new_string(&add
, "");
3839 if (current
->expect
== EXPECT_TOPLEVEL
)
3840 current
->expect
= EXPECT_END
;
3841 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3842 current
->expect
= EXPECT_OBJECT_KEY
;
3844 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3849 case _JSON_BUILD_ID128
:
3850 case _JSON_BUILD_UUID
: {
3851 const sd_id128_t
*id
;
3853 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3858 assert_se(id
= va_arg(ap
, sd_id128_t
*));
3860 if (current
->n_suppress
== 0) {
3861 r
= command
== _JSON_BUILD_ID128
?
3862 json_variant_new_id128(&add
, *id
) :
3863 json_variant_new_uuid(&add
, *id
);
3870 if (current
->expect
== EXPECT_TOPLEVEL
)
3871 current
->expect
= EXPECT_END
;
3872 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3873 current
->expect
= EXPECT_OBJECT_KEY
;
3875 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3880 case _JSON_BUILD_BYTE_ARRAY
: {
3884 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3889 array
= va_arg(ap
, const void*);
3890 n
= va_arg(ap
, size_t);
3892 if (current
->n_suppress
== 0) {
3893 r
= json_variant_new_array_bytes(&add
, array
, n
);
3900 if (current
->expect
== EXPECT_TOPLEVEL
)
3901 current
->expect
= EXPECT_END
;
3902 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3903 current
->expect
= EXPECT_OBJECT_KEY
;
3905 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3910 case _JSON_BUILD_HW_ADDR
: {
3911 const struct hw_addr_data
*hw_addr
;
3913 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3918 assert_se(hw_addr
= va_arg(ap
, struct hw_addr_data
*));
3920 if (current
->n_suppress
== 0) {
3921 r
= json_variant_new_array_bytes(&add
, hw_addr
->bytes
, hw_addr
->length
);
3928 if (current
->expect
== EXPECT_TOPLEVEL
)
3929 current
->expect
= EXPECT_END
;
3930 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3931 current
->expect
= EXPECT_OBJECT_KEY
;
3933 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3938 case _JSON_BUILD_STRING_SET
: {
3941 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3946 set
= va_arg(ap
, Set
*);
3948 if (current
->n_suppress
== 0) {
3949 _cleanup_free_
char **sorted
= NULL
;
3951 r
= set_dump_sorted(set
, (void ***) &sorted
, NULL
);
3955 r
= json_variant_new_array_strv(&add
, sorted
);
3962 if (current
->expect
== EXPECT_TOPLEVEL
)
3963 current
->expect
= EXPECT_END
;
3964 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3965 current
->expect
= EXPECT_OBJECT_KEY
;
3967 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3972 case _JSON_BUILD_CALLBACK
: {
3973 JsonBuildCallback cb
;
3976 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3981 cb
= va_arg(ap
, JsonBuildCallback
);
3982 userdata
= va_arg(ap
, void *);
3984 if (current
->n_suppress
== 0) {
3986 r
= cb(&add
, name
, userdata
);
3992 add
= JSON_VARIANT_MAGIC_NULL
;
3999 if (current
->expect
== EXPECT_TOPLEVEL
)
4000 current
->expect
= EXPECT_END
;
4001 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
4002 current
->expect
= EXPECT_OBJECT_KEY
;
4004 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
4009 case _JSON_BUILD_OBJECT_BEGIN
:
4011 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
4016 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
4020 current
= stack
+ n_stack
- 1;
4022 if (current
->expect
== EXPECT_TOPLEVEL
)
4023 current
->expect
= EXPECT_END
;
4024 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
4025 current
->expect
= EXPECT_OBJECT_KEY
;
4027 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
4029 stack
[n_stack
++] = (JsonStack
) {
4030 .expect
= EXPECT_OBJECT_KEY
,
4031 .n_suppress
= current
->n_suppress
!= 0 ? SIZE_MAX
: 0, /* If we shall suppress the
4032 * new object, then we should
4033 * also suppress all object
4039 case _JSON_BUILD_OBJECT_END
:
4041 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4046 assert(n_stack
> 1);
4048 if (current
->n_suppress
== 0) {
4049 r
= json_variant_new_object(&add
, current
->elements
, current
->n_elements
);
4056 json_stack_release(current
);
4057 n_stack
--, current
--;
4061 case _JSON_BUILD_PAIR
: {
4063 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4068 name
= va_arg(ap
, const char *);
4070 if (current
->n_suppress
== 0) {
4071 r
= json_variant_new_string(&add
, name
);
4078 current
->expect
= EXPECT_OBJECT_VALUE
;
4082 case _JSON_BUILD_PAIR_CONDITION
: {
4085 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4090 b
= va_arg(ap
, int);
4091 name
= va_arg(ap
, const char *);
4093 if (b
&& current
->n_suppress
== 0) {
4094 r
= json_variant_new_string(&add
, name
);
4099 n_subtract
= 1; /* we generated one item */
4101 if (!b
&& current
->n_suppress
!= SIZE_MAX
)
4102 current
->n_suppress
+= 2; /* Suppress this one and the next item */
4104 current
->expect
= EXPECT_OBJECT_VALUE
;
4108 case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO
: {
4112 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4117 n
= va_arg(ap
, const char *);
4118 u
= va_arg(ap
, uint64_t);
4120 if (u
!= 0 && current
->n_suppress
== 0) {
4121 r
= json_variant_new_string(&add
, n
);
4125 r
= json_variant_new_unsigned(&add_more
, u
);
4130 n_subtract
= 2; /* we generated two item */
4132 current
->expect
= EXPECT_OBJECT_KEY
;
4136 case _JSON_BUILD_PAIR_FINITE_USEC
: {
4140 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4145 n
= va_arg(ap
, const char *);
4146 u
= va_arg(ap
, usec_t
);
4148 if (u
!= USEC_INFINITY
&& current
->n_suppress
== 0) {
4149 r
= json_variant_new_string(&add
, n
);
4153 r
= json_variant_new_unsigned(&add_more
, u
);
4158 n_subtract
= 2; /* we generated two item */
4160 current
->expect
= EXPECT_OBJECT_KEY
;
4164 case _JSON_BUILD_PAIR_STRING_NON_EMPTY
: {
4167 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4172 n
= va_arg(ap
, const char *);
4173 s
= va_arg(ap
, const char *);
4175 if (!isempty(s
) && current
->n_suppress
== 0) {
4176 r
= json_variant_new_string(&add
, n
);
4180 r
= json_variant_new_string(&add_more
, s
);
4185 n_subtract
= 2; /* we generated two item */
4187 current
->expect
= EXPECT_OBJECT_KEY
;
4191 case _JSON_BUILD_PAIR_STRV_NON_EMPTY
: {
4195 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4200 n
= va_arg(ap
, const char *);
4201 l
= va_arg(ap
, char **);
4203 if (!strv_isempty(l
) && current
->n_suppress
== 0) {
4204 r
= json_variant_new_string(&add
, n
);
4208 r
= json_variant_new_array_strv(&add_more
, l
);
4213 n_subtract
= 2; /* we generated two item */
4215 current
->expect
= EXPECT_OBJECT_KEY
;
4219 case _JSON_BUILD_PAIR_VARIANT_NON_NULL
: {
4223 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4228 n
= va_arg(ap
, const char *);
4229 v
= va_arg(ap
, JsonVariant
*);
4231 if (v
&& !json_variant_is_null(v
) && current
->n_suppress
== 0) {
4232 r
= json_variant_new_string(&add
, n
);
4236 add_more
= json_variant_ref(v
);
4239 n_subtract
= 2; /* we generated two item */
4241 current
->expect
= EXPECT_OBJECT_KEY
;
4245 case _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL
: {
4246 const struct in_addr
*a
;
4249 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4254 n
= va_arg(ap
, const char *);
4255 a
= va_arg(ap
, const struct in_addr
*);
4257 if (a
&& in4_addr_is_set(a
) && current
->n_suppress
== 0) {
4258 r
= json_variant_new_string(&add
, n
);
4262 r
= json_variant_new_array_bytes(&add_more
, a
, sizeof(struct in_addr
));
4267 n_subtract
= 2; /* we generated two item */
4269 current
->expect
= EXPECT_OBJECT_KEY
;
4273 case _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL
: {
4274 const struct in6_addr
*a
;
4277 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4282 n
= va_arg(ap
, const char *);
4283 a
= va_arg(ap
, const struct in6_addr
*);
4285 if (a
&& in6_addr_is_set(a
) && current
->n_suppress
== 0) {
4286 r
= json_variant_new_string(&add
, n
);
4290 r
= json_variant_new_array_bytes(&add_more
, a
, sizeof(struct in6_addr
));
4295 n_subtract
= 2; /* we generated two item */
4297 current
->expect
= EXPECT_OBJECT_KEY
;
4301 case _JSON_BUILD_PAIR_IN_ADDR_NON_NULL
: {
4302 const union in_addr_union
*a
;
4306 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4311 n
= va_arg(ap
, const char *);
4312 a
= va_arg(ap
, const union in_addr_union
*);
4313 f
= va_arg(ap
, int);
4315 if (a
&& in_addr_is_set(f
, a
) && current
->n_suppress
== 0) {
4316 r
= json_variant_new_string(&add
, n
);
4320 r
= json_variant_new_array_bytes(&add_more
, a
->bytes
, FAMILY_ADDRESS_SIZE(f
));
4325 n_subtract
= 2; /* we generated two item */
4327 current
->expect
= EXPECT_OBJECT_KEY
;
4331 case _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL
: {
4332 const struct ether_addr
*a
;
4335 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4340 n
= va_arg(ap
, const char *);
4341 a
= va_arg(ap
, const struct ether_addr
*);
4343 if (a
&& !ether_addr_is_null(a
) && current
->n_suppress
== 0) {
4344 r
= json_variant_new_string(&add
, n
);
4348 r
= json_variant_new_array_bytes(&add_more
, a
->ether_addr_octet
, sizeof(struct ether_addr
));
4353 n_subtract
= 2; /* we generated two item */
4355 current
->expect
= EXPECT_OBJECT_KEY
;
4359 case _JSON_BUILD_PAIR_HW_ADDR_NON_NULL
: {
4360 const struct hw_addr_data
*a
;
4363 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4368 n
= va_arg(ap
, const char *);
4369 a
= va_arg(ap
, const struct hw_addr_data
*);
4371 if (a
&& !hw_addr_is_null(a
) && current
->n_suppress
== 0) {
4372 r
= json_variant_new_string(&add
, n
);
4376 r
= json_variant_new_array_bytes(&add_more
, a
->bytes
, a
->length
);
4381 n_subtract
= 2; /* we generated two item */
4383 current
->expect
= EXPECT_OBJECT_KEY
;
4388 /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */
4389 if (add
&& current
->n_suppress
== 0) {
4390 if (!GREEDY_REALLOC(current
->elements
, current
->n_elements
+ 1 + !!add_more
)) {
4395 current
->elements
[current
->n_elements
++] = TAKE_PTR(add
);
4397 current
->elements
[current
->n_elements
++] = TAKE_PTR(add_more
);
4400 /* If we are supposed to suppress items, let's subtract how many items where generated from
4401 * that counter. Except if the counter is SIZE_MAX, i.e. we shall suppress an infinite number
4402 * of elements on this stack level */
4403 if (current
->n_suppress
!= SIZE_MAX
) {
4404 if (current
->n_suppress
<= n_subtract
) /* Saturated */
4405 current
->n_suppress
= 0;
4407 current
->n_suppress
-= n_subtract
;
4412 assert(n_stack
== 1);
4413 assert(stack
[0].n_elements
== 1);
4415 *ret
= json_variant_ref(stack
[0].elements
[0]);
4419 for (size_t i
= 0; i
< n_stack
; i
++)
4420 json_stack_release(stack
+ i
);
4427 int json_build(JsonVariant
**ret
, ...) {
4432 r
= json_buildv(ret
, ap
);
4438 int json_log_internal(
4439 JsonVariant
*variant
,
4445 const char *format
, ...) {
4449 unsigned source_line
, source_column
;
4450 char buffer
[LINE_MAX
];
4455 errno
= ERRNO_VALUE(error
);
4457 va_start(ap
, format
);
4458 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
4462 r
= json_variant_get_source(variant
, &source
, &source_line
, &source_column
);
4471 if (source
&& source_line
> 0 && source_column
> 0)
4472 return log_struct_internal(
4476 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
4477 "CONFIG_FILE=%s", source
,
4478 "CONFIG_LINE=%u", source_line
,
4479 "CONFIG_COLUMN=%u", source_column
,
4480 LOG_MESSAGE("%s:%u:%u: %s", source
, source_line
, source_column
, buffer
),
4482 else if (source_line
> 0 && source_column
> 0)
4483 return log_struct_internal(
4487 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
4488 "CONFIG_LINE=%u", source_line
,
4489 "CONFIG_COLUMN=%u", source_column
,
4490 LOG_MESSAGE("(string):%u:%u: %s", source_line
, source_column
, buffer
),
4493 return log_struct_internal(
4497 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
4498 LOG_MESSAGE("%s", buffer
),
4502 static void *dispatch_userdata(const JsonDispatch
*p
, void *userdata
) {
4504 /* When the userdata pointer is passed in as NULL, then we'll just use the offset as a literal
4505 * address, and convert it to a pointer. Note that might as well just add the offset to the NULL
4506 * pointer, but UndefinedBehaviourSanitizer doesn't like pointer arithmetics based on NULL pointers,
4507 * hence we code this explicitly here. */
4510 return (uint8_t*) userdata
+ p
->offset
;
4512 return SIZE_TO_PTR(p
->offset
);
4515 int json_dispatch_full(
4517 const JsonDispatch table
[],
4518 JsonDispatchCallback bad
,
4519 JsonDispatchFlags flags
,
4521 const char **reterr_bad_field
) {
4526 if (!json_variant_is_object(v
)) {
4527 json_log(v
, flags
, 0, "JSON variant is not an object.");
4529 if (flags
& JSON_PERMISSIVE
)
4532 if (reterr_bad_field
)
4533 *reterr_bad_field
= NULL
;
4539 for (const JsonDispatch
*p
= table
; p
->name
; p
++)
4542 found
= newa0(bool, m
);
4544 size_t n
= json_variant_elements(v
);
4545 for (size_t i
= 0; i
< n
; i
+= 2) {
4546 JsonVariant
*key
, *value
;
4547 const JsonDispatch
*p
;
4549 assert_se(key
= json_variant_by_index(v
, i
));
4550 assert_se(value
= json_variant_by_index(v
, i
+1));
4552 for (p
= table
; p
->name
; p
++)
4553 if (p
->name
== POINTER_MAX
||
4554 streq_ptr(json_variant_string(key
), p
->name
))
4557 if (p
->name
) { /* Found a matching entry! 🙂 */
4558 JsonDispatchFlags merged_flags
;
4560 merged_flags
= flags
| p
->flags
;
4562 if (p
->type
!= _JSON_VARIANT_TYPE_INVALID
&&
4563 !json_variant_has_type(value
, p
->type
)) {
4565 json_log(value
, merged_flags
, 0,
4566 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key
),
4567 json_variant_type_to_string(json_variant_type(value
)), json_variant_type_to_string(p
->type
));
4569 if (merged_flags
& JSON_PERMISSIVE
)
4572 if (reterr_bad_field
)
4573 *reterr_bad_field
= p
->name
;
4578 if (found
[p
-table
]) {
4579 json_log(value
, merged_flags
, 0, "Duplicate object field '%s'.", json_variant_string(key
));
4581 if (merged_flags
& JSON_PERMISSIVE
)
4584 if (reterr_bad_field
)
4585 *reterr_bad_field
= p
->name
;
4590 found
[p
-table
] = true;
4593 r
= p
->callback(json_variant_string(key
), value
, merged_flags
, dispatch_userdata(p
, userdata
));
4595 if (merged_flags
& JSON_PERMISSIVE
)
4598 if (reterr_bad_field
)
4599 *reterr_bad_field
= json_variant_string(key
);
4607 } else { /* Didn't find a matching entry! ☹️ */
4610 r
= bad(json_variant_string(key
), value
, flags
, userdata
);
4612 if (flags
& JSON_PERMISSIVE
)
4615 if (reterr_bad_field
)
4616 *reterr_bad_field
= json_variant_string(key
);
4623 if (flags
& JSON_ALLOW_EXTENSIONS
) {
4624 json_log(value
, flags
, 0, "Unrecognized object field '%s', assuming extension.", json_variant_string(key
));
4628 json_log(value
, flags
, 0, "Unexpected object field '%s'.", json_variant_string(key
));
4629 if (flags
& JSON_PERMISSIVE
)
4632 if (reterr_bad_field
)
4633 *reterr_bad_field
= json_variant_string(key
);
4635 return -EADDRNOTAVAIL
;
4640 for (const JsonDispatch
*p
= table
; p
->name
; p
++) {
4641 JsonDispatchFlags merged_flags
= p
->flags
| flags
;
4643 if ((merged_flags
& JSON_MANDATORY
) && !found
[p
-table
]) {
4644 json_log(v
, merged_flags
, 0, "Missing object field '%s'.", p
->name
);
4646 if ((merged_flags
& JSON_PERMISSIVE
))
4649 if (reterr_bad_field
)
4650 *reterr_bad_field
= p
->name
;
4659 int json_dispatch_boolean(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4660 bool *b
= ASSERT_PTR(userdata
);
4664 if (!json_variant_is_boolean(variant
))
4665 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a boolean.", strna(name
));
4667 *b
= json_variant_boolean(variant
);
4671 int json_dispatch_tristate(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4672 int *b
= ASSERT_PTR(userdata
);
4676 if (json_variant_is_null(variant
)) {
4681 if (!json_variant_is_boolean(variant
))
4682 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a boolean.", strna(name
));
4684 *b
= json_variant_boolean(variant
);
4688 int json_dispatch_int64(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4689 int64_t *i
= ASSERT_PTR(userdata
);
4693 /* Also accept numbers formatted as string, to increase compatibility with less capable JSON
4694 * implementations that cannot do 64bit integers. */
4695 if (json_variant_is_string(variant
) && safe_atoi64(json_variant_string(variant
), i
) >= 0)
4698 if (!json_variant_is_integer(variant
))
4699 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an integer, nor one formatted as decimal string.", strna(name
));
4701 *i
= json_variant_integer(variant
);
4705 int json_dispatch_uint64(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4706 uint64_t *u
= ASSERT_PTR(userdata
);
4710 /* Since 64bit values (in particular unsigned ones) in JSON are problematic, let's also accept them
4711 * formatted as strings. If this is not desired make sure to set the .type field in JsonDispatch to
4712 * JSON_UNSIGNED rather than _JSON_VARIANT_TYPE_INVALID, so that json_dispatch() already filters out
4713 * the non-matching type. */
4715 if (json_variant_is_string(variant
) && safe_atou64(json_variant_string(variant
), u
) >= 0)
4718 if (!json_variant_is_unsigned(variant
))
4719 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an unsigned integer, nor one formatted as decimal string.", strna(name
));
4721 *u
= json_variant_unsigned(variant
);
4725 int json_dispatch_uint32(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4726 uint32_t *u
= ASSERT_PTR(userdata
);
4732 r
= json_dispatch_uint64(name
, variant
, flags
, &u64
);
4736 if (u64
> UINT32_MAX
)
4737 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4739 *u
= (uint32_t) u64
;
4743 int json_dispatch_int32(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4744 int32_t *i
= ASSERT_PTR(userdata
);
4750 r
= json_dispatch_int64(name
, variant
, flags
, &i64
);
4754 if (i64
< INT32_MIN
|| i64
> INT32_MAX
)
4755 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4761 int json_dispatch_int16(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4762 int16_t *i
= ASSERT_PTR(userdata
);
4768 r
= json_dispatch_int64(name
, variant
, flags
, &i64
);
4772 if (i64
< INT16_MIN
|| i64
> INT16_MAX
)
4773 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4779 int json_dispatch_uint16(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4780 uint16_t *u
= ASSERT_PTR(userdata
);
4786 r
= json_dispatch_uint64(name
, variant
, flags
, &u64
);
4790 if (u64
> UINT16_MAX
)
4791 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4793 *u
= (uint16_t) u64
;
4797 int json_dispatch_string(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4798 char **s
= ASSERT_PTR(userdata
);
4803 if (json_variant_is_null(variant
)) {
4808 if (!json_variant_is_string(variant
))
4809 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4811 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4812 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4814 r
= free_and_strdup(s
, json_variant_string(variant
));
4816 return json_log(variant
, flags
, r
, "Failed to allocate string: %m");
4821 int json_dispatch_const_string(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4822 const char **s
= ASSERT_PTR(userdata
);
4826 if (json_variant_is_null(variant
)) {
4831 if (!json_variant_is_string(variant
))
4832 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4834 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4835 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4837 *s
= json_variant_string(variant
);
4841 int json_dispatch_strv(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4842 _cleanup_strv_free_
char **l
= NULL
;
4843 char ***s
= ASSERT_PTR(userdata
);
4849 if (json_variant_is_null(variant
)) {
4854 /* Let's be flexible here: accept a single string in place of a single-item array */
4855 if (json_variant_is_string(variant
)) {
4856 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4857 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4859 l
= strv_new(json_variant_string(variant
));
4863 strv_free_and_replace(*s
, l
);
4867 if (!json_variant_is_array(variant
))
4868 return json_log(variant
, SYNTHETIC_ERRNO(EINVAL
), flags
, "JSON field '%s' is not an array.", strna(name
));
4870 JSON_VARIANT_ARRAY_FOREACH(e
, variant
) {
4871 if (!json_variant_is_string(e
))
4872 return json_log(e
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON array element is not a string.");
4874 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(e
)))
4875 return json_log(e
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4877 r
= strv_extend(&l
, json_variant_string(e
));
4879 return json_log(e
, flags
, r
, "Failed to append array element: %m");
4882 strv_free_and_replace(*s
, l
);
4886 int json_dispatch_variant(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4887 JsonVariant
**p
= ASSERT_PTR(userdata
);
4890 /* Takes a reference */
4891 JSON_VARIANT_REPLACE(*p
, json_variant_ref(variant
));
4895 int json_dispatch_variant_noref(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4896 JsonVariant
**p
= ASSERT_PTR(userdata
);
4899 /* Doesn't take a reference */
4904 int json_dispatch_uid_gid(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4905 uid_t
*uid
= userdata
;
4908 assert_cc(sizeof(uid_t
) == sizeof(uint32_t));
4909 assert_cc(sizeof(gid_t
) == sizeof(uint32_t));
4911 DISABLE_WARNING_TYPE_LIMITS
;
4912 assert_cc((UID_INVALID
< (uid_t
) 0) == (GID_INVALID
< (gid_t
) 0));
4915 if (json_variant_is_null(variant
)) {
4920 if (!json_variant_is_unsigned(variant
))
4921 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an integer.", strna(name
));
4923 k
= json_variant_unsigned(variant
);
4924 if (k
> UINT32_MAX
|| !uid_is_valid(k
))
4925 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid UID/GID.", strna(name
));
4931 int json_dispatch_user_group_name(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4932 char **s
= userdata
;
4936 if (json_variant_is_null(variant
)) {
4941 if (!json_variant_is_string(variant
))
4942 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4944 n
= json_variant_string(variant
);
4945 if (!valid_user_group_name(n
, FLAGS_SET(flags
, JSON_RELAX
) ? VALID_USER_RELAX
: 0))
4946 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid user/group name.", strna(name
));
4948 r
= free_and_strdup(s
, n
);
4950 return json_log(variant
, flags
, r
, "Failed to allocate string: %m");
4955 int json_dispatch_id128(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4956 sd_id128_t
*uuid
= userdata
;
4959 if (json_variant_is_null(variant
)) {
4960 *uuid
= SD_ID128_NULL
;
4964 if (!json_variant_is_string(variant
))
4965 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4967 r
= sd_id128_from_string(json_variant_string(variant
), uuid
);
4969 return json_log(variant
, flags
, r
, "JSON field '%s' is not a valid UID.", strna(name
));
4974 int json_dispatch_unsupported(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4975 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not allowed in this object.", strna(name
));
4978 int json_dispatch_unbase64_iovec(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4979 _cleanup_free_
void *buffer
= NULL
;
4980 struct iovec
*iov
= ASSERT_PTR(userdata
);
4984 if (!json_variant_is_string(variant
))
4985 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4987 r
= json_variant_unbase64(variant
, &buffer
, &sz
);
4989 return json_log(variant
, flags
, r
, "JSON field '%s' is not valid Base64 data.", strna(name
));
4991 free_and_replace(iov
->iov_base
, buffer
);
4996 static int json_cmp_strings(const void *x
, const void *y
) {
4997 JsonVariant
*const *a
= x
, *const *b
= y
;
4999 if (!json_variant_is_string(*a
) || !json_variant_is_string(*b
))
5002 return strcmp(json_variant_string(*a
), json_variant_string(*b
));
5005 int json_variant_sort(JsonVariant
**v
) {
5006 _cleanup_free_ JsonVariant
**a
= NULL
;
5007 _cleanup_(json_variant_unrefp
) JsonVariant
*n
= NULL
;
5013 if (json_variant_is_sorted(*v
))
5016 if (!json_variant_is_object(*v
))
5017 return -EMEDIUMTYPE
;
5019 /* Sorts they key/value pairs in an object variant */
5021 m
= json_variant_elements(*v
);
5022 a
= new(JsonVariant
*, m
);
5026 for (size_t i
= 0; i
< m
; i
++)
5027 a
[i
] = json_variant_by_index(*v
, i
);
5029 qsort(a
, m
/2, sizeof(JsonVariant
*)*2, json_cmp_strings
);
5031 r
= json_variant_new_object(&n
, a
, m
);
5035 json_variant_propagate_sensitive(*v
, n
);
5037 if (!n
->sorted
) /* Check if this worked. This will fail if there are multiple identical keys used. */
5040 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(n
));
5045 int json_variant_normalize(JsonVariant
**v
) {
5046 _cleanup_free_ JsonVariant
**a
= NULL
;
5047 _cleanup_(json_variant_unrefp
) JsonVariant
*n
= NULL
;
5053 if (json_variant_is_normalized(*v
))
5056 if (!json_variant_is_object(*v
) && !json_variant_is_array(*v
))
5057 return -EMEDIUMTYPE
;
5059 /* Sorts the key/value pairs in an object variant anywhere down the tree in the specified variant */
5061 m
= json_variant_elements(*v
);
5062 a
= new(JsonVariant
*, m
);
5066 for (i
= 0; i
< m
; ) {
5067 a
[i
] = json_variant_ref(json_variant_by_index(*v
, i
));
5070 r
= json_variant_normalize(&a
[i
-1]);
5075 qsort(a
, m
/2, sizeof(JsonVariant
*)*2, json_cmp_strings
);
5077 if (json_variant_is_object(*v
))
5078 r
= json_variant_new_object(&n
, a
, m
);
5080 assert(json_variant_is_array(*v
));
5081 r
= json_variant_new_array(&n
, a
, m
);
5086 json_variant_propagate_sensitive(*v
, n
);
5088 if (!n
->normalized
) { /* Let's see if normalization worked. It will fail if there are multiple
5089 * identical keys used in the same object anywhere, or if there are floating
5090 * point numbers used (see below) */
5095 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(n
));
5100 for (size_t j
= 0; j
< i
; j
++)
5101 json_variant_unref(a
[j
]);
5106 bool json_variant_is_normalized(JsonVariant
*v
) {
5107 /* For now, let's consider anything containing numbers not expressible as integers as non-normalized.
5108 * That's because we cannot sensibly compare them due to accuracy issues, nor even store them if they
5110 if (json_variant_is_real(v
) && !json_variant_is_integer(v
) && !json_variant_is_unsigned(v
))
5113 /* The concept only applies to variants that include other variants, i.e. objects and arrays. All
5114 * others are normalized anyway. */
5115 if (!json_variant_is_object(v
) && !json_variant_is_array(v
))
5118 /* Empty objects/arrays don't include any other variant, hence are always normalized too */
5119 if (json_variant_elements(v
) == 0)
5122 return v
->normalized
; /* For everything else there's an explicit boolean we maintain */
5125 bool json_variant_is_sorted(JsonVariant
*v
) {
5127 /* Returns true if all key/value pairs of an object are properly sorted. Note that this only applies
5128 * to objects, not arrays. */
5130 if (!json_variant_is_object(v
))
5132 if (json_variant_elements(v
) <= 1)
5138 int json_variant_unbase64(JsonVariant
*v
, void **ret
, size_t *ret_size
) {
5139 if (!json_variant_is_string(v
))
5142 return unbase64mem(json_variant_string(v
), ret
, ret_size
);
5145 int json_variant_unhex(JsonVariant
*v
, void **ret
, size_t *ret_size
) {
5146 if (!json_variant_is_string(v
))
5149 return unhexmem(json_variant_string(v
), ret
, ret_size
);
5152 static const char* const json_variant_type_table
[_JSON_VARIANT_TYPE_MAX
] = {
5153 [JSON_VARIANT_STRING
] = "string",
5154 [JSON_VARIANT_INTEGER
] = "integer",
5155 [JSON_VARIANT_UNSIGNED
] = "unsigned",
5156 [JSON_VARIANT_REAL
] = "real",
5157 [JSON_VARIANT_NUMBER
] = "number",
5158 [JSON_VARIANT_BOOLEAN
] = "boolean",
5159 [JSON_VARIANT_ARRAY
] = "array",
5160 [JSON_VARIANT_OBJECT
] = "object",
5161 [JSON_VARIANT_NULL
] = "null",
5164 DEFINE_STRING_TABLE_LOOKUP(json_variant_type
, JsonVariantType
);