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 "glyph-util.h"
18 #include "hexdecoct.h"
19 #include "iovec-util.h"
20 #include "json-internal.h"
23 #include "math-util.h"
24 #include "memory-util.h"
25 #include "memstream-util.h"
26 #include "path-util.h"
28 #include "string-table.h"
29 #include "string-util.h"
31 #include "terminal-util.h"
32 #include "user-util.h"
35 /* Refuse putting together variants with a larger depth than 2K by default (as a protection against overflowing stacks
36 * if code processes JSON objects recursively. Note that we store the depth in an uint16_t, hence make sure this
39 * The value first was 16k, but it was discovered to be too high on llvm/x86-64. See also:
40 * https://github.com/systemd/systemd/issues/10738
42 * The value then was 4k, but it was discovered to be too high on s390x/aarch64. See also:
43 * https://github.com/systemd/systemd/issues/14396 */
45 #define DEPTH_MAX (2U*1024U)
46 assert_cc(DEPTH_MAX
<= UINT16_MAX
);
48 typedef struct JsonSource
{
49 /* When we parse from a file or similar, encodes the filename, to indicate the source of a json variant */
56 /* On x86-64 this whole structure should have a size of 6 * 64 bit = 48 bytes */
59 /* We either maintain a reference counter for this variant itself, or we are embedded into an
60 * array/object, in which case only that surrounding object is ref-counted. (If 'embedded' is false,
64 /* If this JsonVariant is part of an array/object, then this field points to the surrounding
65 * JSON_VARIANT_ARRAY/JSON_VARIANT_OBJECT object. (If 'embedded' is true, see below.) */
69 /* If this was parsed from some file or buffer, this stores where from, as well as the source line/column */
71 unsigned line
, column
;
73 /* The current 'depth' of the JsonVariant, i.e. how many levels of member variants this has */
76 JsonVariantType type
:8;
78 /* A marker whether this variant is embedded into in array/object or not. If true, the 'parent' pointer above
79 * is valid. If false, the 'n_ref' field above is valid instead. */
82 /* In some conditions (for example, if this object is part of an array of strings or objects), we don't store
83 * any data inline, but instead simply reference an external object and act as surrogate of it. In that case
84 * this bool is set, and the external object is referenced through the .reference field below. */
87 /* While comparing two arrays, we use this for marking what we already have seen */
90 /* Erase from memory when freeing */
93 /* True if we know that any referenced json object is marked sensitive */
94 bool recursive_sensitive
:1;
96 /* If this is an object the fields are strictly ordered by name */
99 /* If in addition to this object all objects referenced by it are also ordered strictly by name */
103 /* For simple types we store the value in-line. */
106 /* For objects and arrays we store the number of elements immediately following */
109 /* If is_reference as indicated above is set, this is where the reference object is actually stored. */
110 JsonVariant
*reference
;
112 /* Strings are placed immediately after the structure. Note that when this is a JsonVariant
113 * embedded into an array we might encode strings up to INLINE_STRING_LENGTH characters
114 * directly inside the element, while longer strings are stored as references. When this
115 * object is not embedded into an array, but stand-alone, we allocate the right size for the
116 * whole structure, i.e. the array might be much larger than INLINE_STRING_LENGTH. */
117 DECLARE_FLEX_ARRAY(char, string
);
121 /* Inside string arrays we have a series of JsonVariant structures one after the other. In this case, strings longer
122 * than INLINE_STRING_MAX are stored as references, and all shorter ones inline. (This means — on x86-64 — strings up
123 * to 7 chars are stored within the array elements, and all others in separate allocations) */
124 #define INLINE_STRING_MAX (sizeof(JsonVariant) - offsetof(JsonVariant, string) - 1U)
126 /* Let's make sure this structure isn't increased in size accidentally. This check is only for our most relevant arch
128 #if defined(__x86_64__) && __SIZEOF_POINTER__ == 8
129 assert_cc(sizeof(JsonVariant
) == 40U);
130 assert_cc(INLINE_STRING_MAX
== 7U);
133 static JsonSource
* json_source_new(const char *name
) {
138 s
= malloc(offsetof(JsonSource
, name
) + strlen(name
) + 1);
145 strcpy(s
->name
, name
);
150 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(JsonSource
, json_source
, mfree
);
152 static bool json_source_equal(JsonSource
*a
, JsonSource
*b
) {
159 return streq(a
->name
, b
->name
);
162 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonSource
*, json_source_unref
);
164 /* There are four kind of JsonVariant* pointers:
167 * 2. A 'regular' one, i.e. pointing to malloc() memory
168 * 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.
169 * 4. A 'const string' one, i.e. a pointer to a const string.
171 * The four kinds of pointers can be discerned like this:
173 * Detecting #1 is easy, just compare with NULL. Detecting #3 is similarly easy: all magic pointers are below
174 * _JSON_VARIANT_MAGIC_MAX (which is pretty low, within the first memory page, which is special on Linux and other
175 * 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,
176 * otherwise #4. This makes use of the fact that malloc() will return "maximum aligned" memory, which definitely
177 * means the pointer is even. This means we can use the uneven pointers to reference static strings, as long as we
178 * make sure that all static strings used like this are aligned to 2 (or higher), and that we mask the bit on
179 * access. The JSON_VARIANT_STRING_CONST() macro encodes strings as JsonVariant* pointers, with the bit set. */
181 static bool json_variant_is_magic(const JsonVariant
*v
) {
185 return v
< _JSON_VARIANT_MAGIC_MAX
;
188 static bool json_variant_is_const_string(const JsonVariant
*v
) {
190 if (v
< _JSON_VARIANT_MAGIC_MAX
)
193 /* A proper JsonVariant is aligned to whatever malloc() aligns things too, which is definitely not uneven. We
194 * hence use all uneven pointers as indicators for const strings. */
196 return (((uintptr_t) v
) & 1) != 0;
199 static bool json_variant_is_regular(const JsonVariant
*v
) {
201 if (v
< _JSON_VARIANT_MAGIC_MAX
)
204 return (((uintptr_t) v
) & 1) == 0;
207 static JsonVariant
*json_variant_dereference(JsonVariant
*v
) {
209 /* Recursively dereference variants that are references to other variants */
214 if (!json_variant_is_regular(v
))
217 if (!v
->is_reference
)
220 return json_variant_dereference(v
->reference
);
223 static uint16_t json_variant_depth(JsonVariant
*v
) {
225 v
= json_variant_dereference(v
);
229 if (!json_variant_is_regular(v
))
235 static JsonVariant
*json_variant_formalize(JsonVariant
*v
) {
237 /* Converts json variant pointers to their normalized form, i.e. fully dereferenced and wherever
238 * possible converted to the "magic" version if there is one */
243 v
= json_variant_dereference(v
);
245 switch (json_variant_type(v
)) {
247 case JSON_VARIANT_BOOLEAN
:
248 return json_variant_boolean(v
) ? JSON_VARIANT_MAGIC_TRUE
: JSON_VARIANT_MAGIC_FALSE
;
250 case JSON_VARIANT_NULL
:
251 return JSON_VARIANT_MAGIC_NULL
;
253 case JSON_VARIANT_INTEGER
:
254 return json_variant_integer(v
) == 0 ? JSON_VARIANT_MAGIC_ZERO_INTEGER
: v
;
256 case JSON_VARIANT_UNSIGNED
:
257 return json_variant_unsigned(v
) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED
: v
;
259 case JSON_VARIANT_REAL
:
260 return iszero_safe(json_variant_real(v
)) ? JSON_VARIANT_MAGIC_ZERO_REAL
: v
;
262 case JSON_VARIANT_STRING
:
263 return isempty(json_variant_string(v
)) ? JSON_VARIANT_MAGIC_EMPTY_STRING
: v
;
265 case JSON_VARIANT_ARRAY
:
266 return json_variant_elements(v
) == 0 ? JSON_VARIANT_MAGIC_EMPTY_ARRAY
: v
;
268 case JSON_VARIANT_OBJECT
:
269 return json_variant_elements(v
) == 0 ? JSON_VARIANT_MAGIC_EMPTY_OBJECT
: v
;
276 static JsonVariant
*json_variant_conservative_formalize(JsonVariant
*v
) {
278 /* Much like json_variant_formalize(), but won't simplify if the variant has a source/line location
279 * attached to it, in order not to lose context */
284 if (!json_variant_is_regular(v
))
287 if (v
->source
|| v
->line
> 0 || v
->column
> 0)
290 return json_variant_formalize(v
);
293 static int json_variant_new(JsonVariant
**ret
, JsonVariantType type
, size_t space
) {
296 assert_return(ret
, -EINVAL
);
298 v
= malloc0(MAX(sizeof(JsonVariant
),
299 offsetof(JsonVariant
, value
) + space
));
310 int json_variant_new_integer(JsonVariant
**ret
, int64_t i
) {
314 assert_return(ret
, -EINVAL
);
317 *ret
= JSON_VARIANT_MAGIC_ZERO_INTEGER
;
321 r
= json_variant_new(&v
, JSON_VARIANT_INTEGER
, sizeof(i
));
325 v
->value
.integer
= i
;
331 int json_variant_new_unsigned(JsonVariant
**ret
, uint64_t u
) {
335 assert_return(ret
, -EINVAL
);
337 *ret
= JSON_VARIANT_MAGIC_ZERO_UNSIGNED
;
341 r
= json_variant_new(&v
, JSON_VARIANT_UNSIGNED
, sizeof(u
));
351 int json_variant_new_real(JsonVariant
**ret
, double d
) {
355 assert_return(ret
, -EINVAL
);
361 /* JSON doesn't know NaN, +Infinity or -Infinity. Let's silently convert to 'null'. */
362 *ret
= JSON_VARIANT_MAGIC_NULL
;
366 *ret
= JSON_VARIANT_MAGIC_ZERO_REAL
;
370 r
= json_variant_new(&v
, JSON_VARIANT_REAL
, sizeof(d
));
380 int json_variant_new_boolean(JsonVariant
**ret
, bool b
) {
381 assert_return(ret
, -EINVAL
);
384 *ret
= JSON_VARIANT_MAGIC_TRUE
;
386 *ret
= JSON_VARIANT_MAGIC_FALSE
;
391 int json_variant_new_null(JsonVariant
**ret
) {
392 assert_return(ret
, -EINVAL
);
394 *ret
= JSON_VARIANT_MAGIC_NULL
;
398 int json_variant_new_stringn(JsonVariant
**ret
, const char *s
, size_t n
) {
402 assert_return(ret
, -EINVAL
);
404 assert_return(IN_SET(n
, 0, SIZE_MAX
), -EINVAL
);
405 return json_variant_new_null(ret
);
407 if (n
== SIZE_MAX
) /* determine length automatically */
409 else if (memchr(s
, 0, n
)) /* don't allow embedded NUL, as we can't express that in JSON */
412 *ret
= JSON_VARIANT_MAGIC_EMPTY_STRING
;
416 if (!utf8_is_valid_n(s
, n
)) /* JSON strings must be valid UTF-8 */
419 r
= json_variant_new(&v
, JSON_VARIANT_STRING
, n
+ 1);
423 memcpy(v
->string
, s
, n
);
430 int json_variant_new_base64(JsonVariant
**ret
, const void *p
, size_t n
) {
431 _cleanup_free_
char *s
= NULL
;
434 assert_return(ret
, -EINVAL
);
435 assert_return(n
== 0 || p
, -EINVAL
);
437 k
= base64mem(p
, n
, &s
);
441 return json_variant_new_stringn(ret
, s
, k
);
444 int json_variant_new_base32hex(JsonVariant
**ret
, const void *p
, size_t n
) {
445 _cleanup_free_
char *s
= NULL
;
447 assert_return(ret
, -EINVAL
);
448 assert_return(n
== 0 || p
, -EINVAL
);
450 s
= base32hexmem(p
, n
, false);
454 return json_variant_new_string(ret
, s
);
457 int json_variant_new_hex(JsonVariant
**ret
, const void *p
, size_t n
) {
458 _cleanup_free_
char *s
= NULL
;
460 assert_return(ret
, -EINVAL
);
461 assert_return(n
== 0 || p
, -EINVAL
);
467 return json_variant_new_stringn(ret
, s
, n
*2);
470 int json_variant_new_octescape(JsonVariant
**ret
, const void *p
, size_t n
) {
471 _cleanup_free_
char *s
= NULL
;
473 assert_return(ret
, -EINVAL
);
474 assert_return(n
== 0 || p
, -EINVAL
);
480 return json_variant_new_string(ret
, s
);
483 int json_variant_new_id128(JsonVariant
**ret
, sd_id128_t id
) {
484 return json_variant_new_string(ret
, SD_ID128_TO_STRING(id
));
487 int json_variant_new_uuid(JsonVariant
**ret
, sd_id128_t id
) {
488 return json_variant_new_string(ret
, SD_ID128_TO_UUID_STRING(id
));
491 static void json_variant_set(JsonVariant
*a
, JsonVariant
*b
) {
494 b
= json_variant_dereference(b
);
496 a
->type
= JSON_VARIANT_NULL
;
500 a
->type
= json_variant_type(b
);
503 case JSON_VARIANT_INTEGER
:
504 a
->value
.integer
= json_variant_integer(b
);
507 case JSON_VARIANT_UNSIGNED
:
508 a
->value
.unsig
= json_variant_unsigned(b
);
511 case JSON_VARIANT_REAL
:
512 a
->value
.real
= json_variant_real(b
);
515 case JSON_VARIANT_BOOLEAN
:
516 a
->value
.boolean
= json_variant_boolean(b
);
519 case JSON_VARIANT_STRING
: {
522 assert_se(s
= json_variant_string(b
));
524 /* Short strings we can store inline */
525 if (strnlen(s
, INLINE_STRING_MAX
+1) <= INLINE_STRING_MAX
) {
526 strcpy(a
->string
, s
);
530 /* For longer strings, use a reference… */
534 case JSON_VARIANT_ARRAY
:
535 case JSON_VARIANT_OBJECT
:
536 a
->is_reference
= true;
537 a
->reference
= json_variant_ref(json_variant_conservative_formalize(b
));
540 case JSON_VARIANT_NULL
:
544 assert_not_reached();
548 static void json_variant_copy_source(JsonVariant
*v
, JsonVariant
*from
) {
551 if (!json_variant_is_regular(from
))
554 v
->line
= from
->line
;
555 v
->column
= from
->column
;
556 v
->source
= json_source_ref(from
->source
);
559 static int _json_variant_array_put_element(JsonVariant
*array
, JsonVariant
*element
) {
561 JsonVariant
*w
= array
+ 1 + array
->n_elements
;
563 uint16_t d
= json_variant_depth(element
);
564 if (d
>= DEPTH_MAX
) /* Refuse too deep nesting */
566 if (d
>= array
->depth
)
567 array
->depth
= d
+ 1;
575 json_variant_set(w
, element
);
576 json_variant_copy_source(w
, element
);
578 if (!json_variant_is_normalized(element
))
579 array
->normalized
= false;
584 int json_variant_new_array(JsonVariant
**ret
, JsonVariant
**array
, size_t n
) {
585 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
588 assert_return(ret
, -EINVAL
);
590 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
593 assert_return(array
, -EINVAL
);
595 v
= new(JsonVariant
, n
+ 1);
601 .type
= JSON_VARIANT_ARRAY
,
605 while (v
->n_elements
< n
) {
606 r
= _json_variant_array_put_element(v
, array
[v
->n_elements
]);
615 int json_variant_new_array_bytes(JsonVariant
**ret
, const void *p
, size_t n
) {
616 assert_return(ret
, -EINVAL
);
618 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
621 assert_return(p
, -EINVAL
);
623 JsonVariant
*v
= new(JsonVariant
, n
+ 1);
629 .type
= JSON_VARIANT_ARRAY
,
634 for (size_t i
= 0; i
< n
; i
++) {
635 JsonVariant
*w
= v
+ 1 + i
;
640 .type
= JSON_VARIANT_UNSIGNED
,
641 .value
.unsig
= ((const uint8_t*) p
)[i
],
645 v
->normalized
= true;
651 int json_variant_new_array_strv(JsonVariant
**ret
, char **l
) {
652 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
660 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
664 v
= new(JsonVariant
, n
+ 1);
670 .type
= JSON_VARIANT_ARRAY
,
674 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
675 JsonVariant
*w
= v
+ 1 + v
->n_elements
;
681 .type
= JSON_VARIANT_STRING
,
684 k
= strlen(l
[v
->n_elements
]);
686 if (k
> INLINE_STRING_MAX
) {
687 /* If string is too long, store it as reference. */
689 r
= json_variant_new_string(&w
->reference
, l
[v
->n_elements
]);
693 w
->is_reference
= true;
695 if (!utf8_is_valid_n(l
[v
->n_elements
], k
)) /* JSON strings must be valid UTF-8 */
698 memcpy(w
->string
, l
[v
->n_elements
], k
+1);
702 v
->normalized
= true;
708 int json_variant_new_object(JsonVariant
**ret
, JsonVariant
**array
, size_t n
) {
709 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
710 const char *prev
= NULL
;
711 bool sorted
= true, normalized
= true;
713 assert_return(ret
, -EINVAL
);
715 *ret
= JSON_VARIANT_MAGIC_EMPTY_OBJECT
;
718 assert_return(array
, -EINVAL
);
719 assert_return(n
% 2 == 0, -EINVAL
);
721 v
= new(JsonVariant
, n
+ 1);
727 .type
= JSON_VARIANT_OBJECT
,
730 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
731 JsonVariant
*w
= v
+ 1 + v
->n_elements
,
732 *c
= array
[v
->n_elements
];
735 if ((v
->n_elements
& 1) == 0) {
738 if (!json_variant_is_string(c
))
739 return -EINVAL
; /* Every second one needs to be a string, as it is the key name */
741 assert_se(k
= json_variant_string(c
));
743 if (prev
&& strcmp(k
, prev
) <= 0)
744 sorted
= normalized
= false;
747 } else if (!json_variant_is_normalized(c
))
750 d
= json_variant_depth(c
);
751 if (d
>= DEPTH_MAX
) /* Refuse too deep nesting */
761 json_variant_set(w
, c
);
762 json_variant_copy_source(w
, c
);
765 v
->normalized
= normalized
;
772 static size_t json_variant_size(JsonVariant
* v
) {
773 if (!json_variant_is_regular(v
))
777 return offsetof(JsonVariant
, reference
) + sizeof(JsonVariant
*);
781 case JSON_VARIANT_STRING
:
782 return offsetof(JsonVariant
, string
) + strlen(v
->string
) + 1;
784 case JSON_VARIANT_REAL
:
785 return offsetof(JsonVariant
, value
) + sizeof(double);
787 case JSON_VARIANT_UNSIGNED
:
788 return offsetof(JsonVariant
, value
) + sizeof(uint64_t);
790 case JSON_VARIANT_INTEGER
:
791 return offsetof(JsonVariant
, value
) + sizeof(int64_t);
793 case JSON_VARIANT_BOOLEAN
:
794 return offsetof(JsonVariant
, value
) + sizeof(bool);
796 case JSON_VARIANT_ARRAY
:
797 case JSON_VARIANT_OBJECT
:
798 return offsetof(JsonVariant
, n_elements
) + sizeof(size_t);
800 case JSON_VARIANT_NULL
:
801 return offsetof(JsonVariant
, value
);
804 assert_not_reached();
808 static void json_variant_free_inner(JsonVariant
*v
, bool force_sensitive
) {
813 if (!json_variant_is_regular(v
))
816 json_source_unref(v
->source
);
818 sensitive
= v
->sensitive
|| force_sensitive
;
820 if (v
->is_reference
) {
822 json_variant_sensitive(v
->reference
);
824 json_variant_unref(v
->reference
);
828 if (IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
829 for (size_t i
= 0; i
< v
->n_elements
; i
++)
830 json_variant_free_inner(v
+ 1 + i
, sensitive
);
833 explicit_bzero_safe(v
, json_variant_size(v
));
836 static unsigned json_variant_n_ref(const JsonVariant
*v
) {
837 /* Return the number of references to v.
838 * 0 => NULL or not a regular object or embedded.
839 * >0 => number of references
842 if (!v
|| !json_variant_is_regular(v
) || v
->is_embedded
)
845 assert(v
->n_ref
> 0);
849 JsonVariant
*json_variant_ref(JsonVariant
*v
) {
852 if (!json_variant_is_regular(v
))
856 json_variant_ref(v
->parent
); /* ref the compounding variant instead */
858 assert(v
->n_ref
> 0);
865 JsonVariant
*json_variant_unref(JsonVariant
*v
) {
868 if (!json_variant_is_regular(v
))
872 json_variant_unref(v
->parent
);
874 assert(v
->n_ref
> 0);
878 json_variant_free_inner(v
, false);
886 void json_variant_unref_many(JsonVariant
**array
, size_t n
) {
887 assert(array
|| n
== 0);
889 for (size_t i
= 0; i
< n
; i
++)
890 json_variant_unref(array
[i
]);
895 const char *json_variant_string(JsonVariant
*v
) {
898 if (v
== JSON_VARIANT_MAGIC_EMPTY_STRING
)
900 if (json_variant_is_magic(v
))
902 if (json_variant_is_const_string(v
)) {
903 uintptr_t p
= (uintptr_t) v
;
905 assert((p
& 1) != 0);
906 return (const char*) (p
^ 1U);
910 return json_variant_string(v
->reference
);
911 if (v
->type
!= JSON_VARIANT_STRING
)
917 log_debug("Non-string JSON variant requested as string, returning NULL.");
921 bool json_variant_boolean(JsonVariant
*v
) {
924 if (v
== JSON_VARIANT_MAGIC_TRUE
)
926 if (v
== JSON_VARIANT_MAGIC_FALSE
)
928 if (!json_variant_is_regular(v
))
930 if (v
->type
!= JSON_VARIANT_BOOLEAN
)
933 return json_variant_boolean(v
->reference
);
935 return v
->value
.boolean
;
938 log_debug("Non-boolean JSON variant requested as boolean, returning false.");
942 int64_t json_variant_integer(JsonVariant
*v
) {
945 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
946 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
947 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
949 if (!json_variant_is_regular(v
))
952 return json_variant_integer(v
->reference
);
956 case JSON_VARIANT_INTEGER
:
957 return v
->value
.integer
;
959 case JSON_VARIANT_UNSIGNED
:
960 if (v
->value
.unsig
<= INT64_MAX
)
961 return (int64_t) v
->value
.unsig
;
963 log_debug("Unsigned integer %" PRIu64
" requested as signed integer and out of range, returning 0.", v
->value
.unsig
);
966 case JSON_VARIANT_REAL
: {
969 converted
= (int64_t) v
->value
.real
;
971 if (fp_equal((double) converted
, v
->value
.real
))
974 log_debug("Real %g requested as integer, and cannot be converted losslessly, returning 0.", v
->value
.real
);
983 log_debug("Non-integer JSON variant requested as integer, returning 0.");
987 uint64_t json_variant_unsigned(JsonVariant
*v
) {
990 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
991 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
992 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
994 if (!json_variant_is_regular(v
))
997 return json_variant_integer(v
->reference
);
1001 case JSON_VARIANT_INTEGER
:
1002 if (v
->value
.integer
>= 0)
1003 return (uint64_t) v
->value
.integer
;
1005 log_debug("Signed integer %" PRIi64
" requested as unsigned integer and out of range, returning 0.", v
->value
.integer
);
1008 case JSON_VARIANT_UNSIGNED
:
1009 return v
->value
.unsig
;
1011 case JSON_VARIANT_REAL
: {
1014 converted
= (uint64_t) v
->value
.real
;
1016 if (fp_equal((double) converted
, v
->value
.real
))
1019 log_debug("Real %g requested as unsigned integer, and cannot be converted losslessly, returning 0.", v
->value
.real
);
1028 log_debug("Non-integer JSON variant requested as unsigned, returning 0.");
1032 double json_variant_real(JsonVariant
*v
) {
1035 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
1036 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
1037 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1039 if (!json_variant_is_regular(v
))
1041 if (v
->is_reference
)
1042 return json_variant_real(v
->reference
);
1046 case JSON_VARIANT_REAL
:
1047 return v
->value
.real
;
1049 case JSON_VARIANT_INTEGER
: {
1050 double converted
= (double) v
->value
.integer
;
1052 if ((int64_t) converted
== v
->value
.integer
)
1055 log_debug("Signed integer %" PRIi64
" requested as real, and cannot be converted losslessly, returning 0.", v
->value
.integer
);
1059 case JSON_VARIANT_UNSIGNED
: {
1060 double converted
= (double) v
->value
.unsig
;
1062 if ((uint64_t) converted
== v
->value
.unsig
)
1065 log_debug("Unsigned integer %" PRIu64
" requested as real, and cannot be converted losslessly, returning 0.", v
->value
.unsig
);
1074 log_debug("Non-integer JSON variant requested as integer, returning 0.");
1078 bool json_variant_is_negative(JsonVariant
*v
) {
1081 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
1082 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
1083 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1085 if (!json_variant_is_regular(v
))
1087 if (v
->is_reference
)
1088 return json_variant_is_negative(v
->reference
);
1090 /* This function is useful as checking whether numbers are negative is pretty complex since we have three types
1091 * of numbers. And some JSON code (OCI for example) uses negative numbers to mark "not defined" numeric
1096 case JSON_VARIANT_REAL
:
1097 return v
->value
.real
< 0;
1099 case JSON_VARIANT_INTEGER
:
1100 return v
->value
.integer
< 0;
1102 case JSON_VARIANT_UNSIGNED
:
1110 log_debug("Non-integer JSON variant tested for negativity, returning false.");
1114 bool json_variant_is_blank_object(JsonVariant
*v
) {
1115 /* Returns true if the specified object is null or empty */
1117 json_variant_is_null(v
) ||
1118 (json_variant_is_object(v
) && json_variant_elements(v
) == 0);
1121 bool json_variant_is_blank_array(JsonVariant
*v
) {
1123 json_variant_is_null(v
) ||
1124 (json_variant_is_array(v
) && json_variant_elements(v
) == 0);
1127 JsonVariantType
json_variant_type(JsonVariant
*v
) {
1130 return _JSON_VARIANT_TYPE_INVALID
;
1132 if (json_variant_is_const_string(v
))
1133 return JSON_VARIANT_STRING
;
1135 if (v
== JSON_VARIANT_MAGIC_TRUE
|| v
== JSON_VARIANT_MAGIC_FALSE
)
1136 return JSON_VARIANT_BOOLEAN
;
1138 if (v
== JSON_VARIANT_MAGIC_NULL
)
1139 return JSON_VARIANT_NULL
;
1141 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
)
1142 return JSON_VARIANT_INTEGER
;
1144 if (v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
)
1145 return JSON_VARIANT_UNSIGNED
;
1147 if (v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1148 return JSON_VARIANT_REAL
;
1150 if (v
== JSON_VARIANT_MAGIC_EMPTY_STRING
)
1151 return JSON_VARIANT_STRING
;
1153 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
)
1154 return JSON_VARIANT_ARRAY
;
1156 if (v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1157 return JSON_VARIANT_OBJECT
;
1162 _function_no_sanitize_float_cast_overflow_
1163 bool json_variant_has_type(JsonVariant
*v
, JsonVariantType type
) {
1166 /* Note: we turn off ubsan float cast overflow detection for this function, since it would complain
1167 * about our float casts but we do them explicitly to detect conversion errors. */
1169 v
= json_variant_dereference(v
);
1173 rt
= json_variant_type(v
);
1177 /* If it's a const string, then it only can be a string, and if it is not, it's not */
1178 if (json_variant_is_const_string(v
))
1181 /* All three magic zeroes qualify as integer, unsigned and as real */
1182 if ((v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
|| v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
|| v
== JSON_VARIANT_MAGIC_ZERO_REAL
) &&
1183 IN_SET(type
, JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
, JSON_VARIANT_NUMBER
))
1186 /* All other magic variant types are only equal to themselves */
1187 if (json_variant_is_magic(v
))
1190 /* Handle the "number" pseudo type */
1191 if (type
== JSON_VARIANT_NUMBER
)
1192 return IN_SET(rt
, JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
);
1194 /* Integer conversions are OK in many cases */
1195 if (rt
== JSON_VARIANT_INTEGER
&& type
== JSON_VARIANT_UNSIGNED
)
1196 return v
->value
.integer
>= 0;
1197 if (rt
== JSON_VARIANT_UNSIGNED
&& type
== JSON_VARIANT_INTEGER
)
1198 return v
->value
.unsig
<= INT64_MAX
;
1200 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1201 if (rt
== JSON_VARIANT_INTEGER
&& type
== JSON_VARIANT_REAL
)
1202 return (int64_t) (double) v
->value
.integer
== v
->value
.integer
;
1203 if (rt
== JSON_VARIANT_UNSIGNED
&& type
== JSON_VARIANT_REAL
)
1204 return (uint64_t) (double) v
->value
.unsig
== v
->value
.unsig
;
1206 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1207 if (rt
== JSON_VARIANT_REAL
&& type
== JSON_VARIANT_INTEGER
)
1208 return fp_equal((double) (int64_t) v
->value
.real
, v
->value
.real
);
1209 if (rt
== JSON_VARIANT_REAL
&& type
== JSON_VARIANT_UNSIGNED
)
1210 return fp_equal((double) (uint64_t) v
->value
.real
, v
->value
.real
);
1215 size_t json_variant_elements(JsonVariant
*v
) {
1218 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
||
1219 v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1221 if (!json_variant_is_regular(v
))
1223 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1225 if (v
->is_reference
)
1226 return json_variant_elements(v
->reference
);
1228 return v
->n_elements
;
1231 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1235 JsonVariant
*json_variant_by_index(JsonVariant
*v
, size_t idx
) {
1238 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
||
1239 v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1241 if (!json_variant_is_regular(v
))
1243 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1245 if (v
->is_reference
)
1246 return json_variant_by_index(v
->reference
, idx
);
1247 if (idx
>= v
->n_elements
)
1250 return json_variant_conservative_formalize(v
+ 1 + idx
);
1253 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1257 JsonVariant
*json_variant_by_key_full(JsonVariant
*v
, const char *key
, JsonVariant
**ret_key
) {
1262 if (v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1264 if (!json_variant_is_regular(v
))
1266 if (v
->type
!= JSON_VARIANT_OBJECT
)
1268 if (v
->is_reference
)
1269 return json_variant_by_key(v
->reference
, key
);
1272 size_t a
= 0, b
= v
->n_elements
/2;
1274 /* If the variant is sorted we can use bisection to find the entry we need in O(log(n)) time */
1283 p
= json_variant_dereference(v
+ 1 + i
*2);
1285 assert_se(f
= json_variant_string(p
));
1290 *ret_key
= json_variant_conservative_formalize(v
+ 1 + i
*2);
1292 return json_variant_conservative_formalize(v
+ 1 + i
*2 + 1);
1302 /* The variant is not sorted, hence search for the field linearly */
1303 for (size_t i
= 0; i
< v
->n_elements
; i
+= 2) {
1306 p
= json_variant_dereference(v
+ 1 + i
);
1308 if (!json_variant_has_type(p
, JSON_VARIANT_STRING
))
1311 if (streq(json_variant_string(p
), key
)) {
1314 *ret_key
= json_variant_conservative_formalize(v
+ 1 + i
);
1316 return json_variant_conservative_formalize(v
+ 1 + i
+ 1);
1327 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1334 JsonVariant
*json_variant_by_key(JsonVariant
*v
, const char *key
) {
1335 return json_variant_by_key_full(v
, key
, NULL
);
1338 bool json_variant_equal(JsonVariant
*a
, JsonVariant
*b
) {
1341 a
= json_variant_formalize(a
);
1342 b
= json_variant_formalize(b
);
1347 t
= json_variant_type(a
);
1348 if (!json_variant_has_type(b
, t
))
1353 case JSON_VARIANT_STRING
:
1354 return streq(json_variant_string(a
), json_variant_string(b
));
1356 case JSON_VARIANT_INTEGER
:
1357 return json_variant_integer(a
) == json_variant_integer(b
);
1359 case JSON_VARIANT_UNSIGNED
:
1360 return json_variant_unsigned(a
) == json_variant_unsigned(b
);
1362 case JSON_VARIANT_REAL
:
1363 return fp_equal(json_variant_real(a
), json_variant_real(b
));
1365 case JSON_VARIANT_BOOLEAN
:
1366 return json_variant_boolean(a
) == json_variant_boolean(b
);
1368 case JSON_VARIANT_NULL
:
1371 case JSON_VARIANT_ARRAY
: {
1372 size_t n
= json_variant_elements(a
);
1373 if (n
!= json_variant_elements(b
))
1376 for (size_t i
= 0; i
< n
; i
++)
1377 if (!json_variant_equal(json_variant_by_index(a
, i
), json_variant_by_index(b
, i
)))
1383 case JSON_VARIANT_OBJECT
: {
1384 size_t n
= json_variant_elements(a
);
1385 if (n
!= json_variant_elements(b
))
1388 /* Iterate through all keys in 'a' */
1389 for (size_t i
= 0; i
< n
; i
+= 2) {
1392 /* Match them against all keys in 'b' */
1393 for (size_t j
= 0; j
< n
; j
+= 2) {
1396 key_b
= json_variant_by_index(b
, j
);
1398 /* During the first iteration unmark everything */
1400 key_b
->is_marked
= false;
1401 else if (key_b
->is_marked
) /* In later iterations if we already marked something, don't bother with it again */
1407 if (json_variant_equal(json_variant_by_index(a
, i
), key_b
) &&
1408 json_variant_equal(json_variant_by_index(a
, i
+1), json_variant_by_index(b
, j
+1))) {
1409 /* Key and values match! */
1410 key_b
->is_marked
= found
= true;
1412 /* In the first iteration we continue the inner loop since we want to mark
1413 * everything, otherwise exit the loop quickly after we found what we were
1428 assert_not_reached();
1432 void json_variant_sensitive(JsonVariant
*v
) {
1435 /* Marks a variant as "sensitive", so that it is erased from memory when it is destroyed. This is a
1436 * one-way operation: as soon as it is marked this way it remains marked this way until it's
1437 * destroyed. A magic variant is never sensitive though, even when asked, since it's too
1438 * basic. Similar, const string variant are never sensitive either, after all they are included in
1439 * the source code as they are, which is not suitable for inclusion of secrets.
1441 * Note that this flag has a recursive effect: when we destroy an object or array we'll propagate the
1442 * flag to all contained variants. And if those are then destroyed this is propagated further down,
1445 v
= json_variant_formalize(v
);
1446 if (!json_variant_is_regular(v
))
1449 v
->sensitive
= true;
1452 bool json_variant_is_sensitive(JsonVariant
*v
) {
1453 v
= json_variant_formalize(v
);
1454 if (!json_variant_is_regular(v
))
1457 return v
->sensitive
;
1460 bool json_variant_is_sensitive_recursive(JsonVariant
*v
) {
1463 if (json_variant_is_sensitive(v
))
1465 if (!json_variant_is_regular(v
))
1467 if (v
->recursive_sensitive
) /* Already checked this before */
1469 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1471 if (v
->is_reference
) {
1472 if (!json_variant_is_sensitive_recursive(v
->reference
))
1475 return (v
->recursive_sensitive
= true);
1478 for (size_t i
= 0; i
< json_variant_elements(v
); i
++)
1479 if (json_variant_is_sensitive_recursive(json_variant_by_index(v
, i
)))
1480 return (v
->recursive_sensitive
= true);
1482 /* Note: we only cache the result here in case true, since we allow all elements down the tree to
1483 * have their sensitive flag toggled later on (but never off) */
1487 static void json_variant_propagate_sensitive(JsonVariant
*from
, JsonVariant
*to
) {
1488 if (json_variant_is_sensitive(from
))
1489 json_variant_sensitive(to
);
1492 int json_variant_get_source(JsonVariant
*v
, const char **ret_source
, unsigned *ret_line
, unsigned *ret_column
) {
1493 assert_return(v
, -EINVAL
);
1496 *ret_source
= json_variant_is_regular(v
) && v
->source
? v
->source
->name
: NULL
;
1499 *ret_line
= json_variant_is_regular(v
) ? v
->line
: 0;
1502 *ret_column
= json_variant_is_regular(v
) ? v
->column
: 0;
1507 static int print_source(FILE *f
, JsonVariant
*v
, JsonFormatFlags flags
, bool whitespace
) {
1510 if (!FLAGS_SET(flags
, JSON_FORMAT_SOURCE
|JSON_FORMAT_PRETTY
))
1513 if (!json_variant_is_regular(v
))
1516 if (!v
->source
&& v
->line
== 0 && v
->column
== 0)
1519 /* The max width we need to format the line numbers for this source file */
1520 w
= (v
->source
&& v
->source
->max_line
> 0) ?
1521 DECIMAL_STR_WIDTH(v
->source
->max_line
) :
1522 DECIMAL_STR_MAX(unsigned)-1;
1523 k
= (v
->source
&& v
->source
->max_column
> 0) ?
1524 DECIMAL_STR_WIDTH(v
->source
->max_column
) :
1525 DECIMAL_STR_MAX(unsigned) -1;
1528 size_t n
= 1 + (v
->source
? strlen(v
->source
->name
) : 0) +
1529 ((v
->source
&& (v
->line
> 0 || v
->column
> 0)) ? 1 : 0) +
1530 (v
->line
> 0 ? w
: 0) +
1531 (((v
->source
|| v
->line
> 0) && v
->column
> 0) ? 1 : 0) +
1532 (v
->column
> 0 ? k
: 0) +
1535 for (size_t i
= 0; i
< n
; i
++)
1541 fputs(v
->source
->name
, f
);
1542 if (v
->source
&& (v
->line
> 0 || v
->column
> 0))
1545 fprintf(f
, "%*u", (int) w
, v
->line
);
1546 if ((v
->source
|| v
->line
> 0) || v
->column
> 0)
1549 fprintf(f
, "%*u", (int) k
, v
->column
);
1558 static void json_format_string(FILE *f
, const char *q
, JsonFormatFlags flags
) {
1563 if (flags
& JSON_FORMAT_COLOR
)
1564 fputs(ansi_green(), f
);
1597 if ((signed char) *q
>= 0 && *q
< ' ')
1598 fprintf(f
, "\\u%04x", (unsigned) *q
);
1604 if (flags
& JSON_FORMAT_COLOR
)
1605 fputs(ANSI_NORMAL
, f
);
1610 static int json_format(FILE *f
, JsonVariant
*v
, JsonFormatFlags flags
, const char *prefix
) {
1616 if (FLAGS_SET(flags
, JSON_FORMAT_CENSOR_SENSITIVE
) && json_variant_is_sensitive(v
)) {
1617 if (flags
& JSON_FORMAT_COLOR
)
1618 fputs(ansi_red(), f
);
1619 fputs("\"<sensitive data>\"", f
);
1620 if (flags
& JSON_FORMAT_COLOR
)
1621 fputs(ANSI_NORMAL
, f
);
1625 switch (json_variant_type(v
)) {
1627 case JSON_VARIANT_REAL
: {
1628 locale_t loc
, old_loc
;
1630 loc
= newlocale(LC_NUMERIC_MASK
, "C", (locale_t
) 0);
1631 if (loc
== (locale_t
) 0)
1634 if (flags
& JSON_FORMAT_COLOR
)
1635 fputs(ansi_highlight_blue(), f
);
1637 old_loc
= uselocale(loc
);
1638 fprintf(f
, "%.*e", DECIMAL_DIG
, json_variant_real(v
));
1641 if (flags
& JSON_FORMAT_COLOR
)
1642 fputs(ANSI_NORMAL
, f
);
1648 case JSON_VARIANT_INTEGER
:
1649 if (flags
& JSON_FORMAT_COLOR
)
1650 fputs(ansi_highlight_blue(), f
);
1652 fprintf(f
, "%" PRIdMAX
, json_variant_integer(v
));
1654 if (flags
& JSON_FORMAT_COLOR
)
1655 fputs(ANSI_NORMAL
, f
);
1658 case JSON_VARIANT_UNSIGNED
:
1659 if (flags
& JSON_FORMAT_COLOR
)
1660 fputs(ansi_highlight_blue(), f
);
1662 fprintf(f
, "%" PRIuMAX
, json_variant_unsigned(v
));
1664 if (flags
& JSON_FORMAT_COLOR
)
1665 fputs(ANSI_NORMAL
, f
);
1668 case JSON_VARIANT_BOOLEAN
:
1670 if (flags
& JSON_FORMAT_COLOR
)
1671 fputs(ANSI_HIGHLIGHT
, f
);
1673 if (json_variant_boolean(v
))
1678 if (flags
& JSON_FORMAT_COLOR
)
1679 fputs(ANSI_NORMAL
, f
);
1683 case JSON_VARIANT_NULL
:
1684 if (flags
& JSON_FORMAT_COLOR
)
1685 fputs(ANSI_HIGHLIGHT
, f
);
1689 if (flags
& JSON_FORMAT_COLOR
)
1690 fputs(ANSI_NORMAL
, f
);
1693 case JSON_VARIANT_STRING
:
1694 json_format_string(f
, json_variant_string(v
), flags
);
1697 case JSON_VARIANT_ARRAY
: {
1698 size_t n
= json_variant_elements(v
);
1702 _cleanup_free_
char *joined
= NULL
;
1703 const char *prefix2
;
1705 if (flags
& JSON_FORMAT_PRETTY
) {
1706 joined
= strjoin(strempty(prefix
), "\t");
1713 prefix2
= strempty(prefix
);
1717 for (size_t i
= 0; i
< n
; i
++) {
1720 assert_se(e
= json_variant_by_index(v
, i
));
1723 if (flags
& JSON_FORMAT_PRETTY
)
1729 if (flags
& JSON_FORMAT_PRETTY
) {
1730 print_source(f
, e
, flags
, false);
1734 r
= json_format(f
, e
, flags
, prefix2
);
1739 if (flags
& JSON_FORMAT_PRETTY
) {
1741 print_source(f
, v
, flags
, true);
1742 fputs(strempty(prefix
), f
);
1750 case JSON_VARIANT_OBJECT
: {
1751 size_t n
= json_variant_elements(v
);
1755 _cleanup_free_
char *joined
= NULL
;
1756 const char *prefix2
;
1758 if (flags
& JSON_FORMAT_PRETTY
) {
1759 joined
= strjoin(strempty(prefix
), "\t");
1766 prefix2
= strempty(prefix
);
1770 for (size_t i
= 0; i
< n
; i
+= 2) {
1773 e
= json_variant_by_index(v
, i
);
1776 if (flags
& JSON_FORMAT_PRETTY
)
1782 if (flags
& JSON_FORMAT_PRETTY
) {
1783 print_source(f
, e
, flags
, false);
1787 r
= json_format(f
, e
, flags
, prefix2
);
1791 fputs(flags
& JSON_FORMAT_PRETTY
? " : " : ":", f
);
1793 r
= json_format(f
, json_variant_by_index(v
, i
+1), flags
, prefix2
);
1798 if (flags
& JSON_FORMAT_PRETTY
) {
1800 print_source(f
, v
, flags
, true);
1801 fputs(strempty(prefix
), f
);
1810 assert_not_reached();
1816 int json_variant_format(JsonVariant
*v
, JsonFormatFlags flags
, char **ret
) {
1817 _cleanup_(memstream_done
) MemStream m
= {};
1822 /* Returns the length of the generated string (without the terminating NUL),
1823 * or negative on error. */
1825 assert_return(v
, -EINVAL
);
1826 assert_return(ret
, -EINVAL
);
1828 if (flags
& JSON_FORMAT_OFF
)
1831 f
= memstream_init(&m
);
1835 r
= json_variant_dump(v
, flags
, f
, NULL
);
1839 r
= memstream_finalize(&m
, ret
, &sz
);
1846 int json_variant_dump(JsonVariant
*v
, JsonFormatFlags flags
, FILE *f
, const char *prefix
) {
1848 if (flags
& JSON_FORMAT_EMPTY_ARRAY
)
1849 v
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
1857 print_source(f
, v
, flags
, false);
1859 if (((flags
& (JSON_FORMAT_COLOR_AUTO
|JSON_FORMAT_COLOR
)) == JSON_FORMAT_COLOR_AUTO
) && colors_enabled())
1860 flags
|= JSON_FORMAT_COLOR
;
1862 if (((flags
& (JSON_FORMAT_PRETTY_AUTO
|JSON_FORMAT_PRETTY
)) == JSON_FORMAT_PRETTY_AUTO
))
1863 flags
|= on_tty() ? JSON_FORMAT_PRETTY
: JSON_FORMAT_NEWLINE
;
1865 if (flags
& JSON_FORMAT_SSE
)
1867 if (flags
& JSON_FORMAT_SEQ
)
1868 fputc('\x1e', f
); /* ASCII Record Separator */
1870 json_format(f
, v
, flags
, prefix
);
1872 if (flags
& (JSON_FORMAT_PRETTY
|JSON_FORMAT_SEQ
|JSON_FORMAT_SSE
|JSON_FORMAT_NEWLINE
))
1874 if (flags
& JSON_FORMAT_SSE
)
1875 fputc('\n', f
); /* In case of SSE add a second newline */
1877 if (flags
& JSON_FORMAT_FLUSH
)
1878 return fflush_and_check(f
);
1882 int json_variant_filter(JsonVariant
**v
, char **to_remove
) {
1883 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
1884 _cleanup_free_ JsonVariant
**array
= NULL
;
1885 size_t n
= 0, k
= 0;
1890 if (json_variant_is_blank_object(*v
))
1892 if (!json_variant_is_object(*v
))
1895 if (strv_isempty(to_remove
))
1898 for (size_t i
= 0; i
< json_variant_elements(*v
); i
+= 2) {
1901 p
= json_variant_by_index(*v
, i
);
1902 if (!json_variant_has_type(p
, JSON_VARIANT_STRING
))
1905 if (strv_contains(to_remove
, json_variant_string(p
))) {
1907 array
= new(JsonVariant
*, json_variant_elements(*v
) - 2);
1911 for (k
= 0; k
< i
; k
++)
1912 array
[k
] = json_variant_by_index(*v
, k
);
1918 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
1925 r
= json_variant_new_object(&w
, array
, k
);
1929 json_variant_propagate_sensitive(*v
, w
);
1930 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(w
));
1935 int json_variant_set_field(JsonVariant
**v
, const char *field
, JsonVariant
*value
) {
1936 _cleanup_(json_variant_unrefp
) JsonVariant
*field_variant
= NULL
, *w
= NULL
;
1937 _cleanup_free_ JsonVariant
**array
= NULL
;
1944 if (json_variant_is_blank_object(*v
)) {
1945 array
= new(JsonVariant
*, 2);
1950 if (!json_variant_is_object(*v
))
1953 for (size_t i
= 0; i
< json_variant_elements(*v
); i
+= 2) {
1956 p
= json_variant_by_index(*v
, i
);
1957 if (!json_variant_is_string(p
))
1960 if (streq(json_variant_string(p
), field
)) {
1963 array
= new(JsonVariant
*, json_variant_elements(*v
));
1967 for (k
= 0; k
< i
; k
++)
1968 array
[k
] = json_variant_by_index(*v
, k
);
1973 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
1978 array
= new(JsonVariant
*, json_variant_elements(*v
) + 2);
1982 for (k
= 0; k
< json_variant_elements(*v
); k
++)
1983 array
[k
] = json_variant_by_index(*v
, k
);
1987 r
= json_variant_new_string(&field_variant
, field
);
1991 array
[k
++] = field_variant
;
1994 r
= json_variant_new_object(&w
, array
, k
);
1998 json_variant_propagate_sensitive(*v
, w
);
1999 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(w
));
2004 int json_variant_set_fieldb(JsonVariant
**v
, const char *field
, ...) {
2005 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2009 va_start(ap
, field
);
2010 r
= json_buildv(&w
, ap
);
2015 return json_variant_set_field(v
, field
, w
);
2018 int json_variant_set_field_string(JsonVariant
**v
, const char *field
, const char *value
) {
2019 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2022 r
= json_variant_new_string(&m
, value
);
2026 return json_variant_set_field(v
, field
, m
);
2029 int json_variant_set_field_integer(JsonVariant
**v
, const char *field
, int64_t i
) {
2030 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2033 r
= json_variant_new_integer(&m
, i
);
2037 return json_variant_set_field(v
, field
, m
);
2040 int json_variant_set_field_unsigned(JsonVariant
**v
, const char *field
, uint64_t u
) {
2041 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2044 r
= json_variant_new_unsigned(&m
, u
);
2048 return json_variant_set_field(v
, field
, m
);
2051 int json_variant_set_field_boolean(JsonVariant
**v
, const char *field
, bool b
) {
2052 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2055 r
= json_variant_new_boolean(&m
, b
);
2059 return json_variant_set_field(v
, field
, m
);
2062 int json_variant_set_field_strv(JsonVariant
**v
, const char *field
, char **l
) {
2063 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2066 r
= json_variant_new_array_strv(&m
, l
);
2070 return json_variant_set_field(v
, field
, m
);
2073 int json_variant_merge_object(JsonVariant
**v
, JsonVariant
*m
) {
2074 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2075 _cleanup_free_ JsonVariant
**array
= NULL
;
2076 size_t v_elements
, m_elements
, k
;
2077 bool v_blank
, m_blank
;
2080 m
= json_variant_dereference(m
);
2082 v_blank
= json_variant_is_blank_object(*v
);
2083 m_blank
= json_variant_is_blank_object(m
);
2085 if (!v_blank
&& !json_variant_is_object(*v
))
2087 if (!m_blank
&& !json_variant_is_object(m
))
2091 return 0; /* nothing to do */
2094 JSON_VARIANT_REPLACE(*v
, json_variant_ref(m
));
2098 v_elements
= json_variant_elements(*v
);
2099 m_elements
= json_variant_elements(m
);
2100 if (v_elements
> SIZE_MAX
- m_elements
) /* overflow check */
2103 array
= new(JsonVariant
*, v_elements
+ m_elements
);
2108 for (size_t i
= 0; i
< v_elements
; i
+= 2) {
2111 u
= json_variant_by_index(*v
, i
);
2112 if (!json_variant_is_string(u
))
2115 if (json_variant_by_key(m
, json_variant_string(u
)))
2116 continue; /* skip if exists in second variant */
2119 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
2122 for (size_t i
= 0; i
< m_elements
; i
++)
2123 array
[k
++] = json_variant_by_index(m
, i
);
2125 r
= json_variant_new_object(&w
, array
, k
);
2129 json_variant_propagate_sensitive(*v
, w
);
2130 json_variant_propagate_sensitive(m
, w
);
2131 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(w
));
2136 int json_variant_merge_objectb(JsonVariant
**v
, ...) {
2137 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2142 r
= json_buildv(&w
, ap
);
2147 return json_variant_merge_object(v
, w
);
2150 int json_variant_append_array(JsonVariant
**v
, JsonVariant
*element
) {
2151 _cleanup_(json_variant_unrefp
) JsonVariant
*nv
= NULL
;
2158 if (!*v
|| json_variant_is_null(*v
))
2160 else if (json_variant_is_array(*v
))
2161 blank
= json_variant_elements(*v
) == 0;
2166 r
= json_variant_new_array(&nv
, (JsonVariant
*[]) { element
}, 1);
2169 } else if (json_variant_n_ref(*v
) == 1) {
2170 /* Let's bump the reference count on element. We can't do the realloc if we're appending *v
2171 * to itself, or one of the objects embedded in *v to *v. If the reference count grows, we
2172 * need to fall back to the other method below. */
2174 _unused_
_cleanup_(json_variant_unrefp
) JsonVariant
*dummy
= json_variant_ref(element
);
2175 if (json_variant_n_ref(*v
) == 1) {
2176 /* We hold the only reference. Let's mutate the object. */
2177 size_t size
= json_variant_elements(*v
);
2180 if (!GREEDY_REALLOC(*v
, size
+ 1 + 1))
2184 /* Readjust the parent pointers to the new address */
2185 for (size_t i
= 1; i
< size
; i
++)
2186 (*v
)[1 + i
].parent
= *v
;
2188 return _json_variant_array_put_element(*v
, element
);
2193 size_t size
= json_variant_elements(*v
);
2195 _cleanup_free_ JsonVariant
**array
= new(JsonVariant
*, size
+ 1);
2199 for (size_t i
= 0; i
< size
; i
++)
2200 array
[i
] = json_variant_by_index(*v
, i
);
2202 array
[size
] = element
;
2204 r
= json_variant_new_array(&nv
, array
, size
+ 1);
2209 json_variant_propagate_sensitive(*v
, nv
);
2210 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(nv
));
2215 int json_variant_append_arrayb(JsonVariant
**v
, ...) {
2216 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2221 r
= json_buildv(&w
, ap
);
2226 return json_variant_append_array(v
, w
);
2229 JsonVariant
*json_variant_find(JsonVariant
*haystack
, JsonVariant
*needle
) {
2232 /* Find a json object in an array. Returns NULL if not found, or if the array is not actually an array. */
2234 JSON_VARIANT_ARRAY_FOREACH(i
, haystack
)
2235 if (json_variant_equal(i
, needle
))
2241 int json_variant_append_array_nodup(JsonVariant
**v
, JsonVariant
*element
) {
2244 if (json_variant_find(*v
, element
))
2247 return json_variant_append_array(v
, element
);
2250 int json_variant_strv(JsonVariant
*v
, char ***ret
) {
2257 if (!v
|| json_variant_is_null(v
)) {
2266 if (!json_variant_is_array(v
))
2269 sensitive
= json_variant_is_sensitive(v
);
2271 size_t n
= json_variant_elements(v
);
2272 l
= new(char*, n
+1);
2276 for (size_t i
= 0; i
< n
; i
++) {
2279 assert_se(e
= json_variant_by_index(v
, i
));
2280 sensitive
= sensitive
|| json_variant_is_sensitive(e
);
2282 if (!json_variant_is_string(e
)) {
2288 l
[i
] = strdup(json_variant_string(e
));
2309 static int json_variant_copy(JsonVariant
**nv
, JsonVariant
*v
) {
2319 /* Let's copy the simple types literally, and the larger types by references */
2320 t
= json_variant_type(v
);
2322 case JSON_VARIANT_INTEGER
:
2323 k
= sizeof(int64_t);
2324 value
.integer
= json_variant_integer(v
);
2328 case JSON_VARIANT_UNSIGNED
:
2329 k
= sizeof(uint64_t);
2330 value
.unsig
= json_variant_unsigned(v
);
2334 case JSON_VARIANT_REAL
:
2336 value
.real
= json_variant_real(v
);
2340 case JSON_VARIANT_BOOLEAN
:
2342 value
.boolean
= json_variant_boolean(v
);
2346 case JSON_VARIANT_NULL
:
2351 case JSON_VARIANT_STRING
:
2352 source
= json_variant_string(v
);
2353 k
= strnlen(source
, INLINE_STRING_MAX
+ 1);
2354 if (k
<= INLINE_STRING_MAX
) {
2362 /* Everything else copy by reference */
2364 c
= malloc0(MAX(sizeof(JsonVariant
),
2365 offsetof(JsonVariant
, reference
) + sizeof(JsonVariant
*)));
2371 c
->is_reference
= true;
2372 c
->reference
= json_variant_ref(json_variant_formalize(v
));
2378 c
= malloc0(MAX(sizeof(JsonVariant
),
2379 offsetof(JsonVariant
, value
) + k
));
2386 memcpy_safe(&c
->value
, source
, k
);
2388 json_variant_propagate_sensitive(v
, c
);
2394 static bool json_single_ref(JsonVariant
*v
) {
2396 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
2398 if (!json_variant_is_regular(v
))
2402 return json_single_ref(v
->parent
);
2404 assert(v
->n_ref
> 0);
2405 return v
->n_ref
== 1;
2408 static int json_variant_set_source(JsonVariant
**v
, JsonSource
*source
, unsigned line
, unsigned column
) {
2414 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole
2415 * referencer of the object. If not, allocates a new object, possibly a surrogate for the original
2421 if (source
&& line
> source
->max_line
)
2422 source
->max_line
= line
;
2423 if (source
&& column
> source
->max_column
)
2424 source
->max_column
= column
;
2426 if (!json_variant_is_regular(*v
)) {
2428 if (!source
&& line
== 0 && column
== 0)
2432 if (json_source_equal((*v
)->source
, source
) &&
2433 (*v
)->line
== line
&&
2434 (*v
)->column
== column
)
2437 if (json_single_ref(*v
)) { /* Sole reference? */
2438 json_source_unref((*v
)->source
);
2439 (*v
)->source
= json_source_ref(source
);
2441 (*v
)->column
= column
;
2446 r
= json_variant_copy(&w
, *v
);
2450 assert(json_variant_is_regular(w
));
2451 assert(!w
->is_embedded
);
2452 assert(w
->n_ref
== 1);
2455 w
->source
= json_source_ref(source
);
2459 JSON_VARIANT_REPLACE(*v
, w
);
2464 static void inc_lines_columns(unsigned *line
, unsigned *column
, const char *s
, size_t n
) {
2467 assert(s
|| n
== 0);
2473 } else if ((signed char) *s
>= 0 && *s
< 127) /* Process ASCII chars quickly */
2478 w
= utf8_encoded_valid_unichar(s
, n
);
2479 if (w
< 0) /* count invalid unichars as normal characters */
2481 else if ((size_t) w
> n
) /* never read more than the specified number of characters */
2496 static int unhex_ucs2(const char *c
, uint16_t *ret
) {
2503 aa
= unhexchar(c
[0]);
2507 bb
= unhexchar(c
[1]);
2511 cc
= unhexchar(c
[2]);
2515 dd
= unhexchar(c
[3]);
2519 x
= ((uint16_t) aa
<< 12) |
2520 ((uint16_t) bb
<< 8) |
2521 ((uint16_t) cc
<< 4) |
2532 static int json_parse_string(const char **p
, char **ret
) {
2533 _cleanup_free_
char *s
= NULL
;
2555 /* Check for control characters 0x00..0x1f */
2556 if (*c
> 0 && *c
< ' ')
2559 /* Check for control character 0x7f */
2574 return JSON_TOKEN_STRING
;
2584 if (IN_SET(*c
, '"', '\\', '/'))
2596 else if (*c
== 'u') {
2600 r
= unhex_ucs2(c
+ 1, &x
);
2606 if (!GREEDY_REALLOC(s
, n
+ 5))
2609 if (!utf16_is_surrogate(x
))
2610 n
+= utf8_encode_unichar(s
+ n
, (char32_t
) x
);
2611 else if (utf16_is_trailing_surrogate(x
))
2616 if (c
[0] != '\\' || c
[1] != 'u')
2619 r
= unhex_ucs2(c
+ 2, &y
);
2625 if (!utf16_is_trailing_surrogate(y
))
2628 n
+= utf8_encode_unichar(s
+ n
, utf16_surrogate_pair_to_unichar(x
, y
));
2635 if (!GREEDY_REALLOC(s
, n
+ 2))
2643 len
= utf8_encoded_valid_unichar(c
, SIZE_MAX
);
2647 if (!GREEDY_REALLOC(s
, n
+ len
+ 1))
2650 memcpy(s
+ n
, c
, len
);
2656 static int json_parse_number(const char **p
, JsonValue
*ret
) {
2657 bool negative
= false, exponent_negative
= false, is_real
= false;
2658 double x
= 0.0, y
= 0.0, exponent
= 0.0, shift
= 1.0;
2677 if (!strchr("123456789", *c
) || *c
== 0)
2684 if (i
< INT64_MIN
/ 10) /* overflow */
2689 if (t
< INT64_MIN
+ (*c
- '0')) /* overflow */
2695 if (u
> UINT64_MAX
/ 10) /* overflow */
2698 uint64_t t
= 10 * u
;
2700 if (t
> UINT64_MAX
- (*c
- '0')) /* overflow */
2708 x
= 10.0 * x
+ (*c
- '0');
2711 } while (strchr("0123456789", *c
) && *c
!= 0);
2718 if (!strchr("0123456789", *c
) || *c
== 0)
2722 y
= 10.0 * y
+ (*c
- '0');
2723 shift
= 10.0 * shift
;
2725 } while (strchr("0123456789", *c
) && *c
!= 0);
2728 if (IN_SET(*c
, 'e', 'E')) {
2733 exponent_negative
= true;
2735 } else if (*c
== '+')
2738 if (!strchr("0123456789", *c
) || *c
== 0)
2742 exponent
= 10.0 * exponent
+ (*c
- '0');
2744 } while (strchr("0123456789", *c
) && *c
!= 0);
2750 ret
->real
= ((negative
? -1.0 : 1.0) * (x
+ (y
/ shift
))) * exp10((exponent_negative
? -1.0 : 1.0) * exponent
);
2751 return JSON_TOKEN_REAL
;
2752 } else if (negative
) {
2754 return JSON_TOKEN_INTEGER
;
2757 return JSON_TOKEN_UNSIGNED
;
2764 JsonValue
*ret_value
,
2765 unsigned *ret_line
, /* 'ret_line' returns the line at the beginning of this token */
2766 unsigned *ret_column
,
2768 unsigned *line
, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2771 unsigned start_line
, start_column
;
2772 const char *start
, *c
;
2792 t
= PTR_TO_INT(*state
);
2793 if (t
== STATE_NULL
) {
2799 /* Skip over the whitespace */
2800 n
= strspn(*p
, WHITESPACE
);
2801 inc_lines_columns(line
, column
, *p
, n
);
2804 /* Remember where we started processing this token */
2807 start_column
= *column
;
2811 *ret_value
= JSON_VALUE_NULL
;
2822 *state
= INT_TO_PTR(STATE_VALUE
);
2823 r
= JSON_TOKEN_OBJECT_OPEN
;
2826 } else if (*c
== '}') {
2828 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2829 r
= JSON_TOKEN_OBJECT_CLOSE
;
2832 } else if (*c
== '[') {
2834 *state
= INT_TO_PTR(STATE_VALUE
);
2835 r
= JSON_TOKEN_ARRAY_OPEN
;
2838 } else if (*c
== ']') {
2840 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2841 r
= JSON_TOKEN_ARRAY_CLOSE
;
2844 } else if (*c
== '"') {
2846 r
= json_parse_string(&c
, ret_string
);
2850 *ret_value
= JSON_VALUE_NULL
;
2851 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2854 } else if (strchr("-0123456789", *c
)) {
2856 r
= json_parse_number(&c
, ret_value
);
2861 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2864 } else if (startswith(c
, "true")) {
2866 ret_value
->boolean
= true;
2868 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2869 r
= JSON_TOKEN_BOOLEAN
;
2872 } else if (startswith(c
, "false")) {
2874 ret_value
->boolean
= false;
2876 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2877 r
= JSON_TOKEN_BOOLEAN
;
2880 } else if (startswith(c
, "null")) {
2882 *ret_value
= JSON_VALUE_NULL
;
2884 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2885 r
= JSON_TOKEN_NULL
;
2892 case STATE_VALUE_POST
:
2896 *state
= INT_TO_PTR(STATE_VALUE
);
2897 r
= JSON_TOKEN_COLON
;
2900 } else if (*c
== ',') {
2902 *state
= INT_TO_PTR(STATE_VALUE
);
2903 r
= JSON_TOKEN_COMMA
;
2906 } else if (*c
== '}') {
2908 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2909 r
= JSON_TOKEN_OBJECT_CLOSE
;
2912 } else if (*c
== ']') {
2914 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2915 r
= JSON_TOKEN_ARRAY_CLOSE
;
2922 assert_not_reached();
2927 *ret_value
= JSON_VALUE_NULL
;
2930 inc_lines_columns(line
, column
, start
, c
- start
);
2933 *ret_line
= start_line
;
2934 *ret_column
= start_column
;
2939 typedef enum JsonExpect
{
2940 /* The following values are used by json_parse() */
2943 EXPECT_OBJECT_FIRST_KEY
,
2944 EXPECT_OBJECT_NEXT_KEY
,
2945 EXPECT_OBJECT_COLON
,
2946 EXPECT_OBJECT_VALUE
,
2947 EXPECT_OBJECT_COMMA
,
2948 EXPECT_ARRAY_FIRST_ELEMENT
,
2949 EXPECT_ARRAY_NEXT_ELEMENT
,
2952 /* And these are used by json_build() */
2953 EXPECT_ARRAY_ELEMENT
,
2957 typedef struct JsonStack
{
2959 JsonVariant
**elements
;
2961 unsigned line_before
;
2962 unsigned column_before
;
2963 size_t n_suppress
; /* When building: if > 0, suppress this many subsequent elements. If == SIZE_MAX, suppress all subsequent elements */
2966 static void json_stack_release(JsonStack
*s
) {
2969 CLEANUP_ARRAY(s
->elements
, s
->n_elements
, json_variant_unref_many
);
2972 static int json_parse_internal(
2975 JsonParseFlags flags
,
2979 bool continue_end
) {
2982 unsigned line_buffer
= 0, column_buffer
= 0;
2983 void *tokenizer_state
= NULL
;
2984 JsonStack
*stack
= NULL
;
2988 assert_return(input
, -EINVAL
);
2989 assert_return(ret
, -EINVAL
);
2993 if (!GREEDY_REALLOC(stack
, n_stack
))
2996 stack
[0] = (JsonStack
) {
2997 .expect
= EXPECT_TOPLEVEL
,
3001 line
= &line_buffer
;
3003 column
= &column_buffer
;
3006 _cleanup_(json_variant_unrefp
) JsonVariant
*add
= NULL
;
3007 _cleanup_free_
char *string
= NULL
;
3008 unsigned line_token
, column_token
;
3013 assert(n_stack
> 0);
3014 current
= stack
+ n_stack
- 1;
3016 if (continue_end
&& current
->expect
== EXPECT_END
)
3019 token
= json_tokenize(&p
, &string
, &value
, &line_token
, &column_token
, &tokenizer_state
, line
, column
);
3027 case JSON_TOKEN_END
:
3028 if (current
->expect
!= EXPECT_END
) {
3033 assert(current
->n_elements
== 1);
3034 assert(n_stack
== 1);
3037 case JSON_TOKEN_COLON
:
3039 if (current
->expect
!= EXPECT_OBJECT_COLON
) {
3044 current
->expect
= EXPECT_OBJECT_VALUE
;
3047 case JSON_TOKEN_COMMA
:
3049 if (current
->expect
== EXPECT_OBJECT_COMMA
)
3050 current
->expect
= EXPECT_OBJECT_NEXT_KEY
;
3051 else if (current
->expect
== EXPECT_ARRAY_COMMA
)
3052 current
->expect
= EXPECT_ARRAY_NEXT_ELEMENT
;
3060 case JSON_TOKEN_OBJECT_OPEN
:
3062 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3067 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
3071 current
= stack
+ n_stack
- 1;
3073 /* Prepare the expect for when we return from the child */
3074 if (current
->expect
== EXPECT_TOPLEVEL
)
3075 current
->expect
= EXPECT_END
;
3076 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3077 current
->expect
= EXPECT_OBJECT_COMMA
;
3079 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3080 current
->expect
= EXPECT_ARRAY_COMMA
;
3083 stack
[n_stack
++] = (JsonStack
) {
3084 .expect
= EXPECT_OBJECT_FIRST_KEY
,
3085 .line_before
= line_token
,
3086 .column_before
= column_token
,
3089 current
= stack
+ n_stack
- 1;
3092 case JSON_TOKEN_OBJECT_CLOSE
:
3093 if (!IN_SET(current
->expect
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_COMMA
)) {
3098 assert(n_stack
> 1);
3100 r
= json_variant_new_object(&add
, current
->elements
, current
->n_elements
);
3104 line_token
= current
->line_before
;
3105 column_token
= current
->column_before
;
3107 json_stack_release(current
);
3108 n_stack
--, current
--;
3112 case JSON_TOKEN_ARRAY_OPEN
:
3113 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3118 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
3122 current
= stack
+ n_stack
- 1;
3124 /* Prepare the expect for when we return from the child */
3125 if (current
->expect
== EXPECT_TOPLEVEL
)
3126 current
->expect
= EXPECT_END
;
3127 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3128 current
->expect
= EXPECT_OBJECT_COMMA
;
3130 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3131 current
->expect
= EXPECT_ARRAY_COMMA
;
3134 stack
[n_stack
++] = (JsonStack
) {
3135 .expect
= EXPECT_ARRAY_FIRST_ELEMENT
,
3136 .line_before
= line_token
,
3137 .column_before
= column_token
,
3142 case JSON_TOKEN_ARRAY_CLOSE
:
3143 if (!IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_COMMA
)) {
3148 assert(n_stack
> 1);
3150 r
= json_variant_new_array(&add
, current
->elements
, current
->n_elements
);
3154 line_token
= current
->line_before
;
3155 column_token
= current
->column_before
;
3157 json_stack_release(current
);
3158 n_stack
--, current
--;
3161 case JSON_TOKEN_STRING
:
3162 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
)) {
3167 r
= json_variant_new_string(&add
, string
);
3171 if (current
->expect
== EXPECT_TOPLEVEL
)
3172 current
->expect
= EXPECT_END
;
3173 else if (IN_SET(current
->expect
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_NEXT_KEY
))
3174 current
->expect
= EXPECT_OBJECT_COLON
;
3175 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3176 current
->expect
= EXPECT_OBJECT_COMMA
;
3178 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3179 current
->expect
= EXPECT_ARRAY_COMMA
;
3184 case JSON_TOKEN_REAL
:
3185 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3190 r
= json_variant_new_real(&add
, value
.real
);
3194 if (current
->expect
== EXPECT_TOPLEVEL
)
3195 current
->expect
= EXPECT_END
;
3196 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3197 current
->expect
= EXPECT_OBJECT_COMMA
;
3199 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3200 current
->expect
= EXPECT_ARRAY_COMMA
;
3205 case JSON_TOKEN_INTEGER
:
3206 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3211 r
= json_variant_new_integer(&add
, value
.integer
);
3215 if (current
->expect
== EXPECT_TOPLEVEL
)
3216 current
->expect
= EXPECT_END
;
3217 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3218 current
->expect
= EXPECT_OBJECT_COMMA
;
3220 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3221 current
->expect
= EXPECT_ARRAY_COMMA
;
3226 case JSON_TOKEN_UNSIGNED
:
3227 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3232 r
= json_variant_new_unsigned(&add
, value
.unsig
);
3236 if (current
->expect
== EXPECT_TOPLEVEL
)
3237 current
->expect
= EXPECT_END
;
3238 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3239 current
->expect
= EXPECT_OBJECT_COMMA
;
3241 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3242 current
->expect
= EXPECT_ARRAY_COMMA
;
3247 case JSON_TOKEN_BOOLEAN
:
3248 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3253 r
= json_variant_new_boolean(&add
, value
.boolean
);
3257 if (current
->expect
== EXPECT_TOPLEVEL
)
3258 current
->expect
= EXPECT_END
;
3259 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3260 current
->expect
= EXPECT_OBJECT_COMMA
;
3262 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3263 current
->expect
= EXPECT_ARRAY_COMMA
;
3268 case JSON_TOKEN_NULL
:
3269 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3274 r
= json_variant_new_null(&add
);
3278 if (current
->expect
== EXPECT_TOPLEVEL
)
3279 current
->expect
= EXPECT_END
;
3280 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3281 current
->expect
= EXPECT_OBJECT_COMMA
;
3283 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3284 current
->expect
= EXPECT_ARRAY_COMMA
;
3290 assert_not_reached();
3294 /* If we are asked to make this parsed object sensitive, then let's apply this
3295 * immediately after allocating each variant, so that when we abort half-way
3296 * everything we already allocated that is then freed is correctly marked. */
3297 if (FLAGS_SET(flags
, JSON_PARSE_SENSITIVE
))
3298 json_variant_sensitive(add
);
3300 (void) json_variant_set_source(&add
, source
, line_token
, column_token
);
3302 if (!GREEDY_REALLOC(current
->elements
, current
->n_elements
+ 1)) {
3307 current
->elements
[current
->n_elements
++] = TAKE_PTR(add
);
3312 assert(n_stack
== 1);
3313 assert(stack
[0].n_elements
== 1);
3315 *ret
= json_variant_ref(stack
[0].elements
[0]);
3320 for (size_t i
= 0; i
< n_stack
; i
++)
3321 json_stack_release(stack
+ i
);
3328 int json_parse_with_source(
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(&input
, s
, flags
, ret
, ret_line
, ret_column
, false);
3347 int json_parse_with_source_continue(
3350 JsonParseFlags flags
,
3353 unsigned *ret_column
) {
3355 _cleanup_(json_source_unrefp
) JsonSource
*s
= NULL
;
3358 s
= json_source_new(source
);
3363 return json_parse_internal(p
, s
, flags
, ret
, ret_line
, ret_column
, true);
3366 int json_parse_file_at(
3370 JsonParseFlags flags
,
3373 unsigned *ret_column
) {
3375 _cleanup_free_
char *text
= NULL
;
3379 r
= read_full_stream(f
, &text
, NULL
);
3381 r
= read_full_file_full(dir_fd
, path
, UINT64_MAX
, SIZE_MAX
, 0, NULL
, &text
, NULL
);
3390 return json_parse_with_source(text
, path
, flags
, ret
, ret_line
, ret_column
);
3393 int json_buildv(JsonVariant
**ret
, va_list ap
) {
3394 JsonStack
*stack
= NULL
;
3396 const char *name
= NULL
;
3399 assert_return(ret
, -EINVAL
);
3401 if (!GREEDY_REALLOC(stack
, n_stack
))
3404 stack
[0] = (JsonStack
) {
3405 .expect
= EXPECT_TOPLEVEL
,
3409 _cleanup_(json_variant_unrefp
) JsonVariant
*add
= NULL
, *add_more
= NULL
;
3410 size_t n_subtract
= 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
3411 * have been added to the current variant */
3415 assert(n_stack
> 0);
3416 current
= stack
+ n_stack
- 1;
3418 if (current
->expect
== EXPECT_END
)
3421 command
= va_arg(ap
, int);
3425 case _JSON_BUILD_STRING
: {
3428 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3433 p
= va_arg(ap
, const char *);
3435 if (current
->n_suppress
== 0) {
3436 r
= json_variant_new_string(&add
, p
);
3443 if (current
->expect
== EXPECT_TOPLEVEL
)
3444 current
->expect
= EXPECT_END
;
3445 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3446 current
->expect
= EXPECT_OBJECT_KEY
;
3448 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3453 case _JSON_BUILD_INTEGER
: {
3456 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3461 j
= va_arg(ap
, int64_t);
3463 if (current
->n_suppress
== 0) {
3464 r
= json_variant_new_integer(&add
, j
);
3471 if (current
->expect
== EXPECT_TOPLEVEL
)
3472 current
->expect
= EXPECT_END
;
3473 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3474 current
->expect
= EXPECT_OBJECT_KEY
;
3476 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3481 case _JSON_BUILD_UNSIGNED
: {
3484 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3489 j
= va_arg(ap
, uint64_t);
3491 if (current
->n_suppress
== 0) {
3492 r
= json_variant_new_unsigned(&add
, j
);
3499 if (current
->expect
== EXPECT_TOPLEVEL
)
3500 current
->expect
= EXPECT_END
;
3501 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3502 current
->expect
= EXPECT_OBJECT_KEY
;
3504 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3509 case _JSON_BUILD_REAL
: {
3512 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3517 d
= va_arg(ap
, double);
3519 if (current
->n_suppress
== 0) {
3520 r
= json_variant_new_real(&add
, d
);
3527 if (current
->expect
== EXPECT_TOPLEVEL
)
3528 current
->expect
= EXPECT_END
;
3529 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3530 current
->expect
= EXPECT_OBJECT_KEY
;
3532 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3537 case _JSON_BUILD_BOOLEAN
: {
3540 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3545 b
= va_arg(ap
, int);
3547 if (current
->n_suppress
== 0) {
3548 r
= json_variant_new_boolean(&add
, b
);
3555 if (current
->expect
== EXPECT_TOPLEVEL
)
3556 current
->expect
= EXPECT_END
;
3557 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3558 current
->expect
= EXPECT_OBJECT_KEY
;
3560 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3565 case _JSON_BUILD_NULL
:
3567 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3572 if (current
->n_suppress
== 0) {
3573 r
= json_variant_new_null(&add
);
3580 if (current
->expect
== EXPECT_TOPLEVEL
)
3581 current
->expect
= EXPECT_END
;
3582 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3583 current
->expect
= EXPECT_OBJECT_KEY
;
3585 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3589 case _JSON_BUILD_VARIANT
:
3591 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3596 /* Note that we don't care for current->n_suppress here, after all the variant is already
3597 * allocated anyway... */
3598 add
= va_arg(ap
, JsonVariant
*);
3600 add
= JSON_VARIANT_MAGIC_NULL
;
3602 json_variant_ref(add
);
3606 if (current
->expect
== EXPECT_TOPLEVEL
)
3607 current
->expect
= EXPECT_END
;
3608 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3609 current
->expect
= EXPECT_OBJECT_KEY
;
3611 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3615 case _JSON_BUILD_VARIANT_ARRAY
: {
3616 JsonVariant
**array
;
3619 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3624 array
= va_arg(ap
, JsonVariant
**);
3625 n
= va_arg(ap
, size_t);
3627 if (current
->n_suppress
== 0) {
3628 r
= json_variant_new_array(&add
, array
, n
);
3635 if (current
->expect
== EXPECT_TOPLEVEL
)
3636 current
->expect
= EXPECT_END
;
3637 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3638 current
->expect
= EXPECT_OBJECT_KEY
;
3640 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3645 case _JSON_BUILD_LITERAL
: {
3648 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3653 l
= va_arg(ap
, const char *);
3656 /* Note that we don't care for current->n_suppress here, we should generate parsing
3657 * errors even in suppressed object properties */
3659 r
= json_parse(l
, 0, &add
, NULL
, NULL
);
3663 add
= JSON_VARIANT_MAGIC_NULL
;
3667 if (current
->expect
== EXPECT_TOPLEVEL
)
3668 current
->expect
= EXPECT_END
;
3669 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3670 current
->expect
= EXPECT_OBJECT_KEY
;
3672 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3677 case _JSON_BUILD_ARRAY_BEGIN
:
3679 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3684 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
3688 current
= stack
+ n_stack
- 1;
3690 if (current
->expect
== EXPECT_TOPLEVEL
)
3691 current
->expect
= EXPECT_END
;
3692 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3693 current
->expect
= EXPECT_OBJECT_KEY
;
3695 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3697 stack
[n_stack
++] = (JsonStack
) {
3698 .expect
= EXPECT_ARRAY_ELEMENT
,
3699 .n_suppress
= current
->n_suppress
!= 0 ? SIZE_MAX
: 0, /* if we shall suppress the
3700 * new array, then we should
3701 * also suppress all array
3707 case _JSON_BUILD_ARRAY_END
:
3708 if (current
->expect
!= EXPECT_ARRAY_ELEMENT
) {
3713 assert(n_stack
> 1);
3715 if (current
->n_suppress
== 0) {
3716 r
= json_variant_new_array(&add
, current
->elements
, current
->n_elements
);
3723 json_stack_release(current
);
3724 n_stack
--, current
--;
3728 case _JSON_BUILD_STRV
: {
3731 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3736 l
= va_arg(ap
, char **);
3738 if (current
->n_suppress
== 0) {
3739 r
= json_variant_new_array_strv(&add
, l
);
3746 if (current
->expect
== EXPECT_TOPLEVEL
)
3747 current
->expect
= EXPECT_END
;
3748 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3749 current
->expect
= EXPECT_OBJECT_KEY
;
3751 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3756 case _JSON_BUILD_STRV_ENV_PAIR
: {
3759 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3764 l
= va_arg(ap
, char **);
3766 _cleanup_strv_free_
char **el
= NULL
;
3767 STRV_FOREACH_PAIR(x
, y
, l
) {
3770 n
= strjoin(*x
, "=", *y
);
3776 r
= strv_consume(&el
, n
);
3781 if (current
->n_suppress
== 0) {
3782 r
= json_variant_new_array_strv(&add
, el
);
3789 if (current
->expect
== EXPECT_TOPLEVEL
)
3790 current
->expect
= EXPECT_END
;
3791 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3792 current
->expect
= EXPECT_OBJECT_KEY
;
3794 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3799 case _JSON_BUILD_BASE64
:
3800 case _JSON_BUILD_BASE32HEX
:
3801 case _JSON_BUILD_HEX
:
3802 case _JSON_BUILD_OCTESCAPE
: {
3806 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3811 p
= va_arg(ap
, const void *);
3812 n
= va_arg(ap
, size_t);
3814 if (current
->n_suppress
== 0) {
3815 r
= command
== _JSON_BUILD_BASE64
? json_variant_new_base64(&add
, p
, n
) :
3816 command
== _JSON_BUILD_BASE32HEX
? json_variant_new_base32hex(&add
, p
, n
) :
3817 command
== _JSON_BUILD_HEX
? json_variant_new_hex(&add
, p
, n
) :
3818 json_variant_new_octescape(&add
, p
, n
);
3825 if (current
->expect
== EXPECT_TOPLEVEL
)
3826 current
->expect
= EXPECT_END
;
3827 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3828 current
->expect
= EXPECT_OBJECT_KEY
;
3830 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3835 case _JSON_BUILD_IOVEC_BASE64
:
3836 case _JSON_BUILD_IOVEC_HEX
: {
3837 const struct iovec
*iov
;
3839 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3844 iov
= va_arg(ap
, const struct iovec
*);
3846 if (current
->n_suppress
== 0) {
3848 r
= command
== _JSON_BUILD_IOVEC_BASE64
? json_variant_new_base64(&add
, iov
->iov_base
, iov
->iov_len
) :
3849 json_variant_new_hex(&add
, iov
->iov_base
, iov
->iov_len
);
3851 r
= json_variant_new_string(&add
, "");
3858 if (current
->expect
== EXPECT_TOPLEVEL
)
3859 current
->expect
= EXPECT_END
;
3860 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3861 current
->expect
= EXPECT_OBJECT_KEY
;
3863 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3868 case _JSON_BUILD_ID128
:
3869 case _JSON_BUILD_UUID
: {
3870 const sd_id128_t
*id
;
3872 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3877 assert_se(id
= va_arg(ap
, sd_id128_t
*));
3879 if (current
->n_suppress
== 0) {
3880 r
= command
== _JSON_BUILD_ID128
?
3881 json_variant_new_id128(&add
, *id
) :
3882 json_variant_new_uuid(&add
, *id
);
3889 if (current
->expect
== EXPECT_TOPLEVEL
)
3890 current
->expect
= EXPECT_END
;
3891 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3892 current
->expect
= EXPECT_OBJECT_KEY
;
3894 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3899 case _JSON_BUILD_BYTE_ARRAY
: {
3903 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3908 array
= va_arg(ap
, const void*);
3909 n
= va_arg(ap
, size_t);
3911 if (current
->n_suppress
== 0) {
3912 r
= json_variant_new_array_bytes(&add
, array
, n
);
3919 if (current
->expect
== EXPECT_TOPLEVEL
)
3920 current
->expect
= EXPECT_END
;
3921 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3922 current
->expect
= EXPECT_OBJECT_KEY
;
3924 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3929 case _JSON_BUILD_HW_ADDR
: {
3930 const struct hw_addr_data
*hw_addr
;
3932 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3937 assert_se(hw_addr
= va_arg(ap
, struct hw_addr_data
*));
3939 if (current
->n_suppress
== 0) {
3940 r
= json_variant_new_array_bytes(&add
, hw_addr
->bytes
, hw_addr
->length
);
3947 if (current
->expect
== EXPECT_TOPLEVEL
)
3948 current
->expect
= EXPECT_END
;
3949 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3950 current
->expect
= EXPECT_OBJECT_KEY
;
3952 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3957 case _JSON_BUILD_STRING_SET
: {
3960 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3965 set
= va_arg(ap
, Set
*);
3967 if (current
->n_suppress
== 0) {
3968 _cleanup_free_
char **sorted
= NULL
;
3970 r
= set_dump_sorted(set
, (void ***) &sorted
, NULL
);
3974 r
= json_variant_new_array_strv(&add
, sorted
);
3981 if (current
->expect
== EXPECT_TOPLEVEL
)
3982 current
->expect
= EXPECT_END
;
3983 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3984 current
->expect
= EXPECT_OBJECT_KEY
;
3986 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3991 case _JSON_BUILD_CALLBACK
: {
3992 JsonBuildCallback cb
;
3995 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
4000 cb
= va_arg(ap
, JsonBuildCallback
);
4001 userdata
= va_arg(ap
, void *);
4003 if (current
->n_suppress
== 0) {
4005 r
= cb(&add
, name
, userdata
);
4011 add
= JSON_VARIANT_MAGIC_NULL
;
4018 if (current
->expect
== EXPECT_TOPLEVEL
)
4019 current
->expect
= EXPECT_END
;
4020 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
4021 current
->expect
= EXPECT_OBJECT_KEY
;
4023 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
4028 case _JSON_BUILD_OBJECT_BEGIN
:
4030 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
4035 if (!GREEDY_REALLOC(stack
, n_stack
+1)) {
4039 current
= stack
+ n_stack
- 1;
4041 if (current
->expect
== EXPECT_TOPLEVEL
)
4042 current
->expect
= EXPECT_END
;
4043 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
4044 current
->expect
= EXPECT_OBJECT_KEY
;
4046 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
4048 stack
[n_stack
++] = (JsonStack
) {
4049 .expect
= EXPECT_OBJECT_KEY
,
4050 .n_suppress
= current
->n_suppress
!= 0 ? SIZE_MAX
: 0, /* If we shall suppress the
4051 * new object, then we should
4052 * also suppress all object
4058 case _JSON_BUILD_OBJECT_END
:
4060 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4065 assert(n_stack
> 1);
4067 if (current
->n_suppress
== 0) {
4068 r
= json_variant_new_object(&add
, current
->elements
, current
->n_elements
);
4075 json_stack_release(current
);
4076 n_stack
--, current
--;
4080 case _JSON_BUILD_PAIR
: {
4082 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4087 name
= va_arg(ap
, const char *);
4089 if (current
->n_suppress
== 0) {
4090 r
= json_variant_new_string(&add
, name
);
4097 current
->expect
= EXPECT_OBJECT_VALUE
;
4101 case _JSON_BUILD_PAIR_CONDITION
: {
4104 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4109 b
= va_arg(ap
, int);
4110 name
= va_arg(ap
, const char *);
4112 if (b
&& current
->n_suppress
== 0) {
4113 r
= json_variant_new_string(&add
, name
);
4118 n_subtract
= 1; /* we generated one item */
4120 if (!b
&& current
->n_suppress
!= SIZE_MAX
)
4121 current
->n_suppress
+= 2; /* Suppress this one and the next item */
4123 current
->expect
= EXPECT_OBJECT_VALUE
;
4127 case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO
: {
4131 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4136 n
= va_arg(ap
, const char *);
4137 u
= va_arg(ap
, uint64_t);
4139 if (u
!= 0 && current
->n_suppress
== 0) {
4140 r
= json_variant_new_string(&add
, n
);
4144 r
= json_variant_new_unsigned(&add_more
, u
);
4149 n_subtract
= 2; /* we generated two item */
4151 current
->expect
= EXPECT_OBJECT_KEY
;
4155 case _JSON_BUILD_PAIR_FINITE_USEC
: {
4159 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4164 n
= va_arg(ap
, const char *);
4165 u
= va_arg(ap
, usec_t
);
4167 if (u
!= USEC_INFINITY
&& current
->n_suppress
== 0) {
4168 r
= json_variant_new_string(&add
, n
);
4172 r
= json_variant_new_unsigned(&add_more
, u
);
4177 n_subtract
= 2; /* we generated two item */
4179 current
->expect
= EXPECT_OBJECT_KEY
;
4183 case _JSON_BUILD_PAIR_STRING_NON_EMPTY
: {
4186 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4191 n
= va_arg(ap
, const char *);
4192 s
= va_arg(ap
, const char *);
4194 if (!isempty(s
) && current
->n_suppress
== 0) {
4195 r
= json_variant_new_string(&add
, n
);
4199 r
= json_variant_new_string(&add_more
, s
);
4204 n_subtract
= 2; /* we generated two item */
4206 current
->expect
= EXPECT_OBJECT_KEY
;
4210 case _JSON_BUILD_PAIR_STRV_NON_EMPTY
: {
4214 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4219 n
= va_arg(ap
, const char *);
4220 l
= va_arg(ap
, char **);
4222 if (!strv_isempty(l
) && current
->n_suppress
== 0) {
4223 r
= json_variant_new_string(&add
, n
);
4227 r
= json_variant_new_array_strv(&add_more
, l
);
4232 n_subtract
= 2; /* we generated two item */
4234 current
->expect
= EXPECT_OBJECT_KEY
;
4238 case _JSON_BUILD_PAIR_VARIANT_NON_NULL
: {
4242 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4247 n
= va_arg(ap
, const char *);
4248 v
= va_arg(ap
, JsonVariant
*);
4250 if (v
&& !json_variant_is_null(v
) && current
->n_suppress
== 0) {
4251 r
= json_variant_new_string(&add
, n
);
4255 add_more
= json_variant_ref(v
);
4258 n_subtract
= 2; /* we generated two item */
4260 current
->expect
= EXPECT_OBJECT_KEY
;
4264 case _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL
: {
4265 const struct in_addr
*a
;
4268 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4273 n
= va_arg(ap
, const char *);
4274 a
= va_arg(ap
, const struct in_addr
*);
4276 if (a
&& in4_addr_is_set(a
) && current
->n_suppress
== 0) {
4277 r
= json_variant_new_string(&add
, n
);
4281 r
= json_variant_new_array_bytes(&add_more
, a
, sizeof(struct in_addr
));
4286 n_subtract
= 2; /* we generated two item */
4288 current
->expect
= EXPECT_OBJECT_KEY
;
4292 case _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL
: {
4293 const struct in6_addr
*a
;
4296 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4301 n
= va_arg(ap
, const char *);
4302 a
= va_arg(ap
, const struct in6_addr
*);
4304 if (a
&& in6_addr_is_set(a
) && current
->n_suppress
== 0) {
4305 r
= json_variant_new_string(&add
, n
);
4309 r
= json_variant_new_array_bytes(&add_more
, a
, sizeof(struct in6_addr
));
4314 n_subtract
= 2; /* we generated two item */
4316 current
->expect
= EXPECT_OBJECT_KEY
;
4320 case _JSON_BUILD_PAIR_IN_ADDR_NON_NULL
: {
4321 const union in_addr_union
*a
;
4325 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4330 n
= va_arg(ap
, const char *);
4331 a
= va_arg(ap
, const union in_addr_union
*);
4332 f
= va_arg(ap
, int);
4334 if (a
&& in_addr_is_set(f
, a
) && current
->n_suppress
== 0) {
4335 r
= json_variant_new_string(&add
, n
);
4339 r
= json_variant_new_array_bytes(&add_more
, a
->bytes
, FAMILY_ADDRESS_SIZE(f
));
4344 n_subtract
= 2; /* we generated two item */
4346 current
->expect
= EXPECT_OBJECT_KEY
;
4350 case _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL
: {
4351 const struct ether_addr
*a
;
4354 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4359 n
= va_arg(ap
, const char *);
4360 a
= va_arg(ap
, const struct ether_addr
*);
4362 if (a
&& !ether_addr_is_null(a
) && current
->n_suppress
== 0) {
4363 r
= json_variant_new_string(&add
, n
);
4367 r
= json_variant_new_array_bytes(&add_more
, a
->ether_addr_octet
, sizeof(struct ether_addr
));
4372 n_subtract
= 2; /* we generated two item */
4374 current
->expect
= EXPECT_OBJECT_KEY
;
4378 case _JSON_BUILD_PAIR_HW_ADDR_NON_NULL
: {
4379 const struct hw_addr_data
*a
;
4382 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
4387 n
= va_arg(ap
, const char *);
4388 a
= va_arg(ap
, const struct hw_addr_data
*);
4390 if (a
&& !hw_addr_is_null(a
) && current
->n_suppress
== 0) {
4391 r
= json_variant_new_string(&add
, n
);
4395 r
= json_variant_new_array_bytes(&add_more
, a
->bytes
, a
->length
);
4400 n_subtract
= 2; /* we generated two item */
4402 current
->expect
= EXPECT_OBJECT_KEY
;
4407 /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */
4408 if (add
&& current
->n_suppress
== 0) {
4409 if (!GREEDY_REALLOC(current
->elements
, current
->n_elements
+ 1 + !!add_more
)) {
4414 current
->elements
[current
->n_elements
++] = TAKE_PTR(add
);
4416 current
->elements
[current
->n_elements
++] = TAKE_PTR(add_more
);
4419 /* If we are supposed to suppress items, let's subtract how many items where generated from
4420 * that counter. Except if the counter is SIZE_MAX, i.e. we shall suppress an infinite number
4421 * of elements on this stack level */
4422 if (current
->n_suppress
!= SIZE_MAX
) {
4423 if (current
->n_suppress
<= n_subtract
) /* Saturated */
4424 current
->n_suppress
= 0;
4426 current
->n_suppress
-= n_subtract
;
4431 assert(n_stack
== 1);
4432 assert(stack
[0].n_elements
== 1);
4434 *ret
= json_variant_ref(stack
[0].elements
[0]);
4438 for (size_t i
= 0; i
< n_stack
; i
++)
4439 json_stack_release(stack
+ i
);
4446 int json_build(JsonVariant
**ret
, ...) {
4451 r
= json_buildv(ret
, ap
);
4457 int json_log_internal(
4458 JsonVariant
*variant
,
4464 const char *format
, ...) {
4468 unsigned source_line
, source_column
;
4469 char buffer
[LINE_MAX
];
4474 errno
= ERRNO_VALUE(error
);
4476 va_start(ap
, format
);
4477 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
4481 r
= json_variant_get_source(variant
, &source
, &source_line
, &source_column
);
4490 if (source
&& source_line
> 0 && source_column
> 0)
4491 return log_struct_internal(
4495 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
4496 "CONFIG_FILE=%s", source
,
4497 "CONFIG_LINE=%u", source_line
,
4498 "CONFIG_COLUMN=%u", source_column
,
4499 LOG_MESSAGE("%s:%u:%u: %s", source
, source_line
, source_column
, buffer
),
4501 else if (source_line
> 0 && source_column
> 0)
4502 return log_struct_internal(
4506 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
4507 "CONFIG_LINE=%u", source_line
,
4508 "CONFIG_COLUMN=%u", source_column
,
4509 LOG_MESSAGE("(string):%u:%u: %s", source_line
, source_column
, buffer
),
4512 return log_struct_internal(
4516 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
4517 LOG_MESSAGE("%s", buffer
),
4521 static void *dispatch_userdata(const JsonDispatch
*p
, void *userdata
) {
4523 /* When the userdata pointer is passed in as NULL, then we'll just use the offset as a literal
4524 * address, and convert it to a pointer. Note that might as well just add the offset to the NULL
4525 * pointer, but UndefinedBehaviourSanitizer doesn't like pointer arithmetics based on NULL pointers,
4526 * hence we code this explicitly here. */
4529 return (uint8_t*) userdata
+ p
->offset
;
4531 return SIZE_TO_PTR(p
->offset
);
4534 int json_dispatch_full(
4536 const JsonDispatch table
[],
4537 JsonDispatchCallback bad
,
4538 JsonDispatchFlags flags
,
4540 const char **reterr_bad_field
) {
4545 if (!json_variant_is_object(v
)) {
4546 json_log(v
, flags
, 0, "JSON variant is not an object.");
4548 if (flags
& JSON_PERMISSIVE
)
4551 if (reterr_bad_field
)
4552 *reterr_bad_field
= NULL
;
4558 for (const JsonDispatch
*p
= table
; p
->name
; p
++)
4561 found
= newa0(bool, m
);
4563 size_t n
= json_variant_elements(v
);
4564 for (size_t i
= 0; i
< n
; i
+= 2) {
4565 JsonVariant
*key
, *value
;
4566 const JsonDispatch
*p
;
4568 assert_se(key
= json_variant_by_index(v
, i
));
4569 assert_se(value
= json_variant_by_index(v
, i
+1));
4571 for (p
= table
; p
->name
; p
++)
4572 if (p
->name
== POINTER_MAX
||
4573 streq_ptr(json_variant_string(key
), p
->name
))
4576 if (p
->name
) { /* Found a matching entry! 🙂 */
4577 JsonDispatchFlags merged_flags
;
4579 merged_flags
= flags
| p
->flags
;
4581 if (p
->type
!= _JSON_VARIANT_TYPE_INVALID
&&
4582 !json_variant_has_type(value
, p
->type
)) {
4584 json_log(value
, merged_flags
, 0,
4585 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key
),
4586 json_variant_type_to_string(json_variant_type(value
)), json_variant_type_to_string(p
->type
));
4588 if (merged_flags
& JSON_PERMISSIVE
)
4591 if (reterr_bad_field
)
4592 *reterr_bad_field
= p
->name
;
4597 if (found
[p
-table
]) {
4598 json_log(value
, merged_flags
, 0, "Duplicate object field '%s'.", json_variant_string(key
));
4600 if (merged_flags
& JSON_PERMISSIVE
)
4603 if (reterr_bad_field
)
4604 *reterr_bad_field
= p
->name
;
4609 found
[p
-table
] = true;
4612 r
= p
->callback(json_variant_string(key
), value
, merged_flags
, dispatch_userdata(p
, userdata
));
4614 if (merged_flags
& JSON_PERMISSIVE
)
4617 if (reterr_bad_field
)
4618 *reterr_bad_field
= json_variant_string(key
);
4626 } else { /* Didn't find a matching entry! ☹️ */
4629 r
= bad(json_variant_string(key
), value
, flags
, userdata
);
4631 if (flags
& JSON_PERMISSIVE
)
4634 if (reterr_bad_field
)
4635 *reterr_bad_field
= json_variant_string(key
);
4642 if (flags
& JSON_ALLOW_EXTENSIONS
) {
4643 json_log(value
, flags
|JSON_DEBUG
, 0, "Unrecognized object field '%s', assuming extension.", json_variant_string(key
));
4647 json_log(value
, flags
, 0, "Unexpected object field '%s'.", json_variant_string(key
));
4648 if (flags
& JSON_PERMISSIVE
)
4651 if (reterr_bad_field
)
4652 *reterr_bad_field
= json_variant_string(key
);
4654 return -EADDRNOTAVAIL
;
4659 for (const JsonDispatch
*p
= table
; p
->name
; p
++) {
4660 JsonDispatchFlags merged_flags
= p
->flags
| flags
;
4662 if ((merged_flags
& JSON_MANDATORY
) && !found
[p
-table
]) {
4663 json_log(v
, merged_flags
, 0, "Missing object field '%s'.", p
->name
);
4665 if ((merged_flags
& JSON_PERMISSIVE
))
4668 if (reterr_bad_field
)
4669 *reterr_bad_field
= p
->name
;
4678 int json_dispatch_boolean(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4679 bool *b
= ASSERT_PTR(userdata
);
4683 if (!json_variant_is_boolean(variant
))
4684 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a boolean.", strna(name
));
4686 *b
= json_variant_boolean(variant
);
4690 int json_dispatch_tristate(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4691 int *b
= ASSERT_PTR(userdata
);
4695 if (json_variant_is_null(variant
)) {
4700 if (!json_variant_is_boolean(variant
))
4701 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a boolean.", strna(name
));
4703 *b
= json_variant_boolean(variant
);
4707 int json_dispatch_int64(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4708 int64_t *i
= ASSERT_PTR(userdata
);
4712 /* Also accept numbers formatted as string, to increase compatibility with less capable JSON
4713 * implementations that cannot do 64bit integers. */
4714 if (json_variant_is_string(variant
) && safe_atoi64(json_variant_string(variant
), i
) >= 0)
4717 if (!json_variant_is_integer(variant
))
4718 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an integer, nor one formatted as decimal string.", strna(name
));
4720 *i
= json_variant_integer(variant
);
4724 int json_dispatch_uint64(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4725 uint64_t *u
= ASSERT_PTR(userdata
);
4729 /* Since 64bit values (in particular unsigned ones) in JSON are problematic, let's also accept them
4730 * formatted as strings. If this is not desired make sure to set the .type field in JsonDispatch to
4731 * JSON_UNSIGNED rather than _JSON_VARIANT_TYPE_INVALID, so that json_dispatch() already filters out
4732 * the non-matching type. */
4734 if (json_variant_is_string(variant
) && safe_atou64(json_variant_string(variant
), u
) >= 0)
4737 if (!json_variant_is_unsigned(variant
))
4738 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an unsigned integer, nor one formatted as decimal string.", strna(name
));
4740 *u
= json_variant_unsigned(variant
);
4744 int json_dispatch_uint32(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4745 uint32_t *u
= ASSERT_PTR(userdata
);
4751 r
= json_dispatch_uint64(name
, variant
, flags
, &u64
);
4755 if (u64
> UINT32_MAX
)
4756 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4758 *u
= (uint32_t) u64
;
4762 int json_dispatch_int32(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4763 int32_t *i
= ASSERT_PTR(userdata
);
4769 r
= json_dispatch_int64(name
, variant
, flags
, &i64
);
4773 if (i64
< INT32_MIN
|| i64
> INT32_MAX
)
4774 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4780 int json_dispatch_int16(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4781 int16_t *i
= ASSERT_PTR(userdata
);
4787 r
= json_dispatch_int64(name
, variant
, flags
, &i64
);
4791 if (i64
< INT16_MIN
|| i64
> INT16_MAX
)
4792 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4798 int json_dispatch_uint16(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4799 uint16_t *u
= ASSERT_PTR(userdata
);
4805 r
= json_dispatch_uint64(name
, variant
, flags
, &u64
);
4809 if (u64
> UINT16_MAX
)
4810 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4812 *u
= (uint16_t) u64
;
4816 int json_dispatch_int8(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4817 int8_t *i
= ASSERT_PTR(userdata
);
4823 r
= json_dispatch_int64(name
, variant
, flags
, &i64
);
4827 if (i64
< INT8_MIN
|| i64
> INT8_MAX
)
4828 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4834 int json_dispatch_uint8(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4835 uint8_t *u
= ASSERT_PTR(userdata
);
4841 r
= json_dispatch_uint64(name
, variant
, flags
, &u64
);
4845 if (u64
> UINT8_MAX
)
4846 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4852 int json_dispatch_string(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4853 char **s
= ASSERT_PTR(userdata
);
4858 if (json_variant_is_null(variant
)) {
4863 if (!json_variant_is_string(variant
))
4864 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4866 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4867 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4869 r
= free_and_strdup(s
, json_variant_string(variant
));
4871 return json_log(variant
, flags
, r
, "Failed to allocate string: %m");
4876 int json_dispatch_const_string(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4877 const char **s
= ASSERT_PTR(userdata
);
4881 if (json_variant_is_null(variant
)) {
4886 if (!json_variant_is_string(variant
))
4887 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4889 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4890 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4892 *s
= json_variant_string(variant
);
4896 int json_dispatch_strv(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4897 _cleanup_strv_free_
char **l
= NULL
;
4898 char ***s
= ASSERT_PTR(userdata
);
4904 if (json_variant_is_null(variant
)) {
4909 /* Let's be flexible here: accept a single string in place of a single-item array */
4910 if (json_variant_is_string(variant
)) {
4911 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4912 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4914 l
= strv_new(json_variant_string(variant
));
4918 strv_free_and_replace(*s
, l
);
4922 if (!json_variant_is_array(variant
))
4923 return json_log(variant
, SYNTHETIC_ERRNO(EINVAL
), flags
, "JSON field '%s' is not an array.", strna(name
));
4925 JSON_VARIANT_ARRAY_FOREACH(e
, variant
) {
4926 if (!json_variant_is_string(e
))
4927 return json_log(e
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON array element is not a string.");
4929 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(e
)))
4930 return json_log(e
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4932 r
= strv_extend(&l
, json_variant_string(e
));
4934 return json_log(e
, flags
, r
, "Failed to append array element: %m");
4937 strv_free_and_replace(*s
, l
);
4941 int json_dispatch_variant(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4942 JsonVariant
**p
= ASSERT_PTR(userdata
);
4945 /* Takes a reference */
4946 JSON_VARIANT_REPLACE(*p
, json_variant_ref(variant
));
4950 int json_dispatch_variant_noref(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4951 JsonVariant
**p
= ASSERT_PTR(userdata
);
4954 /* Doesn't take a reference */
4959 int json_dispatch_uid_gid(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4960 uid_t
*uid
= userdata
;
4963 assert_cc(sizeof(uid_t
) == sizeof(uint32_t));
4964 assert_cc(sizeof(gid_t
) == sizeof(uint32_t));
4966 DISABLE_WARNING_TYPE_LIMITS
;
4967 assert_cc((UID_INVALID
< (uid_t
) 0) == (GID_INVALID
< (gid_t
) 0));
4970 if (json_variant_is_null(variant
)) {
4975 if (!json_variant_is_unsigned(variant
))
4976 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an integer.", strna(name
));
4978 k
= json_variant_unsigned(variant
);
4979 if (k
> UINT32_MAX
|| !uid_is_valid(k
))
4980 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid UID/GID.", strna(name
));
4986 int json_dispatch_user_group_name(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4987 char **s
= userdata
;
4991 if (json_variant_is_null(variant
)) {
4996 if (!json_variant_is_string(variant
))
4997 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4999 n
= json_variant_string(variant
);
5000 if (!valid_user_group_name(n
, FLAGS_SET(flags
, JSON_RELAX
) ? VALID_USER_RELAX
: 0))
5001 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid user/group name.", strna(name
));
5003 r
= free_and_strdup(s
, n
);
5005 return json_log(variant
, flags
, r
, "Failed to allocate string: %m");
5010 int json_dispatch_absolute_path(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
5012 char **p
= ASSERT_PTR(userdata
);
5016 if (!json_variant_is_string(variant
))
5017 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
5019 path
= json_variant_string(variant
);
5020 if (!path_is_valid(path
))
5021 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid path.", strna(name
));
5022 if (!path_is_absolute(path
))
5023 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' must be an absolute path.", strna(name
));
5025 if (free_and_strdup(p
, path
) < 0)
5026 return json_log_oom(variant
, flags
);
5031 int json_dispatch_id128(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
5032 sd_id128_t
*uuid
= userdata
;
5035 if (json_variant_is_null(variant
)) {
5036 *uuid
= SD_ID128_NULL
;
5040 if (!json_variant_is_string(variant
))
5041 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
5043 r
= sd_id128_from_string(json_variant_string(variant
), uuid
);
5045 return json_log(variant
, flags
, r
, "JSON field '%s' is not a valid UID.", strna(name
));
5050 int json_dispatch_unsupported(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
5051 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not allowed in this object.", strna(name
));
5054 int json_dispatch_unbase64_iovec(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
5055 _cleanup_free_
void *buffer
= NULL
;
5056 struct iovec
*iov
= ASSERT_PTR(userdata
);
5060 if (!json_variant_is_string(variant
))
5061 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
5063 r
= json_variant_unbase64(variant
, &buffer
, &sz
);
5065 return json_log(variant
, flags
, r
, "JSON field '%s' is not valid Base64 data.", strna(name
));
5067 free_and_replace(iov
->iov_base
, buffer
);
5072 int json_dispatch_byte_array_iovec(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
5073 _cleanup_free_
uint8_t *buffer
= NULL
;
5074 struct iovec
*iov
= ASSERT_PTR(userdata
);
5079 if (!json_variant_is_array(variant
))
5080 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an array.", strna(name
));
5082 sz
= json_variant_elements(variant
);
5084 buffer
= new(uint8_t, sz
+ 1);
5086 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ENOMEM
), "Out of memory.");
5089 JSON_VARIANT_ARRAY_FOREACH(i
, variant
) {
5092 if (!json_variant_is_unsigned(i
))
5093 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "Element %zu of JSON field '%s' is not an unsigned integer.", k
, strna(name
));
5095 b
= json_variant_unsigned(i
);
5097 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
),
5098 "Element %zu of JSON field '%s' is out of range 0%s255.",
5099 k
, strna(name
), special_glyph(SPECIAL_GLYPH_ELLIPSIS
));
5101 buffer
[k
++] = (uint8_t) b
;
5105 /* Append a NUL byte for safety, like we do in memdup_suffix0() and others. */
5108 free_and_replace(iov
->iov_base
, buffer
);
5113 int json_dispatch_in_addr(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
5114 struct in_addr
*address
= ASSERT_PTR(userdata
);
5115 _cleanup_(iovec_done
) struct iovec iov
= {};
5118 r
= json_dispatch_byte_array_iovec(name
, variant
, flags
, &iov
);
5122 if (iov
.iov_len
!= sizeof(struct in_addr
))
5123 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is array of unexpected size.", strna(name
));
5125 memcpy(address
, iov
.iov_base
, iov
.iov_len
);
5129 static int json_cmp_strings(const void *x
, const void *y
) {
5130 JsonVariant
*const *a
= x
, *const *b
= y
;
5132 if (!json_variant_is_string(*a
) || !json_variant_is_string(*b
))
5135 return strcmp(json_variant_string(*a
), json_variant_string(*b
));
5138 int json_variant_sort(JsonVariant
**v
) {
5139 _cleanup_free_ JsonVariant
**a
= NULL
;
5140 _cleanup_(json_variant_unrefp
) JsonVariant
*n
= NULL
;
5146 if (json_variant_is_sorted(*v
))
5149 if (!json_variant_is_object(*v
))
5150 return -EMEDIUMTYPE
;
5152 /* Sorts they key/value pairs in an object variant */
5154 m
= json_variant_elements(*v
);
5155 a
= new(JsonVariant
*, m
);
5159 for (size_t i
= 0; i
< m
; i
++)
5160 a
[i
] = json_variant_by_index(*v
, i
);
5162 qsort(a
, m
/2, sizeof(JsonVariant
*)*2, json_cmp_strings
);
5164 r
= json_variant_new_object(&n
, a
, m
);
5168 json_variant_propagate_sensitive(*v
, n
);
5170 if (!n
->sorted
) /* Check if this worked. This will fail if there are multiple identical keys used. */
5173 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(n
));
5178 int json_variant_normalize(JsonVariant
**v
) {
5179 _cleanup_free_ JsonVariant
**a
= NULL
;
5180 _cleanup_(json_variant_unrefp
) JsonVariant
*n
= NULL
;
5186 if (json_variant_is_normalized(*v
))
5189 if (!json_variant_is_object(*v
) && !json_variant_is_array(*v
))
5190 return -EMEDIUMTYPE
;
5192 /* Sorts the key/value pairs in an object variant anywhere down the tree in the specified variant */
5194 m
= json_variant_elements(*v
);
5195 a
= new(JsonVariant
*, m
);
5199 for (i
= 0; i
< m
; ) {
5200 a
[i
] = json_variant_ref(json_variant_by_index(*v
, i
));
5203 r
= json_variant_normalize(&a
[i
-1]);
5208 qsort(a
, m
/2, sizeof(JsonVariant
*)*2, json_cmp_strings
);
5210 if (json_variant_is_object(*v
))
5211 r
= json_variant_new_object(&n
, a
, m
);
5213 assert(json_variant_is_array(*v
));
5214 r
= json_variant_new_array(&n
, a
, m
);
5219 json_variant_propagate_sensitive(*v
, n
);
5221 if (!n
->normalized
) { /* Let's see if normalization worked. It will fail if there are multiple
5222 * identical keys used in the same object anywhere, or if there are floating
5223 * point numbers used (see below) */
5228 JSON_VARIANT_REPLACE(*v
, TAKE_PTR(n
));
5233 for (size_t j
= 0; j
< i
; j
++)
5234 json_variant_unref(a
[j
]);
5239 bool json_variant_is_normalized(JsonVariant
*v
) {
5240 /* For now, let's consider anything containing numbers not expressible as integers as non-normalized.
5241 * That's because we cannot sensibly compare them due to accuracy issues, nor even store them if they
5243 if (json_variant_is_real(v
) && !json_variant_is_integer(v
) && !json_variant_is_unsigned(v
))
5246 /* The concept only applies to variants that include other variants, i.e. objects and arrays. All
5247 * others are normalized anyway. */
5248 if (!json_variant_is_object(v
) && !json_variant_is_array(v
))
5251 /* Empty objects/arrays don't include any other variant, hence are always normalized too */
5252 if (json_variant_elements(v
) == 0)
5255 return v
->normalized
; /* For everything else there's an explicit boolean we maintain */
5258 bool json_variant_is_sorted(JsonVariant
*v
) {
5260 /* Returns true if all key/value pairs of an object are properly sorted. Note that this only applies
5261 * to objects, not arrays. */
5263 if (!json_variant_is_object(v
))
5265 if (json_variant_elements(v
) <= 1)
5271 int json_variant_unbase64(JsonVariant
*v
, void **ret
, size_t *ret_size
) {
5272 if (!json_variant_is_string(v
))
5275 return unbase64mem(json_variant_string(v
), ret
, ret_size
);
5278 int json_variant_unhex(JsonVariant
*v
, void **ret
, size_t *ret_size
) {
5279 if (!json_variant_is_string(v
))
5282 return unhexmem(json_variant_string(v
), ret
, ret_size
);
5285 static const char* const json_variant_type_table
[_JSON_VARIANT_TYPE_MAX
] = {
5286 [JSON_VARIANT_STRING
] = "string",
5287 [JSON_VARIANT_INTEGER
] = "integer",
5288 [JSON_VARIANT_UNSIGNED
] = "unsigned",
5289 [JSON_VARIANT_REAL
] = "real",
5290 [JSON_VARIANT_NUMBER
] = "number",
5291 [JSON_VARIANT_BOOLEAN
] = "boolean",
5292 [JSON_VARIANT_ARRAY
] = "array",
5293 [JSON_VARIANT_OBJECT
] = "object",
5294 [JSON_VARIANT_NULL
] = "null",
5297 DEFINE_STRING_TABLE_LOOKUP(json_variant_type
, JsonVariantType
);