1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
10 #include "sd-messages.h"
12 #include "alloc-util.h"
13 #include "errno-util.h"
17 #include "hexdecoct.h"
18 #include "json-internal.h"
21 #include "memory-util.h"
22 #include "string-table.h"
23 #include "string-util.h"
25 #include "terminal-util.h"
26 #include "user-util.h"
29 /* Refuse putting together variants with a larger depth than 2K by default (as a protection against overflowing stacks
30 * if code processes JSON objects recursively. Note that we store the depth in an uint16_t, hence make sure this
33 * The value first was 16k, but it was discovered to be too high on llvm/x86-64. See also:
34 * https://github.com/systemd/systemd/issues/10738
36 * The value then was 4k, but it was discovered to be too high on s390x/aarch64. See also:
37 * https://github.com/systemd/systemd/issues/14396 */
39 #define DEPTH_MAX (2U*1024U)
40 assert_cc(DEPTH_MAX
<= UINT16_MAX
);
42 typedef struct JsonSource
{
43 /* When we parse from a file or similar, encodes the filename, to indicate the source of a json variant */
50 /* On x86-64 this whole structure should have a size of 6 * 64 bit = 48 bytes */
53 /* We either maintain a reference counter for this variant itself, or we are embedded into an
54 * array/object, in which case only that surrounding object is ref-counted. (If 'embedded' is false,
58 /* If this JsonVariant is part of an array/object, then this field points to the surrounding
59 * JSON_VARIANT_ARRAY/JSON_VARIANT_OBJECT object. (If 'embedded' is true, see below.) */
63 /* If this was parsed from some file or buffer, this stores where from, as well as the source line/column */
65 unsigned line
, column
;
67 /* The current 'depth' of the JsonVariant, i.e. how many levels of member variants this has */
70 JsonVariantType type
:8;
72 /* A marker whether this variant is embedded into in array/object or not. If true, the 'parent' pointer above
73 * is valid. If false, the 'n_ref' field above is valid instead. */
76 /* In some conditions (for example, if this object is part of an array of strings or objects), we don't store
77 * any data inline, but instead simply reference an external object and act as surrogate of it. In that case
78 * this bool is set, and the external object is referenced through the .reference field below. */
81 /* While comparing two arrays, we use this for marking what we already have seen */
84 /* Erase from memory when freeing */
87 /* If this is an object the fields are strictly ordered by name */
90 /* If in addition to this object all objects referenced by it are also ordered strictly by name */
94 /* For simple types we store the value in-line. */
97 /* For objects and arrays we store the number of elements immediately following */
100 /* If is_reference as indicated above is set, this is where the reference object is actually stored. */
101 JsonVariant
*reference
;
103 /* Strings are placed immediately after the structure. Note that when this is a JsonVariant embedded
104 * into an array we might encode strings up to INLINE_STRING_LENGTH characters directly inside the
105 * element, while longer strings are stored as references. When this object is not embedded into an
106 * array, but stand-alone we allocate the right size for the whole structure, i.e. the array might be
107 * much larger than INLINE_STRING_LENGTH.
109 * Note that because we want to allocate arrays of the JsonVariant structure we specify [0] here,
110 * rather than the prettier []. If we wouldn't, then this char array would have undefined size, and so
111 * would the union and then the struct this is included in. And of structures with undefined size we
112 * can't allocate arrays (at least not easily). */
117 /* Inside string arrays we have a series of JasonVariant structures one after the other. In this case, strings longer
118 * than INLINE_STRING_MAX are stored as references, and all shorter ones inline. (This means — on x86-64 — strings up
119 * to 15 chars are stored within the array elements, and all others in separate allocations) */
120 #define INLINE_STRING_MAX (sizeof(JsonVariant) - offsetof(JsonVariant, string) - 1U)
122 /* Let's make sure this structure isn't increased in size accidentally. This check is only for our most relevant arch
125 assert_cc(sizeof(JsonVariant
) == 48U);
126 assert_cc(INLINE_STRING_MAX
== 15U);
129 static JsonSource
* json_source_new(const char *name
) {
134 s
= malloc(offsetof(JsonSource
, name
) + strlen(name
) + 1);
141 strcpy(s
->name
, name
);
146 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(JsonSource
, json_source
, mfree
);
148 static bool json_source_equal(JsonSource
*a
, JsonSource
*b
) {
155 return streq(a
->name
, b
->name
);
158 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonSource
*, json_source_unref
);
160 /* There are four kind of JsonVariant* pointers:
163 * 2. A 'regular' one, i.e. pointing to malloc() memory
164 * 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.
165 * 4. A 'const string' one, i.e. a pointer to a const string.
167 * The four kinds of pointers can be discerned like this:
169 * Detecting #1 is easy, just compare with NULL. Detecting #3 is similarly easy: all magic pointers are below
170 * _JSON_VARIANT_MAGIC_MAX (which is pretty low, within the first memory page, which is special on Linux and other
171 * 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,
172 * otherwise #4. This makes use of the fact that malloc() will return "maximum aligned" memory, which definitely
173 * means the pointer is even. This means we can use the uneven pointers to reference static strings, as long as we
174 * make sure that all static strings used like this are aligned to 2 (or higher), and that we mask the bit on
175 * access. The JSON_VARIANT_STRING_CONST() macro encodes strings as JsonVariant* pointers, with the bit set. */
177 static bool json_variant_is_magic(const JsonVariant
*v
) {
181 return v
< _JSON_VARIANT_MAGIC_MAX
;
184 static bool json_variant_is_const_string(const JsonVariant
*v
) {
186 if (v
< _JSON_VARIANT_MAGIC_MAX
)
189 /* A proper JsonVariant is aligned to whatever malloc() aligns things too, which is definitely not uneven. We
190 * hence use all uneven pointers as indicators for const strings. */
192 return (((uintptr_t) v
) & 1) != 0;
195 static bool json_variant_is_regular(const JsonVariant
*v
) {
197 if (v
< _JSON_VARIANT_MAGIC_MAX
)
200 return (((uintptr_t) v
) & 1) == 0;
203 static JsonVariant
*json_variant_dereference(JsonVariant
*v
) {
205 /* Recursively dereference variants that are references to other variants */
210 if (!json_variant_is_regular(v
))
213 if (!v
->is_reference
)
216 return json_variant_dereference(v
->reference
);
219 static uint16_t json_variant_depth(JsonVariant
*v
) {
221 v
= json_variant_dereference(v
);
225 if (!json_variant_is_regular(v
))
231 static JsonVariant
*json_variant_formalize(JsonVariant
*v
) {
233 /* Converts json variant pointers to their normalized form, i.e. fully dereferenced and wherever
234 * possible converted to the "magic" version if there is one */
239 v
= json_variant_dereference(v
);
241 switch (json_variant_type(v
)) {
243 case JSON_VARIANT_BOOLEAN
:
244 return json_variant_boolean(v
) ? JSON_VARIANT_MAGIC_TRUE
: JSON_VARIANT_MAGIC_FALSE
;
246 case JSON_VARIANT_NULL
:
247 return JSON_VARIANT_MAGIC_NULL
;
249 case JSON_VARIANT_INTEGER
:
250 return json_variant_integer(v
) == 0 ? JSON_VARIANT_MAGIC_ZERO_INTEGER
: v
;
252 case JSON_VARIANT_UNSIGNED
:
253 return json_variant_unsigned(v
) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED
: v
;
255 case JSON_VARIANT_REAL
:
256 DISABLE_WARNING_FLOAT_EQUAL
;
257 return json_variant_real(v
) == 0.0 ? JSON_VARIANT_MAGIC_ZERO_REAL
: v
;
260 case JSON_VARIANT_STRING
:
261 return isempty(json_variant_string(v
)) ? JSON_VARIANT_MAGIC_EMPTY_STRING
: v
;
263 case JSON_VARIANT_ARRAY
:
264 return json_variant_elements(v
) == 0 ? JSON_VARIANT_MAGIC_EMPTY_ARRAY
: v
;
266 case JSON_VARIANT_OBJECT
:
267 return json_variant_elements(v
) == 0 ? JSON_VARIANT_MAGIC_EMPTY_OBJECT
: v
;
274 static JsonVariant
*json_variant_conservative_formalize(JsonVariant
*v
) {
276 /* Much like json_variant_formalize(), but won't simplify if the variant has a source/line location attached to
277 * it, in order not to lose context */
282 if (!json_variant_is_regular(v
))
285 if (v
->source
|| v
->line
> 0 || v
->column
> 0)
288 return json_variant_formalize(v
);
291 static int json_variant_new(JsonVariant
**ret
, JsonVariantType type
, size_t space
) {
294 assert_return(ret
, -EINVAL
);
296 v
= malloc0(MAX(sizeof(JsonVariant
),
297 offsetof(JsonVariant
, value
) + space
));
308 int json_variant_new_integer(JsonVariant
**ret
, intmax_t i
) {
312 assert_return(ret
, -EINVAL
);
315 *ret
= JSON_VARIANT_MAGIC_ZERO_INTEGER
;
319 r
= json_variant_new(&v
, JSON_VARIANT_INTEGER
, sizeof(i
));
323 v
->value
.integer
= i
;
329 int json_variant_new_unsigned(JsonVariant
**ret
, uintmax_t u
) {
333 assert_return(ret
, -EINVAL
);
335 *ret
= JSON_VARIANT_MAGIC_ZERO_UNSIGNED
;
339 r
= json_variant_new(&v
, JSON_VARIANT_UNSIGNED
, sizeof(u
));
349 int json_variant_new_real(JsonVariant
**ret
, long double d
) {
353 assert_return(ret
, -EINVAL
);
355 DISABLE_WARNING_FLOAT_EQUAL
;
357 *ret
= JSON_VARIANT_MAGIC_ZERO_REAL
;
362 r
= json_variant_new(&v
, JSON_VARIANT_REAL
, sizeof(d
));
372 int json_variant_new_boolean(JsonVariant
**ret
, bool b
) {
373 assert_return(ret
, -EINVAL
);
376 *ret
= JSON_VARIANT_MAGIC_TRUE
;
378 *ret
= JSON_VARIANT_MAGIC_FALSE
;
383 int json_variant_new_null(JsonVariant
**ret
) {
384 assert_return(ret
, -EINVAL
);
386 *ret
= JSON_VARIANT_MAGIC_NULL
;
390 int json_variant_new_stringn(JsonVariant
**ret
, const char *s
, size_t n
) {
394 assert_return(ret
, -EINVAL
);
396 assert_return(IN_SET(n
, 0, (size_t) -1), -EINVAL
);
397 return json_variant_new_null(ret
);
399 if (n
== (size_t) -1) /* determine length automatically */
401 else if (memchr(s
, 0, n
)) /* don't allow embedded NUL, as we can't express that in JSON */
404 *ret
= JSON_VARIANT_MAGIC_EMPTY_STRING
;
408 if (!utf8_is_valid_n(s
, n
)) /* JSON strings must be valid UTF-8 */
411 r
= json_variant_new(&v
, JSON_VARIANT_STRING
, n
+ 1);
415 memcpy(v
->string
, s
, n
);
422 int json_variant_new_base64(JsonVariant
**ret
, const void *p
, size_t n
) {
423 _cleanup_free_
char *s
= NULL
;
426 assert_return(ret
, -EINVAL
);
427 assert_return(n
== 0 || p
, -EINVAL
);
429 k
= base64mem(p
, n
, &s
);
433 return json_variant_new_stringn(ret
, s
, k
);
436 int json_variant_new_hex(JsonVariant
**ret
, const void *p
, size_t n
) {
437 _cleanup_free_
char *s
= NULL
;
439 assert_return(ret
, -EINVAL
);
440 assert_return(n
== 0 || p
, -EINVAL
);
446 return json_variant_new_stringn(ret
, s
, n
*2);
449 int json_variant_new_id128(JsonVariant
**ret
, sd_id128_t id
) {
450 char s
[SD_ID128_STRING_MAX
];
452 return json_variant_new_string(ret
, sd_id128_to_string(id
, s
));
455 static void json_variant_set(JsonVariant
*a
, JsonVariant
*b
) {
458 b
= json_variant_dereference(b
);
460 a
->type
= JSON_VARIANT_NULL
;
464 a
->type
= json_variant_type(b
);
467 case JSON_VARIANT_INTEGER
:
468 a
->value
.integer
= json_variant_integer(b
);
471 case JSON_VARIANT_UNSIGNED
:
472 a
->value
.unsig
= json_variant_unsigned(b
);
475 case JSON_VARIANT_REAL
:
476 a
->value
.real
= json_variant_real(b
);
479 case JSON_VARIANT_BOOLEAN
:
480 a
->value
.boolean
= json_variant_boolean(b
);
483 case JSON_VARIANT_STRING
: {
486 assert_se(s
= json_variant_string(b
));
488 /* Short strings we can store inline */
489 if (strnlen(s
, INLINE_STRING_MAX
+1) <= INLINE_STRING_MAX
) {
490 strcpy(a
->string
, s
);
494 /* For longer strings, use a reference… */
498 case JSON_VARIANT_ARRAY
:
499 case JSON_VARIANT_OBJECT
:
500 a
->is_reference
= true;
501 a
->reference
= json_variant_ref(json_variant_conservative_formalize(b
));
504 case JSON_VARIANT_NULL
:
508 assert_not_reached("Unexpected variant type");
512 static void json_variant_copy_source(JsonVariant
*v
, JsonVariant
*from
) {
516 if (!json_variant_is_regular(from
))
519 v
->line
= from
->line
;
520 v
->column
= from
->column
;
521 v
->source
= json_source_ref(from
->source
);
524 int json_variant_new_array(JsonVariant
**ret
, JsonVariant
**array
, size_t n
) {
525 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
526 bool normalized
= true;
528 assert_return(ret
, -EINVAL
);
530 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
533 assert_return(array
, -EINVAL
);
535 v
= new(JsonVariant
, n
+ 1);
541 .type
= JSON_VARIANT_ARRAY
,
544 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
545 JsonVariant
*w
= v
+ 1 + v
->n_elements
,
546 *c
= array
[v
->n_elements
];
549 d
= json_variant_depth(c
);
550 if (d
>= DEPTH_MAX
) /* Refuse too deep nesting */
560 json_variant_set(w
, c
);
561 json_variant_copy_source(w
, c
);
563 if (!json_variant_is_normalized(c
))
567 v
->normalized
= normalized
;
573 int json_variant_new_array_bytes(JsonVariant
**ret
, const void *p
, size_t n
) {
577 assert_return(ret
, -EINVAL
);
579 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
582 assert_return(p
, -EINVAL
);
584 v
= new(JsonVariant
, n
+ 1);
590 .type
= JSON_VARIANT_ARRAY
,
595 for (i
= 0; i
< n
; i
++) {
596 JsonVariant
*w
= v
+ 1 + i
;
601 .type
= JSON_VARIANT_UNSIGNED
,
602 .value
.unsig
= ((const uint8_t*) p
)[i
],
606 v
->normalized
= true;
612 int json_variant_new_array_strv(JsonVariant
**ret
, char **l
) {
613 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
621 *ret
= JSON_VARIANT_MAGIC_EMPTY_ARRAY
;
625 v
= new(JsonVariant
, n
+ 1);
631 .type
= JSON_VARIANT_ARRAY
,
635 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
636 JsonVariant
*w
= v
+ 1 + v
->n_elements
;
642 .type
= JSON_VARIANT_STRING
,
645 k
= strlen(l
[v
->n_elements
]);
647 if (k
> INLINE_STRING_MAX
) {
648 /* If string is too long, store it as reference. */
650 r
= json_variant_new_string(&w
->reference
, l
[v
->n_elements
]);
654 w
->is_reference
= true;
656 if (!utf8_is_valid_n(l
[v
->n_elements
], k
)) /* JSON strings must be valid UTF-8 */
659 memcpy(w
->string
, l
[v
->n_elements
], k
+1);
663 v
->normalized
= true;
669 int json_variant_new_object(JsonVariant
**ret
, JsonVariant
**array
, size_t n
) {
670 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
671 const char *prev
= NULL
;
672 bool sorted
= true, normalized
= true;
674 assert_return(ret
, -EINVAL
);
676 *ret
= JSON_VARIANT_MAGIC_EMPTY_OBJECT
;
679 assert_return(array
, -EINVAL
);
680 assert_return(n
% 2 == 0, -EINVAL
);
682 v
= new(JsonVariant
, n
+ 1);
688 .type
= JSON_VARIANT_OBJECT
,
691 for (v
->n_elements
= 0; v
->n_elements
< n
; v
->n_elements
++) {
692 JsonVariant
*w
= v
+ 1 + v
->n_elements
,
693 *c
= array
[v
->n_elements
];
696 if ((v
->n_elements
& 1) == 0) {
699 if (!json_variant_is_string(c
))
700 return -EINVAL
; /* Every second one needs to be a string, as it is the key name */
702 assert_se(k
= json_variant_string(c
));
704 if (prev
&& strcmp(k
, prev
) <= 0)
705 sorted
= normalized
= false;
708 } else if (!json_variant_is_normalized(c
))
711 d
= json_variant_depth(c
);
712 if (d
>= DEPTH_MAX
) /* Refuse too deep nesting */
722 json_variant_set(w
, c
);
723 json_variant_copy_source(w
, c
);
726 v
->normalized
= normalized
;
733 static size_t json_variant_size(JsonVariant
* v
) {
735 if (!json_variant_is_regular(v
))
739 return offsetof(JsonVariant
, reference
) + sizeof(JsonVariant
*);
743 case JSON_VARIANT_STRING
:
744 return offsetof(JsonVariant
, string
) + strlen(v
->string
) + 1;
746 case JSON_VARIANT_REAL
:
747 return offsetof(JsonVariant
, value
) + sizeof(long double);
749 case JSON_VARIANT_UNSIGNED
:
750 return offsetof(JsonVariant
, value
) + sizeof(uintmax_t);
752 case JSON_VARIANT_INTEGER
:
753 return offsetof(JsonVariant
, value
) + sizeof(intmax_t);
755 case JSON_VARIANT_BOOLEAN
:
756 return offsetof(JsonVariant
, value
) + sizeof(bool);
758 case JSON_VARIANT_ARRAY
:
759 case JSON_VARIANT_OBJECT
:
760 return offsetof(JsonVariant
, n_elements
) + sizeof(size_t);
762 case JSON_VARIANT_NULL
:
763 return offsetof(JsonVariant
, value
);
766 assert_not_reached("unexpected type");
770 static void json_variant_free_inner(JsonVariant
*v
, bool force_sensitive
) {
775 if (!json_variant_is_regular(v
))
778 json_source_unref(v
->source
);
780 sensitive
= v
->sensitive
|| force_sensitive
;
782 if (v
->is_reference
) {
784 json_variant_sensitive(v
->reference
);
786 json_variant_unref(v
->reference
);
790 if (IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
)) {
793 for (i
= 0; i
< v
->n_elements
; i
++)
794 json_variant_free_inner(v
+ 1 + i
, sensitive
);
798 explicit_bzero_safe(v
, json_variant_size(v
));
801 JsonVariant
*json_variant_ref(JsonVariant
*v
) {
804 if (!json_variant_is_regular(v
))
808 json_variant_ref(v
->parent
); /* ref the compounding variant instead */
810 assert(v
->n_ref
> 0);
817 JsonVariant
*json_variant_unref(JsonVariant
*v
) {
820 if (!json_variant_is_regular(v
))
824 json_variant_unref(v
->parent
);
826 assert(v
->n_ref
> 0);
830 json_variant_free_inner(v
, false);
838 void json_variant_unref_many(JsonVariant
**array
, size_t n
) {
841 assert(array
|| n
== 0);
843 for (i
= 0; i
< n
; i
++)
844 json_variant_unref(array
[i
]);
847 const char *json_variant_string(JsonVariant
*v
) {
850 if (v
== JSON_VARIANT_MAGIC_EMPTY_STRING
)
852 if (json_variant_is_magic(v
))
854 if (json_variant_is_const_string(v
)) {
855 uintptr_t p
= (uintptr_t) v
;
857 assert((p
& 1) != 0);
858 return (const char*) (p
^ 1U);
862 return json_variant_string(v
->reference
);
863 if (v
->type
!= JSON_VARIANT_STRING
)
869 log_debug("Non-string JSON variant requested as string, returning NULL.");
873 bool json_variant_boolean(JsonVariant
*v
) {
876 if (v
== JSON_VARIANT_MAGIC_TRUE
)
878 if (v
== JSON_VARIANT_MAGIC_FALSE
)
880 if (!json_variant_is_regular(v
))
882 if (v
->type
!= JSON_VARIANT_BOOLEAN
)
885 return json_variant_boolean(v
->reference
);
887 return v
->value
.boolean
;
890 log_debug("Non-boolean JSON variant requested as boolean, returning false.");
894 intmax_t json_variant_integer(JsonVariant
*v
) {
897 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
898 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
899 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
901 if (!json_variant_is_regular(v
))
904 return json_variant_integer(v
->reference
);
908 case JSON_VARIANT_INTEGER
:
909 return v
->value
.integer
;
911 case JSON_VARIANT_UNSIGNED
:
912 if (v
->value
.unsig
<= INTMAX_MAX
)
913 return (intmax_t) v
->value
.unsig
;
915 log_debug("Unsigned integer %ju requested as signed integer and out of range, returning 0.", v
->value
.unsig
);
918 case JSON_VARIANT_REAL
: {
921 converted
= (intmax_t) v
->value
.real
;
923 DISABLE_WARNING_FLOAT_EQUAL
;
924 if ((long double) converted
== v
->value
.real
)
928 log_debug("Real %Lg requested as integer, and cannot be converted losslessly, returning 0.", v
->value
.real
);
937 log_debug("Non-integer JSON variant requested as integer, returning 0.");
941 uintmax_t json_variant_unsigned(JsonVariant
*v
) {
944 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
945 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
946 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
948 if (!json_variant_is_regular(v
))
951 return json_variant_integer(v
->reference
);
955 case JSON_VARIANT_INTEGER
:
956 if (v
->value
.integer
>= 0)
957 return (uintmax_t) v
->value
.integer
;
959 log_debug("Signed integer %ju requested as unsigned integer and out of range, returning 0.", v
->value
.integer
);
962 case JSON_VARIANT_UNSIGNED
:
963 return v
->value
.unsig
;
965 case JSON_VARIANT_REAL
: {
968 converted
= (uintmax_t) v
->value
.real
;
970 DISABLE_WARNING_FLOAT_EQUAL
;
971 if ((long double) converted
== v
->value
.real
)
975 log_debug("Real %Lg requested as unsigned integer, and cannot be converted losslessly, returning 0.", v
->value
.real
);
984 log_debug("Non-integer JSON variant requested as unsigned, returning 0.");
988 long double json_variant_real(JsonVariant
*v
) {
991 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
992 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
993 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
995 if (!json_variant_is_regular(v
))
998 return json_variant_real(v
->reference
);
1002 case JSON_VARIANT_REAL
:
1003 return v
->value
.real
;
1005 case JSON_VARIANT_INTEGER
: {
1006 long double converted
;
1008 converted
= (long double) v
->value
.integer
;
1010 if ((intmax_t) converted
== v
->value
.integer
)
1013 log_debug("Signed integer %ji requested as real, and cannot be converted losslessly, returning 0.", v
->value
.integer
);
1017 case JSON_VARIANT_UNSIGNED
: {
1018 long double converted
;
1020 converted
= (long double) v
->value
.unsig
;
1022 if ((uintmax_t) converted
== v
->value
.unsig
)
1025 log_debug("Unsigned integer %ju requested as real, and cannot be converted losslessly, returning 0.", v
->value
.unsig
);
1034 log_debug("Non-integer JSON variant requested as integer, returning 0.");
1038 bool json_variant_is_negative(JsonVariant
*v
) {
1041 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
||
1042 v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
||
1043 v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1045 if (!json_variant_is_regular(v
))
1047 if (v
->is_reference
)
1048 return json_variant_is_negative(v
->reference
);
1050 /* This function is useful as checking whether numbers are negative is pretty complex since we have three types
1051 * of numbers. And some JSON code (OCI for example) uses negative numbers to mark "not defined" numeric
1056 case JSON_VARIANT_REAL
:
1057 return v
->value
.real
< 0;
1059 case JSON_VARIANT_INTEGER
:
1060 return v
->value
.integer
< 0;
1062 case JSON_VARIANT_UNSIGNED
:
1070 log_debug("Non-integer JSON variant tested for negativity, returning false.");
1074 bool json_variant_is_blank_object(JsonVariant
*v
) {
1075 /* Returns true if the specified object is null or empty */
1077 json_variant_is_null(v
) ||
1078 (json_variant_is_object(v
) && json_variant_elements(v
) == 0);
1081 bool json_variant_is_blank_array(JsonVariant
*v
) {
1083 json_variant_is_null(v
) ||
1084 (json_variant_is_array(v
) && json_variant_elements(v
) == 0);
1087 JsonVariantType
json_variant_type(JsonVariant
*v
) {
1090 return _JSON_VARIANT_TYPE_INVALID
;
1092 if (json_variant_is_const_string(v
))
1093 return JSON_VARIANT_STRING
;
1095 if (v
== JSON_VARIANT_MAGIC_TRUE
|| v
== JSON_VARIANT_MAGIC_FALSE
)
1096 return JSON_VARIANT_BOOLEAN
;
1098 if (v
== JSON_VARIANT_MAGIC_NULL
)
1099 return JSON_VARIANT_NULL
;
1101 if (v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
)
1102 return JSON_VARIANT_INTEGER
;
1104 if (v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
)
1105 return JSON_VARIANT_UNSIGNED
;
1107 if (v
== JSON_VARIANT_MAGIC_ZERO_REAL
)
1108 return JSON_VARIANT_REAL
;
1110 if (v
== JSON_VARIANT_MAGIC_EMPTY_STRING
)
1111 return JSON_VARIANT_STRING
;
1113 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
)
1114 return JSON_VARIANT_ARRAY
;
1116 if (v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1117 return JSON_VARIANT_OBJECT
;
1122 _function_no_sanitize_float_cast_overflow_
bool json_variant_has_type(JsonVariant
*v
, JsonVariantType type
) {
1125 /* Note: we turn off ubsan float cast overflo detection for this function, since it would complain
1126 * about our float casts but we do them explicitly to detect conversion errors. */
1128 v
= json_variant_dereference(v
);
1132 rt
= json_variant_type(v
);
1136 /* If it's a const string, then it only can be a string, and if it is not, it's not */
1137 if (json_variant_is_const_string(v
))
1140 /* All three magic zeroes qualify as integer, unsigned and as real */
1141 if ((v
== JSON_VARIANT_MAGIC_ZERO_INTEGER
|| v
== JSON_VARIANT_MAGIC_ZERO_UNSIGNED
|| v
== JSON_VARIANT_MAGIC_ZERO_REAL
) &&
1142 IN_SET(type
, JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
, JSON_VARIANT_NUMBER
))
1145 /* All other magic variant types are only equal to themselves */
1146 if (json_variant_is_magic(v
))
1149 /* Handle the "number" pseudo type */
1150 if (type
== JSON_VARIANT_NUMBER
)
1151 return IN_SET(rt
, JSON_VARIANT_INTEGER
, JSON_VARIANT_UNSIGNED
, JSON_VARIANT_REAL
);
1153 /* Integer conversions are OK in many cases */
1154 if (rt
== JSON_VARIANT_INTEGER
&& type
== JSON_VARIANT_UNSIGNED
)
1155 return v
->value
.integer
>= 0;
1156 if (rt
== JSON_VARIANT_UNSIGNED
&& type
== JSON_VARIANT_INTEGER
)
1157 return v
->value
.unsig
<= INTMAX_MAX
;
1159 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1160 if (rt
== JSON_VARIANT_INTEGER
&& type
== JSON_VARIANT_REAL
)
1161 return (intmax_t) (long double) v
->value
.integer
== v
->value
.integer
;
1162 if (rt
== JSON_VARIANT_UNSIGNED
&& type
== JSON_VARIANT_REAL
)
1163 return (uintmax_t) (long double) v
->value
.unsig
== v
->value
.unsig
;
1165 DISABLE_WARNING_FLOAT_EQUAL
;
1167 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1168 if (rt
== JSON_VARIANT_REAL
&& type
== JSON_VARIANT_INTEGER
)
1169 return (long double) (intmax_t) v
->value
.real
== v
->value
.real
;
1170 if (rt
== JSON_VARIANT_REAL
&& type
== JSON_VARIANT_UNSIGNED
)
1171 return (long double) (uintmax_t) v
->value
.real
== v
->value
.real
;
1178 size_t json_variant_elements(JsonVariant
*v
) {
1181 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
||
1182 v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1184 if (!json_variant_is_regular(v
))
1186 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1188 if (v
->is_reference
)
1189 return json_variant_elements(v
->reference
);
1191 return v
->n_elements
;
1194 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1198 JsonVariant
*json_variant_by_index(JsonVariant
*v
, size_t idx
) {
1201 if (v
== JSON_VARIANT_MAGIC_EMPTY_ARRAY
||
1202 v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1204 if (!json_variant_is_regular(v
))
1206 if (!IN_SET(v
->type
, JSON_VARIANT_ARRAY
, JSON_VARIANT_OBJECT
))
1208 if (v
->is_reference
)
1209 return json_variant_by_index(v
->reference
, idx
);
1210 if (idx
>= v
->n_elements
)
1213 return json_variant_conservative_formalize(v
+ 1 + idx
);
1216 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1220 JsonVariant
*json_variant_by_key_full(JsonVariant
*v
, const char *key
, JsonVariant
**ret_key
) {
1227 if (v
== JSON_VARIANT_MAGIC_EMPTY_OBJECT
)
1229 if (!json_variant_is_regular(v
))
1231 if (v
->type
!= JSON_VARIANT_OBJECT
)
1233 if (v
->is_reference
)
1234 return json_variant_by_key(v
->reference
, key
);
1237 size_t a
= 0, b
= v
->n_elements
/2;
1239 /* If the variant is sorted we can use bisection to find the entry we need in O(log(n)) time */
1247 p
= json_variant_dereference(v
+ 1 + i
*2);
1249 assert_se(f
= json_variant_string(p
));
1254 *ret_key
= json_variant_conservative_formalize(v
+ 1 + i
*2);
1256 return json_variant_conservative_formalize(v
+ 1 + i
*2 + 1);
1266 /* The variant is not sorted, hence search for the field linearly */
1267 for (i
= 0; i
< v
->n_elements
; i
+= 2) {
1270 p
= json_variant_dereference(v
+ 1 + i
);
1272 if (!json_variant_has_type(p
, JSON_VARIANT_STRING
))
1275 if (streq(json_variant_string(p
), key
)) {
1278 *ret_key
= json_variant_conservative_formalize(v
+ 1 + i
);
1280 return json_variant_conservative_formalize(v
+ 1 + i
+ 1);
1291 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1298 JsonVariant
*json_variant_by_key(JsonVariant
*v
, const char *key
) {
1299 return json_variant_by_key_full(v
, key
, NULL
);
1302 bool json_variant_equal(JsonVariant
*a
, JsonVariant
*b
) {
1305 a
= json_variant_formalize(a
);
1306 b
= json_variant_formalize(b
);
1311 t
= json_variant_type(a
);
1312 if (!json_variant_has_type(b
, t
))
1317 case JSON_VARIANT_STRING
:
1318 return streq(json_variant_string(a
), json_variant_string(b
));
1320 case JSON_VARIANT_INTEGER
:
1321 return json_variant_integer(a
) == json_variant_integer(b
);
1323 case JSON_VARIANT_UNSIGNED
:
1324 return json_variant_unsigned(a
) == json_variant_unsigned(b
);
1326 case JSON_VARIANT_REAL
:
1327 DISABLE_WARNING_FLOAT_EQUAL
;
1328 return json_variant_real(a
) == json_variant_real(b
);
1331 case JSON_VARIANT_BOOLEAN
:
1332 return json_variant_boolean(a
) == json_variant_boolean(b
);
1334 case JSON_VARIANT_NULL
:
1337 case JSON_VARIANT_ARRAY
: {
1340 n
= json_variant_elements(a
);
1341 if (n
!= json_variant_elements(b
))
1344 for (i
= 0; i
< n
; i
++) {
1345 if (!json_variant_equal(json_variant_by_index(a
, i
), json_variant_by_index(b
, i
)))
1352 case JSON_VARIANT_OBJECT
: {
1355 n
= json_variant_elements(a
);
1356 if (n
!= json_variant_elements(b
))
1359 /* Iterate through all keys in 'a' */
1360 for (i
= 0; i
< n
; i
+= 2) {
1364 /* Match them against all keys in 'b' */
1365 for (j
= 0; j
< n
; j
+= 2) {
1368 key_b
= json_variant_by_index(b
, j
);
1370 /* During the first iteration unmark everything */
1372 key_b
->is_marked
= false;
1373 else if (key_b
->is_marked
) /* In later iterations if we already marked something, don't bother with it again */
1379 if (json_variant_equal(json_variant_by_index(a
, i
), key_b
) &&
1380 json_variant_equal(json_variant_by_index(a
, i
+1), json_variant_by_index(b
, j
+1))) {
1381 /* Key and values match! */
1382 key_b
->is_marked
= found
= true;
1384 /* In the first iteration we continue the inner loop since we want to mark
1385 * everything, otherwise exit the loop quickly after we found what we were
1400 assert_not_reached("Unknown variant type.");
1404 void json_variant_sensitive(JsonVariant
*v
) {
1407 /* Marks a variant as "sensitive", so that it is erased from memory when it is destroyed. This is a
1408 * one-way operation: as soon as it is marked this way it remains marked this way until it's
1409 * destroyed. A magic variant is never sensitive though, even when asked, since it's too
1410 * basic. Similar, const string variant are never sensitive either, after all they are included in
1411 * the source code as they are, which is not suitable for inclusion of secrets.
1413 * Note that this flag has a recursive effect: when we destroy an object or array we'll propagate the
1414 * flag to all contained variants. And if those are then destroyed this is propagated further down,
1417 v
= json_variant_formalize(v
);
1418 if (!json_variant_is_regular(v
))
1421 v
->sensitive
= true;
1424 bool json_variant_is_sensitive(JsonVariant
*v
) {
1425 v
= json_variant_formalize(v
);
1426 if (!json_variant_is_regular(v
))
1429 return v
->sensitive
;
1432 static void json_variant_propagate_sensitive(JsonVariant
*from
, JsonVariant
*to
) {
1433 if (json_variant_is_sensitive(from
))
1434 json_variant_sensitive(to
);
1437 int json_variant_get_source(JsonVariant
*v
, const char **ret_source
, unsigned *ret_line
, unsigned *ret_column
) {
1438 assert_return(v
, -EINVAL
);
1441 *ret_source
= json_variant_is_regular(v
) && v
->source
? v
->source
->name
: NULL
;
1444 *ret_line
= json_variant_is_regular(v
) ? v
->line
: 0;
1447 *ret_column
= json_variant_is_regular(v
) ? v
->column
: 0;
1452 static int print_source(FILE *f
, JsonVariant
*v
, JsonFormatFlags flags
, bool whitespace
) {
1455 if (!FLAGS_SET(flags
, JSON_FORMAT_SOURCE
|JSON_FORMAT_PRETTY
))
1458 if (!json_variant_is_regular(v
))
1461 if (!v
->source
&& v
->line
== 0 && v
->column
== 0)
1464 /* The max width we need to format the line numbers for this source file */
1465 w
= (v
->source
&& v
->source
->max_line
> 0) ?
1466 DECIMAL_STR_WIDTH(v
->source
->max_line
) :
1467 DECIMAL_STR_MAX(unsigned)-1;
1468 k
= (v
->source
&& v
->source
->max_column
> 0) ?
1469 DECIMAL_STR_WIDTH(v
->source
->max_column
) :
1470 DECIMAL_STR_MAX(unsigned) -1;
1475 n
= 1 + (v
->source
? strlen(v
->source
->name
) : 0) +
1476 ((v
->source
&& (v
->line
> 0 || v
->column
> 0)) ? 1 : 0) +
1477 (v
->line
> 0 ? w
: 0) +
1478 (((v
->source
|| v
->line
> 0) && v
->column
> 0) ? 1 : 0) +
1479 (v
->column
> 0 ? k
: 0) +
1482 for (i
= 0; i
< n
; i
++)
1488 fputs(v
->source
->name
, f
);
1489 if (v
->source
&& (v
->line
> 0 || v
->column
> 0))
1492 fprintf(f
, "%*u", (int) w
, v
->line
);
1493 if ((v
->source
|| v
->line
> 0) || v
->column
> 0)
1496 fprintf(f
, "%*u", (int) k
, v
->column
);
1505 static void json_format_string(FILE *f
, const char *q
, JsonFormatFlags flags
) {
1510 if (flags
& JSON_FORMAT_COLOR
)
1511 fputs(ansi_green(), f
);
1544 if ((signed char) *q
>= 0 && *q
< ' ')
1545 fprintf(f
, "\\u%04x", *q
);
1551 if (flags
& JSON_FORMAT_COLOR
)
1552 fputs(ANSI_NORMAL
, f
);
1557 static int json_format(FILE *f
, JsonVariant
*v
, JsonFormatFlags flags
, const char *prefix
) {
1563 switch (json_variant_type(v
)) {
1565 case JSON_VARIANT_REAL
: {
1568 loc
= newlocale(LC_NUMERIC_MASK
, "C", (locale_t
) 0);
1569 if (loc
== (locale_t
) 0)
1572 if (flags
& JSON_FORMAT_COLOR
)
1573 fputs(ansi_highlight_blue(), f
);
1575 fprintf(f
, "%.*Le", DECIMAL_DIG
, json_variant_real(v
));
1577 if (flags
& JSON_FORMAT_COLOR
)
1578 fputs(ANSI_NORMAL
, f
);
1584 case JSON_VARIANT_INTEGER
:
1585 if (flags
& JSON_FORMAT_COLOR
)
1586 fputs(ansi_highlight_blue(), f
);
1588 fprintf(f
, "%" PRIdMAX
, json_variant_integer(v
));
1590 if (flags
& JSON_FORMAT_COLOR
)
1591 fputs(ANSI_NORMAL
, f
);
1594 case JSON_VARIANT_UNSIGNED
:
1595 if (flags
& JSON_FORMAT_COLOR
)
1596 fputs(ansi_highlight_blue(), f
);
1598 fprintf(f
, "%" PRIuMAX
, json_variant_unsigned(v
));
1600 if (flags
& JSON_FORMAT_COLOR
)
1601 fputs(ANSI_NORMAL
, f
);
1604 case JSON_VARIANT_BOOLEAN
:
1606 if (flags
& JSON_FORMAT_COLOR
)
1607 fputs(ANSI_HIGHLIGHT
, f
);
1609 if (json_variant_boolean(v
))
1614 if (flags
& JSON_FORMAT_COLOR
)
1615 fputs(ANSI_NORMAL
, f
);
1619 case JSON_VARIANT_NULL
:
1620 if (flags
& JSON_FORMAT_COLOR
)
1621 fputs(ANSI_HIGHLIGHT
, f
);
1625 if (flags
& JSON_FORMAT_COLOR
)
1626 fputs(ANSI_NORMAL
, f
);
1629 case JSON_VARIANT_STRING
:
1630 json_format_string(f
, json_variant_string(v
), flags
);
1633 case JSON_VARIANT_ARRAY
: {
1636 n
= json_variant_elements(v
);
1641 _cleanup_free_
char *joined
= NULL
;
1642 const char *prefix2
;
1644 if (flags
& JSON_FORMAT_PRETTY
) {
1645 joined
= strjoin(strempty(prefix
), "\t");
1652 prefix2
= strempty(prefix
);
1656 for (i
= 0; i
< n
; i
++) {
1659 assert_se(e
= json_variant_by_index(v
, i
));
1662 if (flags
& JSON_FORMAT_PRETTY
)
1668 if (flags
& JSON_FORMAT_PRETTY
) {
1669 print_source(f
, e
, flags
, false);
1673 r
= json_format(f
, e
, flags
, prefix2
);
1678 if (flags
& JSON_FORMAT_PRETTY
) {
1680 print_source(f
, v
, flags
, true);
1681 fputs(strempty(prefix
), f
);
1689 case JSON_VARIANT_OBJECT
: {
1692 n
= json_variant_elements(v
);
1697 _cleanup_free_
char *joined
= NULL
;
1698 const char *prefix2
;
1700 if (flags
& JSON_FORMAT_PRETTY
) {
1701 joined
= strjoin(strempty(prefix
), "\t");
1708 prefix2
= strempty(prefix
);
1712 for (i
= 0; i
< n
; i
+= 2) {
1715 e
= json_variant_by_index(v
, i
);
1718 if (flags
& JSON_FORMAT_PRETTY
)
1724 if (flags
& JSON_FORMAT_PRETTY
) {
1725 print_source(f
, e
, flags
, false);
1729 r
= json_format(f
, e
, flags
, prefix2
);
1733 fputs(flags
& JSON_FORMAT_PRETTY
? " : " : ":", f
);
1735 r
= json_format(f
, json_variant_by_index(v
, i
+1), flags
, prefix2
);
1740 if (flags
& JSON_FORMAT_PRETTY
) {
1742 print_source(f
, v
, flags
, true);
1743 fputs(strempty(prefix
), f
);
1752 assert_not_reached("Unexpected variant type.");
1758 int json_variant_format(JsonVariant
*v
, JsonFormatFlags flags
, char **ret
) {
1759 _cleanup_free_
char *s
= NULL
;
1763 /* Returns the length of the generated string (without the terminating NUL),
1764 * or negative on error. */
1766 assert_return(v
, -EINVAL
);
1767 assert_return(ret
, -EINVAL
);
1769 if (flags
& JSON_FORMAT_OFF
)
1773 _cleanup_fclose_
FILE *f
= NULL
;
1775 f
= open_memstream_unlocked(&s
, &sz
);
1779 json_variant_dump(v
, flags
, f
, NULL
);
1781 /* Add terminating 0, so that the output buffer is a valid string. */
1784 r
= fflush_and_check(f
);
1792 return (int) sz
- 1;
1795 void json_variant_dump(JsonVariant
*v
, JsonFormatFlags flags
, FILE *f
, const char *prefix
) {
1802 print_source(f
, v
, flags
, false);
1804 if (((flags
& (JSON_FORMAT_COLOR_AUTO
|JSON_FORMAT_COLOR
)) == JSON_FORMAT_COLOR_AUTO
) && colors_enabled())
1805 flags
|= JSON_FORMAT_COLOR
;
1807 if (((flags
& (JSON_FORMAT_PRETTY_AUTO
|JSON_FORMAT_PRETTY
)) == JSON_FORMAT_PRETTY_AUTO
))
1808 flags
|= on_tty() ? JSON_FORMAT_PRETTY
: JSON_FORMAT_NEWLINE
;
1810 if (flags
& JSON_FORMAT_SSE
)
1812 if (flags
& JSON_FORMAT_SEQ
)
1813 fputc('\x1e', f
); /* ASCII Record Separator */
1815 json_format(f
, v
, flags
, prefix
);
1817 if (flags
& (JSON_FORMAT_PRETTY
|JSON_FORMAT_SEQ
|JSON_FORMAT_SSE
|JSON_FORMAT_NEWLINE
))
1819 if (flags
& JSON_FORMAT_SSE
)
1820 fputc('\n', f
); /* In case of SSE add a second newline */
1822 if (flags
& JSON_FORMAT_FLUSH
)
1826 int json_variant_filter(JsonVariant
**v
, char **to_remove
) {
1827 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
1828 _cleanup_free_ JsonVariant
**array
= NULL
;
1829 size_t i
, n
= 0, k
= 0;
1834 if (json_variant_is_blank_object(*v
))
1836 if (!json_variant_is_object(*v
))
1839 if (strv_isempty(to_remove
))
1842 for (i
= 0; i
< json_variant_elements(*v
); i
+= 2) {
1845 p
= json_variant_by_index(*v
, i
);
1846 if (!json_variant_has_type(p
, JSON_VARIANT_STRING
))
1849 if (strv_contains(to_remove
, json_variant_string(p
))) {
1851 array
= new(JsonVariant
*, json_variant_elements(*v
) - 2);
1855 for (k
= 0; k
< i
; k
++)
1856 array
[k
] = json_variant_by_index(*v
, k
);
1862 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
1869 r
= json_variant_new_object(&w
, array
, k
);
1873 json_variant_propagate_sensitive(*v
, w
);
1875 json_variant_unref(*v
);
1881 int json_variant_set_field(JsonVariant
**v
, const char *field
, JsonVariant
*value
) {
1882 _cleanup_(json_variant_unrefp
) JsonVariant
*field_variant
= NULL
, *w
= NULL
;
1883 _cleanup_free_ JsonVariant
**array
= NULL
;
1890 if (json_variant_is_blank_object(*v
)) {
1891 array
= new(JsonVariant
*, 2);
1896 if (!json_variant_is_object(*v
))
1899 for (i
= 0; i
< json_variant_elements(*v
); i
+= 2) {
1902 p
= json_variant_by_index(*v
, i
);
1903 if (!json_variant_is_string(p
))
1906 if (streq(json_variant_string(p
), field
)) {
1909 array
= new(JsonVariant
*, json_variant_elements(*v
));
1913 for (k
= 0; k
< i
; k
++)
1914 array
[k
] = json_variant_by_index(*v
, k
);
1919 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
1924 array
= new(JsonVariant
*, json_variant_elements(*v
) + 2);
1928 for (k
= 0; k
< json_variant_elements(*v
); k
++)
1929 array
[k
] = json_variant_by_index(*v
, k
);
1933 r
= json_variant_new_string(&field_variant
, field
);
1937 array
[k
++] = field_variant
;
1940 r
= json_variant_new_object(&w
, array
, k
);
1944 json_variant_propagate_sensitive(*v
, w
);
1946 json_variant_unref(*v
);
1952 int json_variant_set_field_string(JsonVariant
**v
, const char *field
, const char *value
) {
1953 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
1956 r
= json_variant_new_string(&m
, value
);
1960 return json_variant_set_field(v
, field
, m
);
1963 int json_variant_set_field_integer(JsonVariant
**v
, const char *field
, intmax_t i
) {
1964 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
1967 r
= json_variant_new_integer(&m
, i
);
1971 return json_variant_set_field(v
, field
, m
);
1974 int json_variant_set_field_unsigned(JsonVariant
**v
, const char *field
, uintmax_t u
) {
1975 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
1978 r
= json_variant_new_unsigned(&m
, u
);
1982 return json_variant_set_field(v
, field
, m
);
1985 int json_variant_set_field_boolean(JsonVariant
**v
, const char *field
, bool b
) {
1986 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
1989 r
= json_variant_new_boolean(&m
, b
);
1993 return json_variant_set_field(v
, field
, m
);
1996 int json_variant_set_field_strv(JsonVariant
**v
, const char *field
, char **l
) {
1997 _cleanup_(json_variant_unrefp
) JsonVariant
*m
= NULL
;
2000 r
= json_variant_new_array_strv(&m
, l
);
2004 return json_variant_set_field(v
, field
, m
);
2007 int json_variant_merge(JsonVariant
**v
, JsonVariant
*m
) {
2008 _cleanup_(json_variant_unrefp
) JsonVariant
*w
= NULL
;
2009 _cleanup_free_ JsonVariant
**array
= NULL
;
2010 size_t v_elements
, m_elements
, i
, k
;
2011 bool v_blank
, m_blank
;
2014 m
= json_variant_dereference(m
);
2016 v_blank
= json_variant_is_blank_object(*v
);
2017 m_blank
= json_variant_is_blank_object(m
);
2019 if (!v_blank
&& !json_variant_is_object(*v
))
2021 if (!m_blank
&& !json_variant_is_object(m
))
2025 return 0; /* nothing to do */
2028 json_variant_unref(*v
);
2029 *v
= json_variant_ref(m
);
2033 v_elements
= json_variant_elements(*v
);
2034 m_elements
= json_variant_elements(m
);
2035 if (v_elements
> SIZE_MAX
- m_elements
) /* overflow check */
2038 array
= new(JsonVariant
*, v_elements
+ m_elements
);
2043 for (i
= 0; i
< v_elements
; i
+= 2) {
2046 u
= json_variant_by_index(*v
, i
);
2047 if (!json_variant_is_string(u
))
2050 if (json_variant_by_key(m
, json_variant_string(u
)))
2051 continue; /* skip if exists in second variant */
2054 array
[k
++] = json_variant_by_index(*v
, i
+ 1);
2057 for (i
= 0; i
< m_elements
; i
++)
2058 array
[k
++] = json_variant_by_index(m
, i
);
2060 r
= json_variant_new_object(&w
, array
, k
);
2064 json_variant_propagate_sensitive(*v
, w
);
2065 json_variant_propagate_sensitive(m
, w
);
2067 json_variant_unref(*v
);
2073 int json_variant_append_array(JsonVariant
**v
, JsonVariant
*element
) {
2074 _cleanup_(json_variant_unrefp
) JsonVariant
*nv
= NULL
;
2082 if (!*v
|| json_variant_is_null(*v
))
2084 else if (!json_variant_is_array(*v
))
2087 blank
= json_variant_elements(*v
) == 0;
2090 r
= json_variant_new_array(&nv
, (JsonVariant
*[]) { element
}, 1);
2092 _cleanup_free_ JsonVariant
**array
= NULL
;
2095 array
= new(JsonVariant
*, json_variant_elements(*v
) + 1);
2099 for (i
= 0; i
< json_variant_elements(*v
); i
++)
2100 array
[i
] = json_variant_by_index(*v
, i
);
2104 r
= json_variant_new_array(&nv
, array
, i
+ 1);
2109 json_variant_propagate_sensitive(*v
, nv
);
2111 json_variant_unref(*v
);
2117 int json_variant_strv(JsonVariant
*v
, char ***ret
) {
2125 if (!v
|| json_variant_is_null(v
)) {
2134 if (!json_variant_is_array(v
))
2137 sensitive
= v
->sensitive
;
2139 n
= json_variant_elements(v
);
2140 l
= new(char*, n
+1);
2144 for (i
= 0; i
< n
; i
++) {
2147 assert_se(e
= json_variant_by_index(v
, i
));
2148 sensitive
= sensitive
|| e
->sensitive
;
2150 if (!json_variant_is_string(e
)) {
2156 l
[i
] = strdup(json_variant_string(e
));
2177 static int json_variant_copy(JsonVariant
**nv
, JsonVariant
*v
) {
2187 /* Let's copy the simple types literally, and the larger types by references */
2188 t
= json_variant_type(v
);
2190 case JSON_VARIANT_INTEGER
:
2191 k
= sizeof(intmax_t);
2192 value
.integer
= json_variant_integer(v
);
2196 case JSON_VARIANT_UNSIGNED
:
2197 k
= sizeof(uintmax_t);
2198 value
.unsig
= json_variant_unsigned(v
);
2202 case JSON_VARIANT_REAL
:
2203 k
= sizeof(long double);
2204 value
.real
= json_variant_real(v
);
2208 case JSON_VARIANT_BOOLEAN
:
2210 value
.boolean
= json_variant_boolean(v
);
2214 case JSON_VARIANT_NULL
:
2219 case JSON_VARIANT_STRING
:
2220 source
= json_variant_string(v
);
2221 k
= strnlen(source
, INLINE_STRING_MAX
+ 1);
2222 if (k
<= INLINE_STRING_MAX
) {
2230 /* Everything else copy by reference */
2232 c
= malloc0(MAX(sizeof(JsonVariant
),
2233 offsetof(JsonVariant
, reference
) + sizeof(JsonVariant
*)));
2239 c
->is_reference
= true;
2240 c
->reference
= json_variant_ref(json_variant_formalize(v
));
2246 c
= malloc0(MAX(sizeof(JsonVariant
),
2247 offsetof(JsonVariant
, value
) + k
));
2254 memcpy_safe(&c
->value
, source
, k
);
2256 json_variant_propagate_sensitive(v
, c
);
2262 static bool json_single_ref(JsonVariant
*v
) {
2264 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
2266 if (!json_variant_is_regular(v
))
2270 return json_single_ref(v
->parent
);
2272 assert(v
->n_ref
> 0);
2273 return v
->n_ref
== 1;
2276 static int json_variant_set_source(JsonVariant
**v
, JsonSource
*source
, unsigned line
, unsigned column
) {
2282 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole referencer of
2283 * the object. If not, allocates a new object, possibly a surrogate for the original one */
2288 if (source
&& line
> source
->max_line
)
2289 source
->max_line
= line
;
2290 if (source
&& column
> source
->max_column
)
2291 source
->max_column
= column
;
2293 if (!json_variant_is_regular(*v
)) {
2295 if (!source
&& line
== 0 && column
== 0)
2299 if (json_source_equal((*v
)->source
, source
) &&
2300 (*v
)->line
== line
&&
2301 (*v
)->column
== column
)
2304 if (json_single_ref(*v
)) { /* Sole reference? */
2305 json_source_unref((*v
)->source
);
2306 (*v
)->source
= json_source_ref(source
);
2308 (*v
)->column
= column
;
2313 r
= json_variant_copy(&w
, *v
);
2317 assert(json_variant_is_regular(w
));
2318 assert(!w
->is_embedded
);
2319 assert(w
->n_ref
== 1);
2322 w
->source
= json_source_ref(source
);
2326 json_variant_unref(*v
);
2332 static void inc_lines_columns(unsigned *line
, unsigned *column
, const char *s
, size_t n
) {
2335 assert(s
|| n
== 0);
2341 } else if ((signed char) *s
>= 0 && *s
< 127) /* Process ASCII chars quickly */
2346 w
= utf8_encoded_valid_unichar(s
, n
);
2347 if (w
< 0) /* count invalid unichars as normal characters */
2349 else if ((size_t) w
> n
) /* never read more than the specified number of characters */
2364 static int unhex_ucs2(const char *c
, uint16_t *ret
) {
2371 aa
= unhexchar(c
[0]);
2375 bb
= unhexchar(c
[1]);
2379 cc
= unhexchar(c
[2]);
2383 dd
= unhexchar(c
[3]);
2387 x
= ((uint16_t) aa
<< 12) |
2388 ((uint16_t) bb
<< 8) |
2389 ((uint16_t) cc
<< 4) |
2400 static int json_parse_string(const char **p
, char **ret
) {
2401 _cleanup_free_
char *s
= NULL
;
2402 size_t n
= 0, allocated
= 0;
2423 /* Check for control characters 0x00..0x1f */
2424 if (*c
> 0 && *c
< ' ')
2427 /* Check for control character 0x7f */
2442 return JSON_TOKEN_STRING
;
2452 if (IN_SET(*c
, '"', '\\', '/'))
2464 else if (*c
== 'u') {
2468 r
= unhex_ucs2(c
+ 1, &x
);
2474 if (!GREEDY_REALLOC(s
, allocated
, n
+ 5))
2477 if (!utf16_is_surrogate(x
))
2478 n
+= utf8_encode_unichar(s
+ n
, (char32_t
) x
);
2479 else if (utf16_is_trailing_surrogate(x
))
2484 if (c
[0] != '\\' || c
[1] != 'u')
2487 r
= unhex_ucs2(c
+ 2, &y
);
2493 if (!utf16_is_trailing_surrogate(y
))
2496 n
+= utf8_encode_unichar(s
+ n
, utf16_surrogate_pair_to_unichar(x
, y
));
2503 if (!GREEDY_REALLOC(s
, allocated
, n
+ 2))
2511 len
= utf8_encoded_valid_unichar(c
, (size_t) -1);
2515 if (!GREEDY_REALLOC(s
, allocated
, n
+ len
+ 1))
2518 memcpy(s
+ n
, c
, len
);
2524 static int json_parse_number(const char **p
, JsonValue
*ret
) {
2525 bool negative
= false, exponent_negative
= false, is_real
= false;
2526 long double x
= 0.0, y
= 0.0, exponent
= 0.0, shift
= 1.0;
2545 if (!strchr("123456789", *c
) || *c
== 0)
2552 if (i
< INTMAX_MIN
/ 10) /* overflow */
2555 intmax_t t
= 10 * i
;
2557 if (t
< INTMAX_MIN
+ (*c
- '0')) /* overflow */
2563 if (u
> UINTMAX_MAX
/ 10) /* overflow */
2566 uintmax_t t
= 10 * u
;
2568 if (t
> UINTMAX_MAX
- (*c
- '0')) /* overflow */
2576 x
= 10.0 * x
+ (*c
- '0');
2579 } while (strchr("0123456789", *c
) && *c
!= 0);
2586 if (!strchr("0123456789", *c
) || *c
== 0)
2590 y
= 10.0 * y
+ (*c
- '0');
2591 shift
= 10.0 * shift
;
2593 } while (strchr("0123456789", *c
) && *c
!= 0);
2596 if (IN_SET(*c
, 'e', 'E')) {
2601 exponent_negative
= true;
2603 } else if (*c
== '+')
2606 if (!strchr("0123456789", *c
) || *c
== 0)
2610 exponent
= 10.0 * exponent
+ (*c
- '0');
2612 } while (strchr("0123456789", *c
) && *c
!= 0);
2618 ret
->real
= ((negative
? -1.0 : 1.0) * (x
+ (y
/ shift
))) * exp10l((exponent_negative
? -1.0 : 1.0) * exponent
);
2619 return JSON_TOKEN_REAL
;
2620 } else if (negative
) {
2622 return JSON_TOKEN_INTEGER
;
2625 return JSON_TOKEN_UNSIGNED
;
2632 JsonValue
*ret_value
,
2633 unsigned *ret_line
, /* 'ret_line' returns the line at the beginning of this token */
2634 unsigned *ret_column
,
2636 unsigned *line
, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2639 unsigned start_line
, start_column
;
2640 const char *start
, *c
;
2660 t
= PTR_TO_INT(*state
);
2661 if (t
== STATE_NULL
) {
2667 /* Skip over the whitespace */
2668 n
= strspn(*p
, WHITESPACE
);
2669 inc_lines_columns(line
, column
, *p
, n
);
2672 /* Remember where we started processing this token */
2675 start_column
= *column
;
2679 *ret_value
= JSON_VALUE_NULL
;
2690 *state
= INT_TO_PTR(STATE_VALUE
);
2691 r
= JSON_TOKEN_OBJECT_OPEN
;
2694 } else if (*c
== '}') {
2696 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2697 r
= JSON_TOKEN_OBJECT_CLOSE
;
2700 } else if (*c
== '[') {
2702 *state
= INT_TO_PTR(STATE_VALUE
);
2703 r
= JSON_TOKEN_ARRAY_OPEN
;
2706 } else if (*c
== ']') {
2708 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2709 r
= JSON_TOKEN_ARRAY_CLOSE
;
2712 } else if (*c
== '"') {
2714 r
= json_parse_string(&c
, ret_string
);
2718 *ret_value
= JSON_VALUE_NULL
;
2719 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2722 } else if (strchr("-0123456789", *c
)) {
2724 r
= json_parse_number(&c
, ret_value
);
2729 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2732 } else if (startswith(c
, "true")) {
2734 ret_value
->boolean
= true;
2736 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2737 r
= JSON_TOKEN_BOOLEAN
;
2740 } else if (startswith(c
, "false")) {
2742 ret_value
->boolean
= false;
2744 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2745 r
= JSON_TOKEN_BOOLEAN
;
2748 } else if (startswith(c
, "null")) {
2750 *ret_value
= JSON_VALUE_NULL
;
2752 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2753 r
= JSON_TOKEN_NULL
;
2760 case STATE_VALUE_POST
:
2764 *state
= INT_TO_PTR(STATE_VALUE
);
2765 r
= JSON_TOKEN_COLON
;
2768 } else if (*c
== ',') {
2770 *state
= INT_TO_PTR(STATE_VALUE
);
2771 r
= JSON_TOKEN_COMMA
;
2774 } else if (*c
== '}') {
2776 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2777 r
= JSON_TOKEN_OBJECT_CLOSE
;
2780 } else if (*c
== ']') {
2782 *state
= INT_TO_PTR(STATE_VALUE_POST
);
2783 r
= JSON_TOKEN_ARRAY_CLOSE
;
2790 assert_not_reached("Unexpected tokenizer state");
2795 *ret_value
= JSON_VALUE_NULL
;
2798 inc_lines_columns(line
, column
, start
, c
- start
);
2801 *ret_line
= start_line
;
2802 *ret_column
= start_column
;
2807 typedef enum JsonExpect
{
2808 /* The following values are used by json_parse() */
2811 EXPECT_OBJECT_FIRST_KEY
,
2812 EXPECT_OBJECT_NEXT_KEY
,
2813 EXPECT_OBJECT_COLON
,
2814 EXPECT_OBJECT_VALUE
,
2815 EXPECT_OBJECT_COMMA
,
2816 EXPECT_ARRAY_FIRST_ELEMENT
,
2817 EXPECT_ARRAY_NEXT_ELEMENT
,
2820 /* And these are used by json_build() */
2821 EXPECT_ARRAY_ELEMENT
,
2825 typedef struct JsonStack
{
2827 JsonVariant
**elements
;
2828 size_t n_elements
, n_elements_allocated
;
2829 unsigned line_before
;
2830 unsigned column_before
;
2831 size_t n_suppress
; /* When building: if > 0, suppress this many subsequent elements. If == (size_t) -1, suppress all subsequent elements */
2834 static void json_stack_release(JsonStack
*s
) {
2837 json_variant_unref_many(s
->elements
, s
->n_elements
);
2838 s
->elements
= mfree(s
->elements
);
2841 static int json_parse_internal(
2844 JsonParseFlags flags
,
2848 bool continue_end
) {
2850 size_t n_stack
= 1, n_stack_allocated
= 0, i
;
2851 unsigned line_buffer
= 0, column_buffer
= 0;
2852 void *tokenizer_state
= NULL
;
2853 JsonStack
*stack
= NULL
;
2857 assert_return(input
, -EINVAL
);
2858 assert_return(ret
, -EINVAL
);
2862 if (!GREEDY_REALLOC(stack
, n_stack_allocated
, n_stack
))
2865 stack
[0] = (JsonStack
) {
2866 .expect
= EXPECT_TOPLEVEL
,
2870 line
= &line_buffer
;
2872 column
= &column_buffer
;
2875 _cleanup_(json_variant_unrefp
) JsonVariant
*add
= NULL
;
2876 _cleanup_free_
char *string
= NULL
;
2877 unsigned line_token
, column_token
;
2882 assert(n_stack
> 0);
2883 current
= stack
+ n_stack
- 1;
2885 if (continue_end
&& current
->expect
== EXPECT_END
)
2888 token
= json_tokenize(&p
, &string
, &value
, &line_token
, &column_token
, &tokenizer_state
, line
, column
);
2896 case JSON_TOKEN_END
:
2897 if (current
->expect
!= EXPECT_END
) {
2902 assert(current
->n_elements
== 1);
2903 assert(n_stack
== 1);
2906 case JSON_TOKEN_COLON
:
2908 if (current
->expect
!= EXPECT_OBJECT_COLON
) {
2913 current
->expect
= EXPECT_OBJECT_VALUE
;
2916 case JSON_TOKEN_COMMA
:
2918 if (current
->expect
== EXPECT_OBJECT_COMMA
)
2919 current
->expect
= EXPECT_OBJECT_NEXT_KEY
;
2920 else if (current
->expect
== EXPECT_ARRAY_COMMA
)
2921 current
->expect
= EXPECT_ARRAY_NEXT_ELEMENT
;
2929 case JSON_TOKEN_OBJECT_OPEN
:
2931 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
2936 if (!GREEDY_REALLOC(stack
, n_stack_allocated
, n_stack
+1)) {
2940 current
= stack
+ n_stack
- 1;
2942 /* Prepare the expect for when we return from the child */
2943 if (current
->expect
== EXPECT_TOPLEVEL
)
2944 current
->expect
= EXPECT_END
;
2945 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
2946 current
->expect
= EXPECT_OBJECT_COMMA
;
2948 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
2949 current
->expect
= EXPECT_ARRAY_COMMA
;
2952 stack
[n_stack
++] = (JsonStack
) {
2953 .expect
= EXPECT_OBJECT_FIRST_KEY
,
2954 .line_before
= line_token
,
2955 .column_before
= column_token
,
2958 current
= stack
+ n_stack
- 1;
2961 case JSON_TOKEN_OBJECT_CLOSE
:
2962 if (!IN_SET(current
->expect
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_COMMA
)) {
2967 assert(n_stack
> 1);
2969 r
= json_variant_new_object(&add
, current
->elements
, current
->n_elements
);
2973 line_token
= current
->line_before
;
2974 column_token
= current
->column_before
;
2976 json_stack_release(current
);
2977 n_stack
--, current
--;
2981 case JSON_TOKEN_ARRAY_OPEN
:
2982 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
2987 if (!GREEDY_REALLOC(stack
, n_stack_allocated
, n_stack
+1)) {
2991 current
= stack
+ n_stack
- 1;
2993 /* Prepare the expect for when we return from the child */
2994 if (current
->expect
== EXPECT_TOPLEVEL
)
2995 current
->expect
= EXPECT_END
;
2996 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
2997 current
->expect
= EXPECT_OBJECT_COMMA
;
2999 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3000 current
->expect
= EXPECT_ARRAY_COMMA
;
3003 stack
[n_stack
++] = (JsonStack
) {
3004 .expect
= EXPECT_ARRAY_FIRST_ELEMENT
,
3005 .line_before
= line_token
,
3006 .column_before
= column_token
,
3011 case JSON_TOKEN_ARRAY_CLOSE
:
3012 if (!IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_COMMA
)) {
3017 assert(n_stack
> 1);
3019 r
= json_variant_new_array(&add
, current
->elements
, current
->n_elements
);
3023 line_token
= current
->line_before
;
3024 column_token
= current
->column_before
;
3026 json_stack_release(current
);
3027 n_stack
--, current
--;
3030 case JSON_TOKEN_STRING
:
3031 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
)) {
3036 r
= json_variant_new_string(&add
, string
);
3040 if (current
->expect
== EXPECT_TOPLEVEL
)
3041 current
->expect
= EXPECT_END
;
3042 else if (IN_SET(current
->expect
, EXPECT_OBJECT_FIRST_KEY
, EXPECT_OBJECT_NEXT_KEY
))
3043 current
->expect
= EXPECT_OBJECT_COLON
;
3044 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3045 current
->expect
= EXPECT_OBJECT_COMMA
;
3047 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3048 current
->expect
= EXPECT_ARRAY_COMMA
;
3053 case JSON_TOKEN_REAL
:
3054 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3059 r
= json_variant_new_real(&add
, value
.real
);
3063 if (current
->expect
== EXPECT_TOPLEVEL
)
3064 current
->expect
= EXPECT_END
;
3065 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3066 current
->expect
= EXPECT_OBJECT_COMMA
;
3068 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3069 current
->expect
= EXPECT_ARRAY_COMMA
;
3074 case JSON_TOKEN_INTEGER
:
3075 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3080 r
= json_variant_new_integer(&add
, value
.integer
);
3084 if (current
->expect
== EXPECT_TOPLEVEL
)
3085 current
->expect
= EXPECT_END
;
3086 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3087 current
->expect
= EXPECT_OBJECT_COMMA
;
3089 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3090 current
->expect
= EXPECT_ARRAY_COMMA
;
3095 case JSON_TOKEN_UNSIGNED
:
3096 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3101 r
= json_variant_new_unsigned(&add
, value
.unsig
);
3105 if (current
->expect
== EXPECT_TOPLEVEL
)
3106 current
->expect
= EXPECT_END
;
3107 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3108 current
->expect
= EXPECT_OBJECT_COMMA
;
3110 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3111 current
->expect
= EXPECT_ARRAY_COMMA
;
3116 case JSON_TOKEN_BOOLEAN
:
3117 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3122 r
= json_variant_new_boolean(&add
, value
.boolean
);
3126 if (current
->expect
== EXPECT_TOPLEVEL
)
3127 current
->expect
= EXPECT_END
;
3128 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3129 current
->expect
= EXPECT_OBJECT_COMMA
;
3131 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3132 current
->expect
= EXPECT_ARRAY_COMMA
;
3137 case JSON_TOKEN_NULL
:
3138 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
)) {
3143 r
= json_variant_new_null(&add
);
3147 if (current
->expect
== EXPECT_TOPLEVEL
)
3148 current
->expect
= EXPECT_END
;
3149 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3150 current
->expect
= EXPECT_OBJECT_COMMA
;
3152 assert(IN_SET(current
->expect
, EXPECT_ARRAY_FIRST_ELEMENT
, EXPECT_ARRAY_NEXT_ELEMENT
));
3153 current
->expect
= EXPECT_ARRAY_COMMA
;
3159 assert_not_reached("Unexpected token");
3163 /* If we are asked to make this parsed object sensitive, then let's apply this
3164 * immediately after allocating each variant, so that when we abort half-way
3165 * everything we already allocated that is then freed is correctly marked. */
3166 if (FLAGS_SET(flags
, JSON_PARSE_SENSITIVE
))
3167 json_variant_sensitive(add
);
3169 (void) json_variant_set_source(&add
, source
, line_token
, column_token
);
3171 if (!GREEDY_REALLOC(current
->elements
, current
->n_elements_allocated
, current
->n_elements
+ 1)) {
3176 current
->elements
[current
->n_elements
++] = TAKE_PTR(add
);
3181 assert(n_stack
== 1);
3182 assert(stack
[0].n_elements
== 1);
3184 *ret
= json_variant_ref(stack
[0].elements
[0]);
3189 for (i
= 0; i
< n_stack
; i
++)
3190 json_stack_release(stack
+ i
);
3197 int json_parse(const char *input
, JsonParseFlags flags
, JsonVariant
**ret
, unsigned *ret_line
, unsigned *ret_column
) {
3198 return json_parse_internal(&input
, NULL
, flags
, ret
, ret_line
, ret_column
, false);
3201 int json_parse_continue(const char **p
, JsonParseFlags flags
, JsonVariant
**ret
, unsigned *ret_line
, unsigned *ret_column
) {
3202 return json_parse_internal(p
, NULL
, flags
, ret
, ret_line
, ret_column
, true);
3205 int json_parse_file_at(FILE *f
, int dir_fd
, const char *path
, JsonParseFlags flags
, JsonVariant
**ret
, unsigned *ret_line
, unsigned *ret_column
) {
3206 _cleanup_(json_source_unrefp
) JsonSource
*source
= NULL
;
3207 _cleanup_free_
char *text
= NULL
;
3212 r
= read_full_stream(f
, &text
, NULL
);
3214 r
= read_full_file_full(dir_fd
, path
, UINT64_MAX
, SIZE_MAX
, 0, NULL
, &text
, NULL
);
3221 source
= json_source_new(path
);
3227 return json_parse_internal(&p
, source
, flags
, ret
, ret_line
, ret_column
, false);
3230 int json_buildv(JsonVariant
**ret
, va_list ap
) {
3231 JsonStack
*stack
= NULL
;
3232 size_t n_stack
= 1, n_stack_allocated
= 0, i
;
3235 assert_return(ret
, -EINVAL
);
3237 if (!GREEDY_REALLOC(stack
, n_stack_allocated
, n_stack
))
3240 stack
[0] = (JsonStack
) {
3241 .expect
= EXPECT_TOPLEVEL
,
3245 _cleanup_(json_variant_unrefp
) JsonVariant
*add
= NULL
;
3246 size_t n_subtract
= 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
3247 * have been added to the current variant */
3251 assert(n_stack
> 0);
3252 current
= stack
+ n_stack
- 1;
3254 if (current
->expect
== EXPECT_END
)
3257 command
= va_arg(ap
, int);
3261 case _JSON_BUILD_STRING
: {
3264 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3269 p
= va_arg(ap
, const char *);
3271 if (current
->n_suppress
== 0) {
3272 r
= json_variant_new_string(&add
, p
);
3279 if (current
->expect
== EXPECT_TOPLEVEL
)
3280 current
->expect
= EXPECT_END
;
3281 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3282 current
->expect
= EXPECT_OBJECT_KEY
;
3284 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3289 case _JSON_BUILD_INTEGER
: {
3292 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3297 j
= va_arg(ap
, intmax_t);
3299 if (current
->n_suppress
== 0) {
3300 r
= json_variant_new_integer(&add
, j
);
3307 if (current
->expect
== EXPECT_TOPLEVEL
)
3308 current
->expect
= EXPECT_END
;
3309 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3310 current
->expect
= EXPECT_OBJECT_KEY
;
3312 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3317 case _JSON_BUILD_UNSIGNED
: {
3320 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3325 j
= va_arg(ap
, uintmax_t);
3327 if (current
->n_suppress
== 0) {
3328 r
= json_variant_new_unsigned(&add
, j
);
3335 if (current
->expect
== EXPECT_TOPLEVEL
)
3336 current
->expect
= EXPECT_END
;
3337 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3338 current
->expect
= EXPECT_OBJECT_KEY
;
3340 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3345 case _JSON_BUILD_REAL
: {
3348 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3353 d
= va_arg(ap
, long double);
3355 if (current
->n_suppress
== 0) {
3356 r
= json_variant_new_real(&add
, d
);
3363 if (current
->expect
== EXPECT_TOPLEVEL
)
3364 current
->expect
= EXPECT_END
;
3365 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3366 current
->expect
= EXPECT_OBJECT_KEY
;
3368 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3373 case _JSON_BUILD_BOOLEAN
: {
3376 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3381 b
= va_arg(ap
, int);
3383 if (current
->n_suppress
== 0) {
3384 r
= json_variant_new_boolean(&add
, b
);
3391 if (current
->expect
== EXPECT_TOPLEVEL
)
3392 current
->expect
= EXPECT_END
;
3393 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3394 current
->expect
= EXPECT_OBJECT_KEY
;
3396 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3401 case _JSON_BUILD_NULL
:
3403 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3408 if (current
->n_suppress
== 0) {
3409 r
= json_variant_new_null(&add
);
3416 if (current
->expect
== EXPECT_TOPLEVEL
)
3417 current
->expect
= EXPECT_END
;
3418 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3419 current
->expect
= EXPECT_OBJECT_KEY
;
3421 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3425 case _JSON_BUILD_VARIANT
:
3427 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3432 /* Note that we don't care for current->n_suppress here, after all the variant is already
3433 * allocated anyway... */
3434 add
= va_arg(ap
, JsonVariant
*);
3436 add
= JSON_VARIANT_MAGIC_NULL
;
3438 json_variant_ref(add
);
3442 if (current
->expect
== EXPECT_TOPLEVEL
)
3443 current
->expect
= EXPECT_END
;
3444 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3445 current
->expect
= EXPECT_OBJECT_KEY
;
3447 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3451 case _JSON_BUILD_VARIANT_ARRAY
: {
3452 JsonVariant
**array
;
3455 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3460 array
= va_arg(ap
, JsonVariant
**);
3461 n
= va_arg(ap
, size_t);
3463 if (current
->n_suppress
== 0) {
3464 r
= json_variant_new_array(&add
, array
, n
);
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_LITERAL
: {
3484 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3489 l
= va_arg(ap
, const char *);
3492 /* Note that we don't care for current->n_suppress here, we should generate parsing
3493 * errors even in suppressed object properties */
3495 r
= json_parse(l
, 0, &add
, NULL
, NULL
);
3499 add
= JSON_VARIANT_MAGIC_NULL
;
3503 if (current
->expect
== EXPECT_TOPLEVEL
)
3504 current
->expect
= EXPECT_END
;
3505 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3506 current
->expect
= EXPECT_OBJECT_KEY
;
3508 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3513 case _JSON_BUILD_ARRAY_BEGIN
:
3515 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3520 if (!GREEDY_REALLOC(stack
, n_stack_allocated
, n_stack
+1)) {
3524 current
= stack
+ n_stack
- 1;
3526 if (current
->expect
== EXPECT_TOPLEVEL
)
3527 current
->expect
= EXPECT_END
;
3528 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3529 current
->expect
= EXPECT_OBJECT_KEY
;
3531 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3533 stack
[n_stack
++] = (JsonStack
) {
3534 .expect
= EXPECT_ARRAY_ELEMENT
,
3535 .n_suppress
= current
->n_suppress
!= 0 ? (size_t) -1 : 0, /* if we shall suppress the
3536 * new array, then we should
3537 * also suppress all array
3543 case _JSON_BUILD_ARRAY_END
:
3544 if (current
->expect
!= EXPECT_ARRAY_ELEMENT
) {
3549 assert(n_stack
> 1);
3551 if (current
->n_suppress
== 0) {
3552 r
= json_variant_new_array(&add
, current
->elements
, current
->n_elements
);
3559 json_stack_release(current
);
3560 n_stack
--, current
--;
3564 case _JSON_BUILD_STRV
: {
3567 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3572 l
= va_arg(ap
, char **);
3574 if (current
->n_suppress
== 0) {
3575 r
= json_variant_new_array_strv(&add
, l
);
3582 if (current
->expect
== EXPECT_TOPLEVEL
)
3583 current
->expect
= EXPECT_END
;
3584 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3585 current
->expect
= EXPECT_OBJECT_KEY
;
3587 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3592 case _JSON_BUILD_BASE64
: {
3596 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3601 p
= va_arg(ap
, const void *);
3602 n
= va_arg(ap
, size_t);
3604 if (current
->n_suppress
== 0) {
3605 r
= json_variant_new_base64(&add
, p
, n
);
3612 if (current
->expect
== EXPECT_TOPLEVEL
)
3613 current
->expect
= EXPECT_END
;
3614 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3615 current
->expect
= EXPECT_OBJECT_KEY
;
3617 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3622 case _JSON_BUILD_HEX
: {
3626 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3631 p
= va_arg(ap
, const void *);
3632 n
= va_arg(ap
, size_t);
3634 if (current
->n_suppress
== 0) {
3635 r
= json_variant_new_hex(&add
, p
, n
);
3642 if (current
->expect
== EXPECT_TOPLEVEL
)
3643 current
->expect
= EXPECT_END
;
3644 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3645 current
->expect
= EXPECT_OBJECT_KEY
;
3647 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3652 case _JSON_BUILD_ID128
: {
3655 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3660 id
= va_arg(ap
, sd_id128_t
);
3662 if (current
->n_suppress
== 0) {
3663 r
= json_variant_new_id128(&add
, id
);
3670 if (current
->expect
== EXPECT_TOPLEVEL
)
3671 current
->expect
= EXPECT_END
;
3672 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3673 current
->expect
= EXPECT_OBJECT_KEY
;
3675 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3680 case _JSON_BUILD_BYTE_ARRAY
: {
3684 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3689 array
= va_arg(ap
, const void*);
3690 n
= va_arg(ap
, size_t);
3692 if (current
->n_suppress
== 0) {
3693 r
= json_variant_new_array_bytes(&add
, array
, n
);
3700 if (current
->expect
== EXPECT_TOPLEVEL
)
3701 current
->expect
= EXPECT_END
;
3702 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3703 current
->expect
= EXPECT_OBJECT_KEY
;
3705 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3710 case _JSON_BUILD_OBJECT_BEGIN
:
3712 if (!IN_SET(current
->expect
, EXPECT_TOPLEVEL
, EXPECT_OBJECT_VALUE
, EXPECT_ARRAY_ELEMENT
)) {
3717 if (!GREEDY_REALLOC(stack
, n_stack_allocated
, n_stack
+1)) {
3721 current
= stack
+ n_stack
- 1;
3723 if (current
->expect
== EXPECT_TOPLEVEL
)
3724 current
->expect
= EXPECT_END
;
3725 else if (current
->expect
== EXPECT_OBJECT_VALUE
)
3726 current
->expect
= EXPECT_OBJECT_KEY
;
3728 assert(current
->expect
== EXPECT_ARRAY_ELEMENT
);
3730 stack
[n_stack
++] = (JsonStack
) {
3731 .expect
= EXPECT_OBJECT_KEY
,
3732 .n_suppress
= current
->n_suppress
!= 0 ? (size_t) -1 : 0, /* if we shall suppress the
3733 * new object, then we should
3734 * also suppress all object
3740 case _JSON_BUILD_OBJECT_END
:
3742 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
3747 assert(n_stack
> 1);
3749 if (current
->n_suppress
== 0) {
3750 r
= json_variant_new_object(&add
, current
->elements
, current
->n_elements
);
3757 json_stack_release(current
);
3758 n_stack
--, current
--;
3762 case _JSON_BUILD_PAIR
: {
3765 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
3770 n
= va_arg(ap
, const char *);
3772 if (current
->n_suppress
== 0) {
3773 r
= json_variant_new_string(&add
, n
);
3780 current
->expect
= EXPECT_OBJECT_VALUE
;
3784 case _JSON_BUILD_PAIR_CONDITION
: {
3788 if (current
->expect
!= EXPECT_OBJECT_KEY
) {
3793 b
= va_arg(ap
, int);
3794 n
= va_arg(ap
, const char *);
3796 if (b
&& current
->n_suppress
== 0) {
3797 r
= json_variant_new_string(&add
, n
);
3802 n_subtract
= 1; /* we generated one item */
3804 if (!b
&& current
->n_suppress
!= (size_t) -1)
3805 current
->n_suppress
+= 2; /* Suppress this one and the next item */
3807 current
->expect
= EXPECT_OBJECT_VALUE
;
3811 /* If a variant was generated, add it to our current variant, but only if we are not supposed to suppress additions */
3812 if (add
&& current
->n_suppress
== 0) {
3813 if (!GREEDY_REALLOC(current
->elements
, current
->n_elements_allocated
, current
->n_elements
+ 1)) {
3818 current
->elements
[current
->n_elements
++] = TAKE_PTR(add
);
3821 /* If we are supposed to suppress items, let's subtract how many items where generated from that
3822 * counter. Except if the counter is (size_t) -1, i.e. we shall suppress an infinite number of elements
3823 * on this stack level */
3824 if (current
->n_suppress
!= (size_t) -1) {
3825 if (current
->n_suppress
<= n_subtract
) /* Saturated */
3826 current
->n_suppress
= 0;
3828 current
->n_suppress
-= n_subtract
;
3833 assert(n_stack
== 1);
3834 assert(stack
[0].n_elements
== 1);
3836 *ret
= json_variant_ref(stack
[0].elements
[0]);
3840 for (i
= 0; i
< n_stack
; i
++)
3841 json_stack_release(stack
+ i
);
3848 int json_build(JsonVariant
**ret
, ...) {
3853 r
= json_buildv(ret
, ap
);
3859 int json_log_internal(
3860 JsonVariant
*variant
,
3866 const char *format
, ...) {
3870 unsigned source_line
, source_column
;
3871 char buffer
[LINE_MAX
];
3876 errno
= ERRNO_VALUE(error
);
3878 va_start(ap
, format
);
3879 (void) vsnprintf(buffer
, sizeof buffer
, format
, ap
);
3883 r
= json_variant_get_source(variant
, &source
, &source_line
, &source_column
);
3892 if (source
&& source_line
> 0 && source_column
> 0)
3893 return log_struct_internal(
3897 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
3898 "CONFIG_FILE=%s", source
,
3899 "CONFIG_LINE=%u", source_line
,
3900 "CONFIG_COLUMN=%u", source_column
,
3901 LOG_MESSAGE("%s:%u:%u: %s", source
, source_line
, source_column
, buffer
),
3903 else if (source_line
> 0 && source_column
> 0)
3904 return log_struct_internal(
3908 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
3909 "CONFIG_LINE=%u", source_line
,
3910 "CONFIG_COLUMN=%u", source_column
,
3911 LOG_MESSAGE("(string):%u:%u: %s", source_line
, source_column
, buffer
),
3914 return log_struct_internal(
3918 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR
,
3919 LOG_MESSAGE("%s", buffer
),
3923 int json_dispatch(JsonVariant
*v
, const JsonDispatch table
[], JsonDispatchCallback bad
, JsonDispatchFlags flags
, void *userdata
) {
3924 const JsonDispatch
*p
;
3929 if (!json_variant_is_object(v
)) {
3930 json_log(v
, flags
, 0, "JSON variant is not an object.");
3932 if (flags
& JSON_PERMISSIVE
)
3938 for (p
= table
, m
= 0; p
->name
; p
++)
3941 found
= newa0(bool, m
);
3943 n
= json_variant_elements(v
);
3944 for (i
= 0; i
< n
; i
+= 2) {
3945 JsonVariant
*key
, *value
;
3947 assert_se(key
= json_variant_by_index(v
, i
));
3948 assert_se(value
= json_variant_by_index(v
, i
+1));
3950 for (p
= table
; p
->name
; p
++)
3951 if (p
->name
== POINTER_MAX
||
3952 streq_ptr(json_variant_string(key
), p
->name
))
3955 if (p
->name
) { /* Found a matching entry! :-) */
3956 JsonDispatchFlags merged_flags
;
3958 merged_flags
= flags
| p
->flags
;
3960 if (p
->type
!= _JSON_VARIANT_TYPE_INVALID
&&
3961 !json_variant_has_type(value
, p
->type
)) {
3963 json_log(value
, merged_flags
, 0,
3964 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key
),
3965 json_variant_type_to_string(json_variant_type(value
)), json_variant_type_to_string(p
->type
));
3967 if (merged_flags
& JSON_PERMISSIVE
)
3973 if (found
[p
-table
]) {
3974 json_log(value
, merged_flags
, 0, "Duplicate object field '%s'.", json_variant_string(key
));
3976 if (merged_flags
& JSON_PERMISSIVE
)
3982 found
[p
-table
] = true;
3985 r
= p
->callback(json_variant_string(key
), value
, merged_flags
, (uint8_t*) userdata
+ p
->offset
);
3987 if (merged_flags
& JSON_PERMISSIVE
)
3996 } else { /* Didn't find a matching entry! :-( */
3999 r
= bad(json_variant_string(key
), value
, flags
, userdata
);
4001 if (flags
& JSON_PERMISSIVE
)
4009 json_log(value
, flags
, 0, "Unexpected object field '%s'.", json_variant_string(key
));
4011 if (flags
& JSON_PERMISSIVE
)
4014 return -EADDRNOTAVAIL
;
4019 for (p
= table
; p
->name
; p
++) {
4020 JsonDispatchFlags merged_flags
= p
->flags
| flags
;
4022 if ((merged_flags
& JSON_MANDATORY
) && !found
[p
-table
]) {
4023 json_log(v
, merged_flags
, 0, "Missing object field '%s'.", p
->name
);
4025 if ((merged_flags
& JSON_PERMISSIVE
))
4035 int json_dispatch_boolean(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4041 if (!json_variant_is_boolean(variant
))
4042 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a boolean.", strna(name
));
4044 *b
= json_variant_boolean(variant
);
4048 int json_dispatch_tristate(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4054 if (json_variant_is_null(variant
)) {
4059 if (!json_variant_is_boolean(variant
))
4060 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a boolean.", strna(name
));
4062 *b
= json_variant_boolean(variant
);
4066 int json_dispatch_intmax(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4067 intmax_t *i
= userdata
;
4072 if (!json_variant_is_integer(variant
))
4073 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an integer.", strna(name
));
4075 *i
= json_variant_integer(variant
);
4079 int json_dispatch_uintmax(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4080 uintmax_t *u
= userdata
;
4085 if (!json_variant_is_unsigned(variant
))
4086 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an unsigned integer.", strna(name
));
4088 *u
= json_variant_unsigned(variant
);
4092 int json_dispatch_uint32(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4093 uint32_t *u
= userdata
;
4098 if (!json_variant_is_unsigned(variant
))
4099 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an unsigned integer.", strna(name
));
4101 if (json_variant_unsigned(variant
) > UINT32_MAX
)
4102 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4104 *u
= (uint32_t) json_variant_unsigned(variant
);
4108 int json_dispatch_int32(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4109 int32_t *i
= userdata
;
4114 if (!json_variant_is_integer(variant
))
4115 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not an integer.", strna(name
));
4117 if (json_variant_integer(variant
) < INT32_MIN
|| json_variant_integer(variant
) > INT32_MAX
)
4118 return json_log(variant
, flags
, SYNTHETIC_ERRNO(ERANGE
), "JSON field '%s' out of bounds.", strna(name
));
4120 *i
= (int32_t) json_variant_integer(variant
);
4124 int json_dispatch_string(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4125 char **s
= userdata
;
4131 if (json_variant_is_null(variant
)) {
4136 if (!json_variant_is_string(variant
))
4137 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4139 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4140 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4142 r
= free_and_strdup(s
, json_variant_string(variant
));
4144 return json_log(variant
, flags
, r
, "Failed to allocate string: %m");
4149 int json_dispatch_const_string(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4150 const char **s
= userdata
;
4155 if (json_variant_is_null(variant
)) {
4160 if (!json_variant_is_string(variant
))
4161 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4163 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4164 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4166 *s
= json_variant_string(variant
);
4170 int json_dispatch_strv(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4171 _cleanup_strv_free_
char **l
= NULL
;
4172 char ***s
= userdata
;
4179 if (json_variant_is_null(variant
)) {
4184 /* Let's be flexible here: accept a single string in place of a single-item array */
4185 if (json_variant_is_string(variant
)) {
4186 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(variant
)))
4187 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4189 l
= strv_new(json_variant_string(variant
));
4193 strv_free_and_replace(*s
, l
);
4197 if (!json_variant_is_array(variant
))
4198 return json_log(variant
, SYNTHETIC_ERRNO(EINVAL
), flags
, "JSON field '%s' is not an array.", strna(name
));
4200 JSON_VARIANT_ARRAY_FOREACH(e
, variant
) {
4201 if (!json_variant_is_string(e
))
4202 return json_log(e
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON array element is not a string.");
4204 if ((flags
& JSON_SAFE
) && !string_is_safe(json_variant_string(e
)))
4205 return json_log(e
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' contains unsafe characters, refusing.", strna(name
));
4207 r
= strv_extend(&l
, json_variant_string(e
));
4209 return json_log(e
, flags
, r
, "Failed to append array element: %m");
4212 strv_free_and_replace(*s
, l
);
4216 int json_dispatch_variant(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4217 JsonVariant
**p
= userdata
;
4222 json_variant_unref(*p
);
4223 *p
= json_variant_ref(variant
);
4228 int json_dispatch_uid_gid(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4229 uid_t
*uid
= userdata
;
4232 assert_cc(sizeof(uid_t
) == sizeof(uint32_t));
4233 assert_cc(sizeof(gid_t
) == sizeof(uint32_t));
4235 DISABLE_WARNING_TYPE_LIMITS
;
4236 assert_cc(((uid_t
) -1 < (uid_t
) 0) == ((gid_t
) -1 < (gid_t
) 0));
4239 if (json_variant_is_null(variant
)) {
4244 if (!json_variant_is_unsigned(variant
))
4245 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a integer.", strna(name
));
4247 k
= json_variant_unsigned(variant
);
4248 if (k
> UINT32_MAX
|| !uid_is_valid(k
))
4249 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid UID/GID.", strna(name
));
4255 int json_dispatch_user_group_name(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4256 char **s
= userdata
;
4260 if (json_variant_is_null(variant
)) {
4265 if (!json_variant_is_string(variant
))
4266 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4268 n
= json_variant_string(variant
);
4269 if (!valid_user_group_name(n
, FLAGS_SET(flags
, JSON_RELAX
) ? VALID_USER_RELAX
: 0))
4270 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a valid user/group name.", strna(name
));
4272 r
= free_and_strdup(s
, n
);
4274 return json_log(variant
, flags
, r
, "Failed to allocate string: %m");
4279 int json_dispatch_id128(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4280 sd_id128_t
*uuid
= userdata
;
4283 if (json_variant_is_null(variant
)) {
4284 *uuid
= SD_ID128_NULL
;
4288 if (!json_variant_is_string(variant
))
4289 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not a string.", strna(name
));
4291 r
= sd_id128_from_string(json_variant_string(variant
), uuid
);
4293 return json_log(variant
, flags
, r
, "JSON field '%s' is not a valid UID.", strna(name
));
4298 int json_dispatch_unsupported(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
4299 return json_log(variant
, flags
, SYNTHETIC_ERRNO(EINVAL
), "JSON field '%s' is not allowed in this object.", strna(name
));
4302 static int json_cmp_strings(const void *x
, const void *y
) {
4303 JsonVariant
*const *a
= x
, *const *b
= y
;
4305 if (!json_variant_is_string(*a
) || !json_variant_is_string(*b
))
4308 return strcmp(json_variant_string(*a
), json_variant_string(*b
));
4311 int json_variant_sort(JsonVariant
**v
) {
4312 _cleanup_free_ JsonVariant
**a
= NULL
;
4313 JsonVariant
*n
= NULL
;
4319 if (json_variant_is_sorted(*v
))
4322 if (!json_variant_is_object(*v
))
4323 return -EMEDIUMTYPE
;
4325 /* Sorts they key/value pairs in an object variant */
4327 m
= json_variant_elements(*v
);
4328 a
= new(JsonVariant
*, m
);
4332 for (i
= 0; i
< m
; i
++)
4333 a
[i
] = json_variant_by_index(*v
, i
);
4335 qsort(a
, m
/2, sizeof(JsonVariant
*)*2, json_cmp_strings
);
4337 r
= json_variant_new_object(&n
, a
, m
);
4341 json_variant_propagate_sensitive(*v
, n
);
4343 if (!n
->sorted
) /* Check if this worked. This will fail if there are multiple identical keys used. */
4346 json_variant_unref(*v
);
4352 int json_variant_normalize(JsonVariant
**v
) {
4353 _cleanup_free_ JsonVariant
**a
= NULL
;
4354 JsonVariant
*n
= NULL
;
4360 if (json_variant_is_normalized(*v
))
4363 if (!json_variant_is_object(*v
) && !json_variant_is_array(*v
))
4364 return -EMEDIUMTYPE
;
4366 /* Sorts the key/value pairs in an object variant anywhere down the tree in the specified variant */
4368 m
= json_variant_elements(*v
);
4369 a
= new(JsonVariant
*, m
);
4373 for (i
= 0; i
< m
; i
++) {
4374 a
[i
] = json_variant_ref(json_variant_by_index(*v
, i
));
4376 r
= json_variant_normalize(a
+ i
);
4381 qsort(a
, m
/2, sizeof(JsonVariant
*)*2, json_cmp_strings
);
4383 if (json_variant_is_object(*v
))
4384 r
= json_variant_new_object(&n
, a
, m
);
4386 assert(json_variant_is_array(*v
));
4387 r
= json_variant_new_array(&n
, a
, m
);
4392 json_variant_propagate_sensitive(*v
, n
);
4394 if (!n
->normalized
) { /* Let's see if normalization worked. It will fail if there are multiple
4395 * identical keys used in the same object anywhere, or if there are floating
4396 * point numbers used (see below) */
4401 json_variant_unref(*v
);
4407 for (j
= 0; j
< i
; j
++)
4408 json_variant_unref(a
[j
]);
4413 bool json_variant_is_normalized(JsonVariant
*v
) {
4415 /* For now, let's consider anything containing numbers not expressible as integers as
4416 * non-normalized. That's because we cannot sensibly compare them due to accuracy issues, nor even
4417 * store them if they are too large. */
4418 if (json_variant_is_real(v
) && !json_variant_is_integer(v
) && !json_variant_is_unsigned(v
))
4421 /* The concept only applies to variants that include other variants, i.e. objects and arrays. All
4422 * others are normalized anyway. */
4423 if (!json_variant_is_object(v
) && !json_variant_is_array(v
))
4426 /* Empty objects/arrays don't include any other variant, hence are always normalized too */
4427 if (json_variant_elements(v
) == 0)
4430 return v
->normalized
; /* For everything else there's an explicit boolean we maintain */
4433 bool json_variant_is_sorted(JsonVariant
*v
) {
4435 /* Returns true if all key/value pairs of an object are properly sorted. Note that this only applies
4436 * to objects, not arrays. */
4438 if (!json_variant_is_object(v
))
4440 if (json_variant_elements(v
) <= 1)
4446 int json_variant_unbase64(JsonVariant
*v
, void **ret
, size_t *ret_size
) {
4448 if (!json_variant_is_string(v
))
4451 return unbase64mem(json_variant_string(v
), (size_t) -1, ret
, ret_size
);
4454 int json_variant_unhex(JsonVariant
*v
, void **ret
, size_t *ret_size
) {
4456 if (!json_variant_is_string(v
))
4459 return unhexmem(json_variant_string(v
), (size_t) -1, ret
, ret_size
);
4462 static const char* const json_variant_type_table
[_JSON_VARIANT_TYPE_MAX
] = {
4463 [JSON_VARIANT_STRING
] = "string",
4464 [JSON_VARIANT_INTEGER
] = "integer",
4465 [JSON_VARIANT_UNSIGNED
] = "unsigned",
4466 [JSON_VARIANT_REAL
] = "real",
4467 [JSON_VARIANT_NUMBER
] = "number",
4468 [JSON_VARIANT_BOOLEAN
] = "boolean",
4469 [JSON_VARIANT_ARRAY
] = "array",
4470 [JSON_VARIANT_OBJECT
] = "object",
4471 [JSON_VARIANT_NULL
] = "null",
4474 DEFINE_STRING_TABLE_LOOKUP(json_variant_type
, JsonVariantType
);