]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/json.c
hexdecoct: make unbase64mem and unhexmem always use SIZE_MAX
[thirdparty/systemd.git] / src / shared / json.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <locale.h>
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <sys/types.h>
8
9 #include "sd-messages.h"
10
11 #include "alloc-util.h"
12 #include "errno-util.h"
13 #include "escape.h"
14 #include "fd-util.h"
15 #include "fileio.h"
16 #include "float.h"
17 #include "hexdecoct.h"
18 #include "json-internal.h"
19 #include "json.h"
20 #include "macro.h"
21 #include "math-util.h"
22 #include "memory-util.h"
23 #include "memstream-util.h"
24 #include "set.h"
25 #include "string-table.h"
26 #include "string-util.h"
27 #include "strv.h"
28 #include "terminal-util.h"
29 #include "user-util.h"
30 #include "utf8.h"
31
32 /* Refuse putting together variants with a larger depth than 2K by default (as a protection against overflowing stacks
33 * if code processes JSON objects recursively. Note that we store the depth in an uint16_t, hence make sure this
34 * remains under 2^16.
35 *
36 * The value first was 16k, but it was discovered to be too high on llvm/x86-64. See also:
37 * https://github.com/systemd/systemd/issues/10738
38 *
39 * The value then was 4k, but it was discovered to be too high on s390x/aarch64. See also:
40 * https://github.com/systemd/systemd/issues/14396 */
41
42 #define DEPTH_MAX (2U*1024U)
43 assert_cc(DEPTH_MAX <= UINT16_MAX);
44
45 typedef struct JsonSource {
46 /* When we parse from a file or similar, encodes the filename, to indicate the source of a json variant */
47 unsigned n_ref;
48 unsigned max_line;
49 unsigned max_column;
50 char name[];
51 } JsonSource;
52
53 /* On x86-64 this whole structure should have a size of 6 * 64 bit = 48 bytes */
54 struct JsonVariant {
55 union {
56 /* We either maintain a reference counter for this variant itself, or we are embedded into an
57 * array/object, in which case only that surrounding object is ref-counted. (If 'embedded' is false,
58 * see below.) */
59 unsigned n_ref;
60
61 /* If this JsonVariant is part of an array/object, then this field points to the surrounding
62 * JSON_VARIANT_ARRAY/JSON_VARIANT_OBJECT object. (If 'embedded' is true, see below.) */
63 JsonVariant *parent;
64 };
65
66 /* If this was parsed from some file or buffer, this stores where from, as well as the source line/column */
67 JsonSource *source;
68 unsigned line, column;
69
70 /* The current 'depth' of the JsonVariant, i.e. how many levels of member variants this has */
71 uint16_t depth;
72
73 JsonVariantType type:8;
74
75 /* A marker whether this variant is embedded into in array/object or not. If true, the 'parent' pointer above
76 * is valid. If false, the 'n_ref' field above is valid instead. */
77 bool is_embedded:1;
78
79 /* In some conditions (for example, if this object is part of an array of strings or objects), we don't store
80 * any data inline, but instead simply reference an external object and act as surrogate of it. In that case
81 * this bool is set, and the external object is referenced through the .reference field below. */
82 bool is_reference:1;
83
84 /* While comparing two arrays, we use this for marking what we already have seen */
85 bool is_marked:1;
86
87 /* Erase from memory when freeing */
88 bool sensitive:1;
89
90 /* If this is an object the fields are strictly ordered by name */
91 bool sorted:1;
92
93 /* If in addition to this object all objects referenced by it are also ordered strictly by name */
94 bool normalized:1;
95
96 union {
97 /* For simple types we store the value in-line. */
98 JsonValue value;
99
100 /* For objects and arrays we store the number of elements immediately following */
101 size_t n_elements;
102
103 /* If is_reference as indicated above is set, this is where the reference object is actually stored. */
104 JsonVariant *reference;
105
106 /* Strings are placed immediately after the structure. Note that when this is a JsonVariant
107 * embedded into an array we might encode strings up to INLINE_STRING_LENGTH characters
108 * directly inside the element, while longer strings are stored as references. When this
109 * object is not embedded into an array, but stand-alone, we allocate the right size for the
110 * whole structure, i.e. the array might be much larger than INLINE_STRING_LENGTH. */
111 DECLARE_FLEX_ARRAY(char, string);
112 };
113 };
114
115 /* Inside string arrays we have a series of JsonVariant structures one after the other. In this case, strings longer
116 * than INLINE_STRING_MAX are stored as references, and all shorter ones inline. (This means — on x86-64 — strings up
117 * to 7 chars are stored within the array elements, and all others in separate allocations) */
118 #define INLINE_STRING_MAX (sizeof(JsonVariant) - offsetof(JsonVariant, string) - 1U)
119
120 /* Let's make sure this structure isn't increased in size accidentally. This check is only for our most relevant arch
121 * (x86-64). */
122 #if defined(__x86_64__) && __SIZEOF_POINTER__ == 8
123 assert_cc(sizeof(JsonVariant) == 40U);
124 assert_cc(INLINE_STRING_MAX == 7U);
125 #endif
126
127 static JsonSource* json_source_new(const char *name) {
128 JsonSource *s;
129
130 assert(name);
131
132 s = malloc(offsetof(JsonSource, name) + strlen(name) + 1);
133 if (!s)
134 return NULL;
135
136 *s = (JsonSource) {
137 .n_ref = 1,
138 };
139 strcpy(s->name, name);
140
141 return s;
142 }
143
144 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(JsonSource, json_source, mfree);
145
146 static bool json_source_equal(JsonSource *a, JsonSource *b) {
147 if (a == b)
148 return true;
149
150 if (!a || !b)
151 return false;
152
153 return streq(a->name, b->name);
154 }
155
156 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonSource*, json_source_unref);
157
158 /* There are four kind of JsonVariant* pointers:
159 *
160 * 1. NULL
161 * 2. A 'regular' one, i.e. pointing to malloc() memory
162 * 3. A 'magic' one, i.e. one of the special JSON_VARIANT_MAGIC_XYZ values, that encode a few very basic values directly in the pointer.
163 * 4. A 'const string' one, i.e. a pointer to a const string.
164 *
165 * The four kinds of pointers can be discerned like this:
166 *
167 * Detecting #1 is easy, just compare with NULL. Detecting #3 is similarly easy: all magic pointers are below
168 * _JSON_VARIANT_MAGIC_MAX (which is pretty low, within the first memory page, which is special on Linux and other
169 * OSes, as it is a faulting page). In order to discern #2 and #4 we check the lowest bit. If it's off it's #2,
170 * otherwise #4. This makes use of the fact that malloc() will return "maximum aligned" memory, which definitely
171 * means the pointer is even. This means we can use the uneven pointers to reference static strings, as long as we
172 * make sure that all static strings used like this are aligned to 2 (or higher), and that we mask the bit on
173 * access. The JSON_VARIANT_STRING_CONST() macro encodes strings as JsonVariant* pointers, with the bit set. */
174
175 static bool json_variant_is_magic(const JsonVariant *v) {
176 if (!v)
177 return false;
178
179 return v < _JSON_VARIANT_MAGIC_MAX;
180 }
181
182 static bool json_variant_is_const_string(const JsonVariant *v) {
183
184 if (v < _JSON_VARIANT_MAGIC_MAX)
185 return false;
186
187 /* A proper JsonVariant is aligned to whatever malloc() aligns things too, which is definitely not uneven. We
188 * hence use all uneven pointers as indicators for const strings. */
189
190 return (((uintptr_t) v) & 1) != 0;
191 }
192
193 static bool json_variant_is_regular(const JsonVariant *v) {
194
195 if (v < _JSON_VARIANT_MAGIC_MAX)
196 return false;
197
198 return (((uintptr_t) v) & 1) == 0;
199 }
200
201 static JsonVariant *json_variant_dereference(JsonVariant *v) {
202
203 /* Recursively dereference variants that are references to other variants */
204
205 if (!v)
206 return NULL;
207
208 if (!json_variant_is_regular(v))
209 return v;
210
211 if (!v->is_reference)
212 return v;
213
214 return json_variant_dereference(v->reference);
215 }
216
217 static uint16_t json_variant_depth(JsonVariant *v) {
218
219 v = json_variant_dereference(v);
220 if (!v)
221 return 0;
222
223 if (!json_variant_is_regular(v))
224 return 0;
225
226 return v->depth;
227 }
228
229 static JsonVariant *json_variant_formalize(JsonVariant *v) {
230
231 /* Converts json variant pointers to their normalized form, i.e. fully dereferenced and wherever
232 * possible converted to the "magic" version if there is one */
233
234 if (!v)
235 return NULL;
236
237 v = json_variant_dereference(v);
238
239 switch (json_variant_type(v)) {
240
241 case JSON_VARIANT_BOOLEAN:
242 return json_variant_boolean(v) ? JSON_VARIANT_MAGIC_TRUE : JSON_VARIANT_MAGIC_FALSE;
243
244 case JSON_VARIANT_NULL:
245 return JSON_VARIANT_MAGIC_NULL;
246
247 case JSON_VARIANT_INTEGER:
248 return json_variant_integer(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_INTEGER : v;
249
250 case JSON_VARIANT_UNSIGNED:
251 return json_variant_unsigned(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED : v;
252
253 case JSON_VARIANT_REAL:
254 return iszero_safe(json_variant_real(v)) ? JSON_VARIANT_MAGIC_ZERO_REAL : v;
255
256 case JSON_VARIANT_STRING:
257 return isempty(json_variant_string(v)) ? JSON_VARIANT_MAGIC_EMPTY_STRING : v;
258
259 case JSON_VARIANT_ARRAY:
260 return json_variant_elements(v) == 0 ? JSON_VARIANT_MAGIC_EMPTY_ARRAY : v;
261
262 case JSON_VARIANT_OBJECT:
263 return json_variant_elements(v) == 0 ? JSON_VARIANT_MAGIC_EMPTY_OBJECT : v;
264
265 default:
266 return v;
267 }
268 }
269
270 static JsonVariant *json_variant_conservative_formalize(JsonVariant *v) {
271
272 /* Much like json_variant_formalize(), but won't simplify if the variant has a source/line location
273 * attached to it, in order not to lose context */
274
275 if (!v)
276 return NULL;
277
278 if (!json_variant_is_regular(v))
279 return v;
280
281 if (v->source || v->line > 0 || v->column > 0)
282 return v;
283
284 return json_variant_formalize(v);
285 }
286
287 static int json_variant_new(JsonVariant **ret, JsonVariantType type, size_t space) {
288 JsonVariant *v;
289
290 assert_return(ret, -EINVAL);
291
292 v = malloc0(MAX(sizeof(JsonVariant),
293 offsetof(JsonVariant, value) + space));
294 if (!v)
295 return -ENOMEM;
296
297 v->n_ref = 1;
298 v->type = type;
299
300 *ret = v;
301 return 0;
302 }
303
304 int json_variant_new_integer(JsonVariant **ret, int64_t i) {
305 JsonVariant *v;
306 int r;
307
308 assert_return(ret, -EINVAL);
309
310 if (i == 0) {
311 *ret = JSON_VARIANT_MAGIC_ZERO_INTEGER;
312 return 0;
313 }
314
315 r = json_variant_new(&v, JSON_VARIANT_INTEGER, sizeof(i));
316 if (r < 0)
317 return r;
318
319 v->value.integer = i;
320 *ret = v;
321
322 return 0;
323 }
324
325 int json_variant_new_unsigned(JsonVariant **ret, uint64_t u) {
326 JsonVariant *v;
327 int r;
328
329 assert_return(ret, -EINVAL);
330 if (u == 0) {
331 *ret = JSON_VARIANT_MAGIC_ZERO_UNSIGNED;
332 return 0;
333 }
334
335 r = json_variant_new(&v, JSON_VARIANT_UNSIGNED, sizeof(u));
336 if (r < 0)
337 return r;
338
339 v->value.unsig = u;
340 *ret = v;
341
342 return 0;
343 }
344
345 int json_variant_new_real(JsonVariant **ret, double d) {
346 JsonVariant *v;
347 int r;
348
349 assert_return(ret, -EINVAL);
350
351 r = fpclassify(d);
352 switch (r) {
353 case FP_NAN:
354 case FP_INFINITE:
355 /* JSON doesn't know NaN, +Infinity or -Infinity. Let's silently convert to 'null'. */
356 *ret = JSON_VARIANT_MAGIC_NULL;
357 return 0;
358
359 case FP_ZERO:
360 *ret = JSON_VARIANT_MAGIC_ZERO_REAL;
361 return 0;
362 }
363
364 r = json_variant_new(&v, JSON_VARIANT_REAL, sizeof(d));
365 if (r < 0)
366 return r;
367
368 v->value.real = d;
369 *ret = v;
370
371 return 0;
372 }
373
374 int json_variant_new_boolean(JsonVariant **ret, bool b) {
375 assert_return(ret, -EINVAL);
376
377 if (b)
378 *ret = JSON_VARIANT_MAGIC_TRUE;
379 else
380 *ret = JSON_VARIANT_MAGIC_FALSE;
381
382 return 0;
383 }
384
385 int json_variant_new_null(JsonVariant **ret) {
386 assert_return(ret, -EINVAL);
387
388 *ret = JSON_VARIANT_MAGIC_NULL;
389 return 0;
390 }
391
392 int json_variant_new_stringn(JsonVariant **ret, const char *s, size_t n) {
393 JsonVariant *v;
394 int r;
395
396 assert_return(ret, -EINVAL);
397 if (!s) {
398 assert_return(IN_SET(n, 0, SIZE_MAX), -EINVAL);
399 return json_variant_new_null(ret);
400 }
401 if (n == SIZE_MAX) /* determine length automatically */
402 n = strlen(s);
403 else if (memchr(s, 0, n)) /* don't allow embedded NUL, as we can't express that in JSON */
404 return -EINVAL;
405 if (n == 0) {
406 *ret = JSON_VARIANT_MAGIC_EMPTY_STRING;
407 return 0;
408 }
409
410 if (!utf8_is_valid_n(s, n)) /* JSON strings must be valid UTF-8 */
411 return -EUCLEAN;
412
413 r = json_variant_new(&v, JSON_VARIANT_STRING, n + 1);
414 if (r < 0)
415 return r;
416
417 memcpy(v->string, s, n);
418 v->string[n] = 0;
419
420 *ret = v;
421 return 0;
422 }
423
424 int json_variant_new_base64(JsonVariant **ret, const void *p, size_t n) {
425 _cleanup_free_ char *s = NULL;
426 ssize_t k;
427
428 assert_return(ret, -EINVAL);
429 assert_return(n == 0 || p, -EINVAL);
430
431 k = base64mem(p, n, &s);
432 if (k < 0)
433 return k;
434
435 return json_variant_new_stringn(ret, s, k);
436 }
437
438 int json_variant_new_base32hex(JsonVariant **ret, const void *p, size_t n) {
439 _cleanup_free_ char *s = NULL;
440
441 assert_return(ret, -EINVAL);
442 assert_return(n == 0 || p, -EINVAL);
443
444 s = base32hexmem(p, n, false);
445 if (!s)
446 return -ENOMEM;
447
448 return json_variant_new_string(ret, s);
449 }
450
451 int json_variant_new_hex(JsonVariant **ret, const void *p, size_t n) {
452 _cleanup_free_ char *s = NULL;
453
454 assert_return(ret, -EINVAL);
455 assert_return(n == 0 || p, -EINVAL);
456
457 s = hexmem(p, n);
458 if (!s)
459 return -ENOMEM;
460
461 return json_variant_new_stringn(ret, s, n*2);
462 }
463
464 int json_variant_new_octescape(JsonVariant **ret, const void *p, size_t n) {
465 _cleanup_free_ char *s = NULL;
466
467 assert_return(ret, -EINVAL);
468 assert_return(n == 0 || p, -EINVAL);
469
470 s = octescape(p, n);
471 if (!s)
472 return -ENOMEM;
473
474 return json_variant_new_string(ret, s);
475 }
476
477 int json_variant_new_id128(JsonVariant **ret, sd_id128_t id) {
478 return json_variant_new_string(ret, SD_ID128_TO_STRING(id));
479 }
480
481 int json_variant_new_uuid(JsonVariant **ret, sd_id128_t id) {
482 return json_variant_new_string(ret, SD_ID128_TO_UUID_STRING(id));
483 }
484
485 static void json_variant_set(JsonVariant *a, JsonVariant *b) {
486 assert(a);
487
488 b = json_variant_dereference(b);
489 if (!b) {
490 a->type = JSON_VARIANT_NULL;
491 return;
492 }
493
494 a->type = json_variant_type(b);
495 switch (a->type) {
496
497 case JSON_VARIANT_INTEGER:
498 a->value.integer = json_variant_integer(b);
499 break;
500
501 case JSON_VARIANT_UNSIGNED:
502 a->value.unsig = json_variant_unsigned(b);
503 break;
504
505 case JSON_VARIANT_REAL:
506 a->value.real = json_variant_real(b);
507 break;
508
509 case JSON_VARIANT_BOOLEAN:
510 a->value.boolean = json_variant_boolean(b);
511 break;
512
513 case JSON_VARIANT_STRING: {
514 const char *s;
515
516 assert_se(s = json_variant_string(b));
517
518 /* Short strings we can store inline */
519 if (strnlen(s, INLINE_STRING_MAX+1) <= INLINE_STRING_MAX) {
520 strcpy(a->string, s);
521 break;
522 }
523
524 /* For longer strings, use a reference… */
525 _fallthrough_;
526 }
527
528 case JSON_VARIANT_ARRAY:
529 case JSON_VARIANT_OBJECT:
530 a->is_reference = true;
531 a->reference = json_variant_ref(json_variant_conservative_formalize(b));
532 break;
533
534 case JSON_VARIANT_NULL:
535 break;
536
537 default:
538 assert_not_reached();
539 }
540 }
541
542 static void json_variant_copy_source(JsonVariant *v, JsonVariant *from) {
543 assert(v);
544
545 if (!json_variant_is_regular(from))
546 return;
547
548 v->line = from->line;
549 v->column = from->column;
550 v->source = json_source_ref(from->source);
551 }
552
553 static int _json_variant_array_put_element(JsonVariant *array, JsonVariant *element) {
554 assert(array);
555 JsonVariant *w = array + 1 + array->n_elements;
556
557 uint16_t d = json_variant_depth(element);
558 if (d >= DEPTH_MAX) /* Refuse too deep nesting */
559 return -ELNRNG;
560 if (d >= array->depth)
561 array->depth = d + 1;
562 array->n_elements++;
563
564 *w = (JsonVariant) {
565 .is_embedded = true,
566 .parent = array,
567 };
568
569 json_variant_set(w, element);
570 json_variant_copy_source(w, element);
571
572 if (!json_variant_is_normalized(element))
573 array->normalized = false;
574
575 return 0;
576 }
577
578 int json_variant_new_array(JsonVariant **ret, JsonVariant **array, size_t n) {
579 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
580 int r;
581
582 assert_return(ret, -EINVAL);
583 if (n == 0) {
584 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
585 return 0;
586 }
587 assert_return(array, -EINVAL);
588
589 v = new(JsonVariant, n + 1);
590 if (!v)
591 return -ENOMEM;
592
593 *v = (JsonVariant) {
594 .n_ref = 1,
595 .type = JSON_VARIANT_ARRAY,
596 .normalized = true,
597 };
598
599 while (v->n_elements < n) {
600 r = _json_variant_array_put_element(v, array[v->n_elements]);
601 if (r < 0)
602 return r;
603 }
604
605 *ret = TAKE_PTR(v);
606 return 0;
607 }
608
609 int json_variant_new_array_bytes(JsonVariant **ret, const void *p, size_t n) {
610 assert_return(ret, -EINVAL);
611 if (n == 0) {
612 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
613 return 0;
614 }
615 assert_return(p, -EINVAL);
616
617 JsonVariant *v = new(JsonVariant, n + 1);
618 if (!v)
619 return -ENOMEM;
620
621 *v = (JsonVariant) {
622 .n_ref = 1,
623 .type = JSON_VARIANT_ARRAY,
624 .n_elements = n,
625 .depth = 1,
626 };
627
628 for (size_t i = 0; i < n; i++) {
629 JsonVariant *w = v + 1 + i;
630
631 *w = (JsonVariant) {
632 .is_embedded = true,
633 .parent = v,
634 .type = JSON_VARIANT_UNSIGNED,
635 .value.unsig = ((const uint8_t*) p)[i],
636 };
637 }
638
639 v->normalized = true;
640
641 *ret = v;
642 return 0;
643 }
644
645 int json_variant_new_array_strv(JsonVariant **ret, char **l) {
646 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
647 size_t n;
648 int r;
649
650 assert(ret);
651
652 n = strv_length(l);
653 if (n == 0) {
654 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
655 return 0;
656 }
657
658 v = new(JsonVariant, n + 1);
659 if (!v)
660 return -ENOMEM;
661
662 *v = (JsonVariant) {
663 .n_ref = 1,
664 .type = JSON_VARIANT_ARRAY,
665 .depth = 1,
666 };
667
668 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
669 JsonVariant *w = v + 1 + v->n_elements;
670 size_t k;
671
672 *w = (JsonVariant) {
673 .is_embedded = true,
674 .parent = v,
675 .type = JSON_VARIANT_STRING,
676 };
677
678 k = strlen(l[v->n_elements]);
679
680 if (k > INLINE_STRING_MAX) {
681 /* If string is too long, store it as reference. */
682
683 r = json_variant_new_string(&w->reference, l[v->n_elements]);
684 if (r < 0)
685 return r;
686
687 w->is_reference = true;
688 } else {
689 if (!utf8_is_valid_n(l[v->n_elements], k)) /* JSON strings must be valid UTF-8 */
690 return -EUCLEAN;
691
692 memcpy(w->string, l[v->n_elements], k+1);
693 }
694 }
695
696 v->normalized = true;
697
698 *ret = TAKE_PTR(v);
699 return 0;
700 }
701
702 int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n) {
703 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
704 const char *prev = NULL;
705 bool sorted = true, normalized = true;
706
707 assert_return(ret, -EINVAL);
708 if (n == 0) {
709 *ret = JSON_VARIANT_MAGIC_EMPTY_OBJECT;
710 return 0;
711 }
712 assert_return(array, -EINVAL);
713 assert_return(n % 2 == 0, -EINVAL);
714
715 v = new(JsonVariant, n + 1);
716 if (!v)
717 return -ENOMEM;
718
719 *v = (JsonVariant) {
720 .n_ref = 1,
721 .type = JSON_VARIANT_OBJECT,
722 };
723
724 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
725 JsonVariant *w = v + 1 + v->n_elements,
726 *c = array[v->n_elements];
727 uint16_t d;
728
729 if ((v->n_elements & 1) == 0) {
730 const char *k;
731
732 if (!json_variant_is_string(c))
733 return -EINVAL; /* Every second one needs to be a string, as it is the key name */
734
735 assert_se(k = json_variant_string(c));
736
737 if (prev && strcmp(k, prev) <= 0)
738 sorted = normalized = false;
739
740 prev = k;
741 } else if (!json_variant_is_normalized(c))
742 normalized = false;
743
744 d = json_variant_depth(c);
745 if (d >= DEPTH_MAX) /* Refuse too deep nesting */
746 return -ELNRNG;
747 if (d >= v->depth)
748 v->depth = d + 1;
749
750 *w = (JsonVariant) {
751 .is_embedded = true,
752 .parent = v,
753 };
754
755 json_variant_set(w, c);
756 json_variant_copy_source(w, c);
757 }
758
759 v->normalized = normalized;
760 v->sorted = sorted;
761
762 *ret = TAKE_PTR(v);
763 return 0;
764 }
765
766 static size_t json_variant_size(JsonVariant* v) {
767 if (!json_variant_is_regular(v))
768 return 0;
769
770 if (v->is_reference)
771 return offsetof(JsonVariant, reference) + sizeof(JsonVariant*);
772
773 switch (v->type) {
774
775 case JSON_VARIANT_STRING:
776 return offsetof(JsonVariant, string) + strlen(v->string) + 1;
777
778 case JSON_VARIANT_REAL:
779 return offsetof(JsonVariant, value) + sizeof(double);
780
781 case JSON_VARIANT_UNSIGNED:
782 return offsetof(JsonVariant, value) + sizeof(uint64_t);
783
784 case JSON_VARIANT_INTEGER:
785 return offsetof(JsonVariant, value) + sizeof(int64_t);
786
787 case JSON_VARIANT_BOOLEAN:
788 return offsetof(JsonVariant, value) + sizeof(bool);
789
790 case JSON_VARIANT_ARRAY:
791 case JSON_VARIANT_OBJECT:
792 return offsetof(JsonVariant, n_elements) + sizeof(size_t);
793
794 case JSON_VARIANT_NULL:
795 return offsetof(JsonVariant, value);
796
797 default:
798 assert_not_reached();
799 }
800 }
801
802 static void json_variant_free_inner(JsonVariant *v, bool force_sensitive) {
803 bool sensitive;
804
805 assert(v);
806
807 if (!json_variant_is_regular(v))
808 return;
809
810 json_source_unref(v->source);
811
812 sensitive = v->sensitive || force_sensitive;
813
814 if (v->is_reference) {
815 if (sensitive)
816 json_variant_sensitive(v->reference);
817
818 json_variant_unref(v->reference);
819 return;
820 }
821
822 if (IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
823 for (size_t i = 0; i < v->n_elements; i++)
824 json_variant_free_inner(v + 1 + i, sensitive);
825
826 if (sensitive)
827 explicit_bzero_safe(v, json_variant_size(v));
828 }
829
830 static unsigned json_variant_n_ref(const JsonVariant *v) {
831 /* Return the number of references to v.
832 * 0 => NULL or not a regular object or embedded.
833 * >0 => number of references
834 */
835
836 if (!v || !json_variant_is_regular(v) || v->is_embedded)
837 return 0;
838
839 assert(v->n_ref > 0);
840 return v->n_ref;
841 }
842
843 JsonVariant *json_variant_ref(JsonVariant *v) {
844 if (!v)
845 return NULL;
846 if (!json_variant_is_regular(v))
847 return v;
848
849 if (v->is_embedded)
850 json_variant_ref(v->parent); /* ref the compounding variant instead */
851 else {
852 assert(v->n_ref > 0);
853 v->n_ref++;
854 }
855
856 return v;
857 }
858
859 JsonVariant *json_variant_unref(JsonVariant *v) {
860 if (!v)
861 return NULL;
862 if (!json_variant_is_regular(v))
863 return NULL;
864
865 if (v->is_embedded)
866 json_variant_unref(v->parent);
867 else {
868 assert(v->n_ref > 0);
869 v->n_ref--;
870
871 if (v->n_ref == 0) {
872 json_variant_free_inner(v, false);
873 free(v);
874 }
875 }
876
877 return NULL;
878 }
879
880 void json_variant_unref_many(JsonVariant **array, size_t n) {
881 assert(array || n == 0);
882
883 for (size_t i = 0; i < n; i++)
884 json_variant_unref(array[i]);
885
886 free(array);
887 }
888
889 const char *json_variant_string(JsonVariant *v) {
890 if (!v)
891 return NULL;
892 if (v == JSON_VARIANT_MAGIC_EMPTY_STRING)
893 return "";
894 if (json_variant_is_magic(v))
895 goto mismatch;
896 if (json_variant_is_const_string(v)) {
897 uintptr_t p = (uintptr_t) v;
898
899 assert((p & 1) != 0);
900 return (const char*) (p ^ 1U);
901 }
902
903 if (v->is_reference)
904 return json_variant_string(v->reference);
905 if (v->type != JSON_VARIANT_STRING)
906 goto mismatch;
907
908 return v->string;
909
910 mismatch:
911 log_debug("Non-string JSON variant requested as string, returning NULL.");
912 return NULL;
913 }
914
915 bool json_variant_boolean(JsonVariant *v) {
916 if (!v)
917 goto mismatch;
918 if (v == JSON_VARIANT_MAGIC_TRUE)
919 return true;
920 if (v == JSON_VARIANT_MAGIC_FALSE)
921 return false;
922 if (!json_variant_is_regular(v))
923 goto mismatch;
924 if (v->type != JSON_VARIANT_BOOLEAN)
925 goto mismatch;
926 if (v->is_reference)
927 return json_variant_boolean(v->reference);
928
929 return v->value.boolean;
930
931 mismatch:
932 log_debug("Non-boolean JSON variant requested as boolean, returning false.");
933 return false;
934 }
935
936 int64_t json_variant_integer(JsonVariant *v) {
937 if (!v)
938 goto mismatch;
939 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
940 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
941 v == JSON_VARIANT_MAGIC_ZERO_REAL)
942 return 0;
943 if (!json_variant_is_regular(v))
944 goto mismatch;
945 if (v->is_reference)
946 return json_variant_integer(v->reference);
947
948 switch (v->type) {
949
950 case JSON_VARIANT_INTEGER:
951 return v->value.integer;
952
953 case JSON_VARIANT_UNSIGNED:
954 if (v->value.unsig <= INT64_MAX)
955 return (int64_t) v->value.unsig;
956
957 log_debug("Unsigned integer %" PRIu64 " requested as signed integer and out of range, returning 0.", v->value.unsig);
958 return 0;
959
960 case JSON_VARIANT_REAL: {
961 int64_t converted;
962
963 converted = (int64_t) v->value.real;
964
965 if (fp_equal((double) converted, v->value.real))
966 return converted;
967
968 log_debug("Real %g requested as integer, and cannot be converted losslessly, returning 0.", v->value.real);
969 return 0;
970 }
971
972 default:
973 break;
974 }
975
976 mismatch:
977 log_debug("Non-integer JSON variant requested as integer, returning 0.");
978 return 0;
979 }
980
981 uint64_t json_variant_unsigned(JsonVariant *v) {
982 if (!v)
983 goto mismatch;
984 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
985 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
986 v == JSON_VARIANT_MAGIC_ZERO_REAL)
987 return 0;
988 if (!json_variant_is_regular(v))
989 goto mismatch;
990 if (v->is_reference)
991 return json_variant_integer(v->reference);
992
993 switch (v->type) {
994
995 case JSON_VARIANT_INTEGER:
996 if (v->value.integer >= 0)
997 return (uint64_t) v->value.integer;
998
999 log_debug("Signed integer %" PRIi64 " requested as unsigned integer and out of range, returning 0.", v->value.integer);
1000 return 0;
1001
1002 case JSON_VARIANT_UNSIGNED:
1003 return v->value.unsig;
1004
1005 case JSON_VARIANT_REAL: {
1006 uint64_t converted;
1007
1008 converted = (uint64_t) v->value.real;
1009
1010 if (fp_equal((double) converted, v->value.real))
1011 return converted;
1012
1013 log_debug("Real %g requested as unsigned integer, and cannot be converted losslessly, returning 0.", v->value.real);
1014 return 0;
1015 }
1016
1017 default:
1018 break;
1019 }
1020
1021 mismatch:
1022 log_debug("Non-integer JSON variant requested as unsigned, returning 0.");
1023 return 0;
1024 }
1025
1026 double json_variant_real(JsonVariant *v) {
1027 if (!v)
1028 return 0.0;
1029 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
1030 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
1031 v == JSON_VARIANT_MAGIC_ZERO_REAL)
1032 return 0.0;
1033 if (!json_variant_is_regular(v))
1034 goto mismatch;
1035 if (v->is_reference)
1036 return json_variant_real(v->reference);
1037
1038 switch (v->type) {
1039
1040 case JSON_VARIANT_REAL:
1041 return v->value.real;
1042
1043 case JSON_VARIANT_INTEGER: {
1044 double converted = (double) v->value.integer;
1045
1046 if ((int64_t) converted == v->value.integer)
1047 return converted;
1048
1049 log_debug("Signed integer %" PRIi64 " requested as real, and cannot be converted losslessly, returning 0.", v->value.integer);
1050 return 0.0;
1051 }
1052
1053 case JSON_VARIANT_UNSIGNED: {
1054 double converted = (double) v->value.unsig;
1055
1056 if ((uint64_t) converted == v->value.unsig)
1057 return converted;
1058
1059 log_debug("Unsigned integer %" PRIu64 " requested as real, and cannot be converted losslessly, returning 0.", v->value.unsig);
1060 return 0.0;
1061 }
1062
1063 default:
1064 break;
1065 }
1066
1067 mismatch:
1068 log_debug("Non-integer JSON variant requested as integer, returning 0.");
1069 return 0.0;
1070 }
1071
1072 bool json_variant_is_negative(JsonVariant *v) {
1073 if (!v)
1074 goto mismatch;
1075 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
1076 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
1077 v == JSON_VARIANT_MAGIC_ZERO_REAL)
1078 return false;
1079 if (!json_variant_is_regular(v))
1080 goto mismatch;
1081 if (v->is_reference)
1082 return json_variant_is_negative(v->reference);
1083
1084 /* This function is useful as checking whether numbers are negative is pretty complex since we have three types
1085 * of numbers. And some JSON code (OCI for example) uses negative numbers to mark "not defined" numeric
1086 * values. */
1087
1088 switch (v->type) {
1089
1090 case JSON_VARIANT_REAL:
1091 return v->value.real < 0;
1092
1093 case JSON_VARIANT_INTEGER:
1094 return v->value.integer < 0;
1095
1096 case JSON_VARIANT_UNSIGNED:
1097 return false;
1098
1099 default:
1100 break;
1101 }
1102
1103 mismatch:
1104 log_debug("Non-integer JSON variant tested for negativity, returning false.");
1105 return false;
1106 }
1107
1108 bool json_variant_is_blank_object(JsonVariant *v) {
1109 /* Returns true if the specified object is null or empty */
1110 return !v ||
1111 json_variant_is_null(v) ||
1112 (json_variant_is_object(v) && json_variant_elements(v) == 0);
1113 }
1114
1115 bool json_variant_is_blank_array(JsonVariant *v) {
1116 return !v ||
1117 json_variant_is_null(v) ||
1118 (json_variant_is_array(v) && json_variant_elements(v) == 0);
1119 }
1120
1121 JsonVariantType json_variant_type(JsonVariant *v) {
1122
1123 if (!v)
1124 return _JSON_VARIANT_TYPE_INVALID;
1125
1126 if (json_variant_is_const_string(v))
1127 return JSON_VARIANT_STRING;
1128
1129 if (v == JSON_VARIANT_MAGIC_TRUE || v == JSON_VARIANT_MAGIC_FALSE)
1130 return JSON_VARIANT_BOOLEAN;
1131
1132 if (v == JSON_VARIANT_MAGIC_NULL)
1133 return JSON_VARIANT_NULL;
1134
1135 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER)
1136 return JSON_VARIANT_INTEGER;
1137
1138 if (v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED)
1139 return JSON_VARIANT_UNSIGNED;
1140
1141 if (v == JSON_VARIANT_MAGIC_ZERO_REAL)
1142 return JSON_VARIANT_REAL;
1143
1144 if (v == JSON_VARIANT_MAGIC_EMPTY_STRING)
1145 return JSON_VARIANT_STRING;
1146
1147 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY)
1148 return JSON_VARIANT_ARRAY;
1149
1150 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1151 return JSON_VARIANT_OBJECT;
1152
1153 return v->type;
1154 }
1155
1156 _function_no_sanitize_float_cast_overflow_
1157 bool json_variant_has_type(JsonVariant *v, JsonVariantType type) {
1158 JsonVariantType rt;
1159
1160 /* Note: we turn off ubsan float cast overflow detection for this function, since it would complain
1161 * about our float casts but we do them explicitly to detect conversion errors. */
1162
1163 v = json_variant_dereference(v);
1164 if (!v)
1165 return false;
1166
1167 rt = json_variant_type(v);
1168 if (rt == type)
1169 return true;
1170
1171 /* If it's a const string, then it only can be a string, and if it is not, it's not */
1172 if (json_variant_is_const_string(v))
1173 return false;
1174
1175 /* All three magic zeroes qualify as integer, unsigned and as real */
1176 if ((v == JSON_VARIANT_MAGIC_ZERO_INTEGER || v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED || v == JSON_VARIANT_MAGIC_ZERO_REAL) &&
1177 IN_SET(type, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL, JSON_VARIANT_NUMBER))
1178 return true;
1179
1180 /* All other magic variant types are only equal to themselves */
1181 if (json_variant_is_magic(v))
1182 return false;
1183
1184 /* Handle the "number" pseudo type */
1185 if (type == JSON_VARIANT_NUMBER)
1186 return IN_SET(rt, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL);
1187
1188 /* Integer conversions are OK in many cases */
1189 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_UNSIGNED)
1190 return v->value.integer >= 0;
1191 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_INTEGER)
1192 return v->value.unsig <= INT64_MAX;
1193
1194 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1195 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_REAL)
1196 return (int64_t) (double) v->value.integer == v->value.integer;
1197 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_REAL)
1198 return (uint64_t) (double) v->value.unsig == v->value.unsig;
1199
1200 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1201 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_INTEGER)
1202 return fp_equal((double) (int64_t) v->value.real, v->value.real);
1203 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_UNSIGNED)
1204 return fp_equal((double) (uint64_t) v->value.real, v->value.real);
1205
1206 return false;
1207 }
1208
1209 size_t json_variant_elements(JsonVariant *v) {
1210 if (!v)
1211 return 0;
1212 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1213 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1214 return 0;
1215 if (!json_variant_is_regular(v))
1216 goto mismatch;
1217 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1218 goto mismatch;
1219 if (v->is_reference)
1220 return json_variant_elements(v->reference);
1221
1222 return v->n_elements;
1223
1224 mismatch:
1225 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1226 return 0;
1227 }
1228
1229 JsonVariant *json_variant_by_index(JsonVariant *v, size_t idx) {
1230 if (!v)
1231 return NULL;
1232 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1233 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1234 return NULL;
1235 if (!json_variant_is_regular(v))
1236 goto mismatch;
1237 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1238 goto mismatch;
1239 if (v->is_reference)
1240 return json_variant_by_index(v->reference, idx);
1241 if (idx >= v->n_elements)
1242 return NULL;
1243
1244 return json_variant_conservative_formalize(v + 1 + idx);
1245
1246 mismatch:
1247 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1248 return NULL;
1249 }
1250
1251 JsonVariant *json_variant_by_key_full(JsonVariant *v, const char *key, JsonVariant **ret_key) {
1252 if (!v)
1253 goto not_found;
1254 if (!key)
1255 goto not_found;
1256 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1257 goto not_found;
1258 if (!json_variant_is_regular(v))
1259 goto mismatch;
1260 if (v->type != JSON_VARIANT_OBJECT)
1261 goto mismatch;
1262 if (v->is_reference)
1263 return json_variant_by_key(v->reference, key);
1264
1265 if (v->sorted) {
1266 size_t a = 0, b = v->n_elements/2;
1267
1268 /* If the variant is sorted we can use bisection to find the entry we need in O(log(n)) time */
1269
1270 while (b > a) {
1271 JsonVariant *p;
1272 const char *f;
1273 size_t i;
1274 int c;
1275
1276 i = (a + b) / 2;
1277 p = json_variant_dereference(v + 1 + i*2);
1278
1279 assert_se(f = json_variant_string(p));
1280
1281 c = strcmp(key, f);
1282 if (c == 0) {
1283 if (ret_key)
1284 *ret_key = json_variant_conservative_formalize(v + 1 + i*2);
1285
1286 return json_variant_conservative_formalize(v + 1 + i*2 + 1);
1287 } else if (c < 0)
1288 b = i;
1289 else
1290 a = i + 1;
1291 }
1292
1293 goto not_found;
1294 }
1295
1296 /* The variant is not sorted, hence search for the field linearly */
1297 for (size_t i = 0; i < v->n_elements; i += 2) {
1298 JsonVariant *p;
1299
1300 p = json_variant_dereference(v + 1 + i);
1301
1302 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1303 continue;
1304
1305 if (streq(json_variant_string(p), key)) {
1306
1307 if (ret_key)
1308 *ret_key = json_variant_conservative_formalize(v + 1 + i);
1309
1310 return json_variant_conservative_formalize(v + 1 + i + 1);
1311 }
1312 }
1313
1314 not_found:
1315 if (ret_key)
1316 *ret_key = NULL;
1317
1318 return NULL;
1319
1320 mismatch:
1321 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1322 if (ret_key)
1323 *ret_key = NULL;
1324
1325 return NULL;
1326 }
1327
1328 JsonVariant *json_variant_by_key(JsonVariant *v, const char *key) {
1329 return json_variant_by_key_full(v, key, NULL);
1330 }
1331
1332 bool json_variant_equal(JsonVariant *a, JsonVariant *b) {
1333 JsonVariantType t;
1334
1335 a = json_variant_formalize(a);
1336 b = json_variant_formalize(b);
1337
1338 if (a == b)
1339 return true;
1340
1341 t = json_variant_type(a);
1342 if (!json_variant_has_type(b, t))
1343 return false;
1344
1345 switch (t) {
1346
1347 case JSON_VARIANT_STRING:
1348 return streq(json_variant_string(a), json_variant_string(b));
1349
1350 case JSON_VARIANT_INTEGER:
1351 return json_variant_integer(a) == json_variant_integer(b);
1352
1353 case JSON_VARIANT_UNSIGNED:
1354 return json_variant_unsigned(a) == json_variant_unsigned(b);
1355
1356 case JSON_VARIANT_REAL:
1357 return fp_equal(json_variant_real(a), json_variant_real(b));
1358
1359 case JSON_VARIANT_BOOLEAN:
1360 return json_variant_boolean(a) == json_variant_boolean(b);
1361
1362 case JSON_VARIANT_NULL:
1363 return true;
1364
1365 case JSON_VARIANT_ARRAY: {
1366 size_t n = json_variant_elements(a);
1367 if (n != json_variant_elements(b))
1368 return false;
1369
1370 for (size_t i = 0; i < n; i++)
1371 if (!json_variant_equal(json_variant_by_index(a, i), json_variant_by_index(b, i)))
1372 return false;
1373
1374 return true;
1375 }
1376
1377 case JSON_VARIANT_OBJECT: {
1378 size_t n = json_variant_elements(a);
1379 if (n != json_variant_elements(b))
1380 return false;
1381
1382 /* Iterate through all keys in 'a' */
1383 for (size_t i = 0; i < n; i += 2) {
1384 bool found = false;
1385
1386 /* Match them against all keys in 'b' */
1387 for (size_t j = 0; j < n; j += 2) {
1388 JsonVariant *key_b;
1389
1390 key_b = json_variant_by_index(b, j);
1391
1392 /* During the first iteration unmark everything */
1393 if (i == 0)
1394 key_b->is_marked = false;
1395 else if (key_b->is_marked) /* In later iterations if we already marked something, don't bother with it again */
1396 continue;
1397
1398 if (found)
1399 continue;
1400
1401 if (json_variant_equal(json_variant_by_index(a, i), key_b) &&
1402 json_variant_equal(json_variant_by_index(a, i+1), json_variant_by_index(b, j+1))) {
1403 /* Key and values match! */
1404 key_b->is_marked = found = true;
1405
1406 /* In the first iteration we continue the inner loop since we want to mark
1407 * everything, otherwise exit the loop quickly after we found what we were
1408 * looking for. */
1409 if (i != 0)
1410 break;
1411 }
1412 }
1413
1414 if (!found)
1415 return false;
1416 }
1417
1418 return true;
1419 }
1420
1421 default:
1422 assert_not_reached();
1423 }
1424 }
1425
1426 void json_variant_sensitive(JsonVariant *v) {
1427 assert(v);
1428
1429 /* Marks a variant as "sensitive", so that it is erased from memory when it is destroyed. This is a
1430 * one-way operation: as soon as it is marked this way it remains marked this way until it's
1431 * destroyed. A magic variant is never sensitive though, even when asked, since it's too
1432 * basic. Similar, const string variant are never sensitive either, after all they are included in
1433 * the source code as they are, which is not suitable for inclusion of secrets.
1434 *
1435 * Note that this flag has a recursive effect: when we destroy an object or array we'll propagate the
1436 * flag to all contained variants. And if those are then destroyed this is propagated further down,
1437 * and so on. */
1438
1439 v = json_variant_formalize(v);
1440 if (!json_variant_is_regular(v))
1441 return;
1442
1443 v->sensitive = true;
1444 }
1445
1446 bool json_variant_is_sensitive(JsonVariant *v) {
1447 v = json_variant_formalize(v);
1448 if (!json_variant_is_regular(v))
1449 return false;
1450
1451 return v->sensitive;
1452 }
1453
1454 static void json_variant_propagate_sensitive(JsonVariant *from, JsonVariant *to) {
1455 if (json_variant_is_sensitive(from))
1456 json_variant_sensitive(to);
1457 }
1458
1459 int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column) {
1460 assert_return(v, -EINVAL);
1461
1462 if (ret_source)
1463 *ret_source = json_variant_is_regular(v) && v->source ? v->source->name : NULL;
1464
1465 if (ret_line)
1466 *ret_line = json_variant_is_regular(v) ? v->line : 0;
1467
1468 if (ret_column)
1469 *ret_column = json_variant_is_regular(v) ? v->column : 0;
1470
1471 return 0;
1472 }
1473
1474 static int print_source(FILE *f, JsonVariant *v, JsonFormatFlags flags, bool whitespace) {
1475 size_t w, k;
1476
1477 if (!FLAGS_SET(flags, JSON_FORMAT_SOURCE|JSON_FORMAT_PRETTY))
1478 return 0;
1479
1480 if (!json_variant_is_regular(v))
1481 return 0;
1482
1483 if (!v->source && v->line == 0 && v->column == 0)
1484 return 0;
1485
1486 /* The max width we need to format the line numbers for this source file */
1487 w = (v->source && v->source->max_line > 0) ?
1488 DECIMAL_STR_WIDTH(v->source->max_line) :
1489 DECIMAL_STR_MAX(unsigned)-1;
1490 k = (v->source && v->source->max_column > 0) ?
1491 DECIMAL_STR_WIDTH(v->source->max_column) :
1492 DECIMAL_STR_MAX(unsigned) -1;
1493
1494 if (whitespace) {
1495 size_t n = 1 + (v->source ? strlen(v->source->name) : 0) +
1496 ((v->source && (v->line > 0 || v->column > 0)) ? 1 : 0) +
1497 (v->line > 0 ? w : 0) +
1498 (((v->source || v->line > 0) && v->column > 0) ? 1 : 0) +
1499 (v->column > 0 ? k : 0) +
1500 2;
1501
1502 for (size_t i = 0; i < n; i++)
1503 fputc(' ', f);
1504 } else {
1505 fputc('[', f);
1506
1507 if (v->source)
1508 fputs(v->source->name, f);
1509 if (v->source && (v->line > 0 || v->column > 0))
1510 fputc(':', f);
1511 if (v->line > 0)
1512 fprintf(f, "%*u", (int) w, v->line);
1513 if ((v->source || v->line > 0) || v->column > 0)
1514 fputc(':', f);
1515 if (v->column > 0)
1516 fprintf(f, "%*u", (int) k, v->column);
1517
1518 fputc(']', f);
1519 fputc(' ', f);
1520 }
1521
1522 return 0;
1523 }
1524
1525 static void json_format_string(FILE *f, const char *q, JsonFormatFlags flags) {
1526 assert(q);
1527
1528 fputc('"', f);
1529
1530 if (flags & JSON_FORMAT_COLOR)
1531 fputs(ansi_green(), f);
1532
1533 for (; *q; q++)
1534 switch (*q) {
1535 case '"':
1536 fputs("\\\"", f);
1537 break;
1538
1539 case '\\':
1540 fputs("\\\\", f);
1541 break;
1542
1543 case '\b':
1544 fputs("\\b", f);
1545 break;
1546
1547 case '\f':
1548 fputs("\\f", f);
1549 break;
1550
1551 case '\n':
1552 fputs("\\n", f);
1553 break;
1554
1555 case '\r':
1556 fputs("\\r", f);
1557 break;
1558
1559 case '\t':
1560 fputs("\\t", f);
1561 break;
1562
1563 default:
1564 if ((signed char) *q >= 0 && *q < ' ')
1565 fprintf(f, "\\u%04x", (unsigned) *q);
1566 else
1567 fputc(*q, f);
1568 break;
1569 }
1570
1571 if (flags & JSON_FORMAT_COLOR)
1572 fputs(ANSI_NORMAL, f);
1573
1574 fputc('"', f);
1575 }
1576
1577 static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const char *prefix) {
1578 int r;
1579
1580 assert(f);
1581 assert(v);
1582
1583 switch (json_variant_type(v)) {
1584
1585 case JSON_VARIANT_REAL: {
1586 locale_t loc, old_loc;
1587
1588 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
1589 if (loc == (locale_t) 0)
1590 return -errno;
1591
1592 if (flags & JSON_FORMAT_COLOR)
1593 fputs(ansi_highlight_blue(), f);
1594
1595 old_loc = uselocale(loc);
1596 fprintf(f, "%.*e", DECIMAL_DIG, json_variant_real(v));
1597 uselocale(old_loc);
1598
1599 if (flags & JSON_FORMAT_COLOR)
1600 fputs(ANSI_NORMAL, f);
1601
1602 freelocale(loc);
1603 break;
1604 }
1605
1606 case JSON_VARIANT_INTEGER:
1607 if (flags & JSON_FORMAT_COLOR)
1608 fputs(ansi_highlight_blue(), f);
1609
1610 fprintf(f, "%" PRIdMAX, json_variant_integer(v));
1611
1612 if (flags & JSON_FORMAT_COLOR)
1613 fputs(ANSI_NORMAL, f);
1614 break;
1615
1616 case JSON_VARIANT_UNSIGNED:
1617 if (flags & JSON_FORMAT_COLOR)
1618 fputs(ansi_highlight_blue(), f);
1619
1620 fprintf(f, "%" PRIuMAX, json_variant_unsigned(v));
1621
1622 if (flags & JSON_FORMAT_COLOR)
1623 fputs(ANSI_NORMAL, f);
1624 break;
1625
1626 case JSON_VARIANT_BOOLEAN:
1627
1628 if (flags & JSON_FORMAT_COLOR)
1629 fputs(ANSI_HIGHLIGHT, f);
1630
1631 if (json_variant_boolean(v))
1632 fputs("true", f);
1633 else
1634 fputs("false", f);
1635
1636 if (flags & JSON_FORMAT_COLOR)
1637 fputs(ANSI_NORMAL, f);
1638
1639 break;
1640
1641 case JSON_VARIANT_NULL:
1642 if (flags & JSON_FORMAT_COLOR)
1643 fputs(ANSI_HIGHLIGHT, f);
1644
1645 fputs("null", f);
1646
1647 if (flags & JSON_FORMAT_COLOR)
1648 fputs(ANSI_NORMAL, f);
1649 break;
1650
1651 case JSON_VARIANT_STRING:
1652 json_format_string(f, json_variant_string(v), flags);
1653 break;
1654
1655 case JSON_VARIANT_ARRAY: {
1656 size_t n = json_variant_elements(v);
1657 if (n == 0)
1658 fputs("[]", f);
1659 else {
1660 _cleanup_free_ char *joined = NULL;
1661 const char *prefix2;
1662
1663 if (flags & JSON_FORMAT_PRETTY) {
1664 joined = strjoin(strempty(prefix), "\t");
1665 if (!joined)
1666 return -ENOMEM;
1667
1668 prefix2 = joined;
1669 fputs("[\n", f);
1670 } else {
1671 prefix2 = strempty(prefix);
1672 fputc('[', f);
1673 }
1674
1675 for (size_t i = 0; i < n; i++) {
1676 JsonVariant *e;
1677
1678 assert_se(e = json_variant_by_index(v, i));
1679
1680 if (i > 0) {
1681 if (flags & JSON_FORMAT_PRETTY)
1682 fputs(",\n", f);
1683 else
1684 fputc(',', f);
1685 }
1686
1687 if (flags & JSON_FORMAT_PRETTY) {
1688 print_source(f, e, flags, false);
1689 fputs(prefix2, f);
1690 }
1691
1692 r = json_format(f, e, flags, prefix2);
1693 if (r < 0)
1694 return r;
1695 }
1696
1697 if (flags & JSON_FORMAT_PRETTY) {
1698 fputc('\n', f);
1699 print_source(f, v, flags, true);
1700 fputs(strempty(prefix), f);
1701 }
1702
1703 fputc(']', f);
1704 }
1705 break;
1706 }
1707
1708 case JSON_VARIANT_OBJECT: {
1709 size_t n = json_variant_elements(v);
1710 if (n == 0)
1711 fputs("{}", f);
1712 else {
1713 _cleanup_free_ char *joined = NULL;
1714 const char *prefix2;
1715
1716 if (flags & JSON_FORMAT_PRETTY) {
1717 joined = strjoin(strempty(prefix), "\t");
1718 if (!joined)
1719 return -ENOMEM;
1720
1721 prefix2 = joined;
1722 fputs("{\n", f);
1723 } else {
1724 prefix2 = strempty(prefix);
1725 fputc('{', f);
1726 }
1727
1728 for (size_t i = 0; i < n; i += 2) {
1729 JsonVariant *e;
1730
1731 e = json_variant_by_index(v, i);
1732
1733 if (i > 0) {
1734 if (flags & JSON_FORMAT_PRETTY)
1735 fputs(",\n", f);
1736 else
1737 fputc(',', f);
1738 }
1739
1740 if (flags & JSON_FORMAT_PRETTY) {
1741 print_source(f, e, flags, false);
1742 fputs(prefix2, f);
1743 }
1744
1745 r = json_format(f, e, flags, prefix2);
1746 if (r < 0)
1747 return r;
1748
1749 fputs(flags & JSON_FORMAT_PRETTY ? " : " : ":", f);
1750
1751 r = json_format(f, json_variant_by_index(v, i+1), flags, prefix2);
1752 if (r < 0)
1753 return r;
1754 }
1755
1756 if (flags & JSON_FORMAT_PRETTY) {
1757 fputc('\n', f);
1758 print_source(f, v, flags, true);
1759 fputs(strempty(prefix), f);
1760 }
1761
1762 fputc('}', f);
1763 }
1764 break;
1765 }
1766
1767 default:
1768 assert_not_reached();
1769 }
1770
1771 return 0;
1772 }
1773
1774 static bool json_variant_is_sensitive_recursive(JsonVariant *v) {
1775 if (!v)
1776 return false;
1777 if (json_variant_is_sensitive(v))
1778 return true;
1779 if (!json_variant_is_regular(v))
1780 return false;
1781 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1782 return false;
1783 if (v->is_reference)
1784 return json_variant_is_sensitive_recursive(v->reference);
1785
1786 for (size_t i = 0; i < json_variant_elements(v); i++)
1787 if (json_variant_is_sensitive_recursive(json_variant_by_index(v, i)))
1788 return true;
1789
1790 return false;
1791 }
1792
1793 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
1794 _cleanup_(memstream_done) MemStream m = {};
1795 size_t sz;
1796 FILE *f;
1797 int r;
1798
1799 /* Returns the length of the generated string (without the terminating NUL),
1800 * or negative on error. */
1801
1802 assert_return(v, -EINVAL);
1803 assert_return(ret, -EINVAL);
1804
1805 if (flags & JSON_FORMAT_OFF)
1806 return -ENOEXEC;
1807
1808 if ((flags & JSON_FORMAT_REFUSE_SENSITIVE))
1809 if (json_variant_is_sensitive_recursive(v))
1810 return -EPERM;
1811
1812 f = memstream_init(&m);
1813 if (!f)
1814 return -ENOMEM;
1815
1816 r = json_variant_dump(v, flags, f, NULL);
1817 if (r < 0)
1818 return r;
1819
1820 r = memstream_finalize(&m, ret, &sz);
1821 if (r < 0)
1822 return r;
1823
1824 return sz;
1825 }
1826
1827 int json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) {
1828 if (!v) {
1829 if (flags & JSON_FORMAT_EMPTY_ARRAY)
1830 v = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
1831 else
1832 return 0;
1833 }
1834
1835 if (!f)
1836 f = stdout;
1837
1838 print_source(f, v, flags, false);
1839
1840 if (((flags & (JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_COLOR)) == JSON_FORMAT_COLOR_AUTO) && colors_enabled())
1841 flags |= JSON_FORMAT_COLOR;
1842
1843 if (((flags & (JSON_FORMAT_PRETTY_AUTO|JSON_FORMAT_PRETTY)) == JSON_FORMAT_PRETTY_AUTO))
1844 flags |= on_tty() ? JSON_FORMAT_PRETTY : JSON_FORMAT_NEWLINE;
1845
1846 if (flags & JSON_FORMAT_SSE)
1847 fputs("data: ", f);
1848 if (flags & JSON_FORMAT_SEQ)
1849 fputc('\x1e', f); /* ASCII Record Separator */
1850
1851 json_format(f, v, flags, prefix);
1852
1853 if (flags & (JSON_FORMAT_PRETTY|JSON_FORMAT_SEQ|JSON_FORMAT_SSE|JSON_FORMAT_NEWLINE))
1854 fputc('\n', f);
1855 if (flags & JSON_FORMAT_SSE)
1856 fputc('\n', f); /* In case of SSE add a second newline */
1857
1858 if (flags & JSON_FORMAT_FLUSH)
1859 return fflush_and_check(f);
1860 return 0;
1861 }
1862
1863 int json_variant_filter(JsonVariant **v, char **to_remove) {
1864 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1865 _cleanup_free_ JsonVariant **array = NULL;
1866 size_t n = 0, k = 0;
1867 int r;
1868
1869 assert(v);
1870
1871 if (json_variant_is_blank_object(*v))
1872 return 0;
1873 if (!json_variant_is_object(*v))
1874 return -EINVAL;
1875
1876 if (strv_isempty(to_remove))
1877 return 0;
1878
1879 for (size_t i = 0; i < json_variant_elements(*v); i += 2) {
1880 JsonVariant *p;
1881
1882 p = json_variant_by_index(*v, i);
1883 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1884 return -EINVAL;
1885
1886 if (strv_contains(to_remove, json_variant_string(p))) {
1887 if (!array) {
1888 array = new(JsonVariant*, json_variant_elements(*v) - 2);
1889 if (!array)
1890 return -ENOMEM;
1891
1892 for (k = 0; k < i; k++)
1893 array[k] = json_variant_by_index(*v, k);
1894 }
1895
1896 n++;
1897 } else if (array) {
1898 array[k++] = p;
1899 array[k++] = json_variant_by_index(*v, i + 1);
1900 }
1901 }
1902
1903 if (n == 0)
1904 return 0;
1905
1906 r = json_variant_new_object(&w, array, k);
1907 if (r < 0)
1908 return r;
1909
1910 json_variant_propagate_sensitive(*v, w);
1911 JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
1912
1913 return (int) n;
1914 }
1915
1916 int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value) {
1917 _cleanup_(json_variant_unrefp) JsonVariant *field_variant = NULL, *w = NULL;
1918 _cleanup_free_ JsonVariant **array = NULL;
1919 size_t k = 0;
1920 int r;
1921
1922 assert(v);
1923 assert(field);
1924
1925 if (json_variant_is_blank_object(*v)) {
1926 array = new(JsonVariant*, 2);
1927 if (!array)
1928 return -ENOMEM;
1929
1930 } else {
1931 if (!json_variant_is_object(*v))
1932 return -EINVAL;
1933
1934 for (size_t i = 0; i < json_variant_elements(*v); i += 2) {
1935 JsonVariant *p;
1936
1937 p = json_variant_by_index(*v, i);
1938 if (!json_variant_is_string(p))
1939 return -EINVAL;
1940
1941 if (streq(json_variant_string(p), field)) {
1942
1943 if (!array) {
1944 array = new(JsonVariant*, json_variant_elements(*v));
1945 if (!array)
1946 return -ENOMEM;
1947
1948 for (k = 0; k < i; k++)
1949 array[k] = json_variant_by_index(*v, k);
1950 }
1951
1952 } else if (array) {
1953 array[k++] = p;
1954 array[k++] = json_variant_by_index(*v, i + 1);
1955 }
1956 }
1957
1958 if (!array) {
1959 array = new(JsonVariant*, json_variant_elements(*v) + 2);
1960 if (!array)
1961 return -ENOMEM;
1962
1963 for (k = 0; k < json_variant_elements(*v); k++)
1964 array[k] = json_variant_by_index(*v, k);
1965 }
1966 }
1967
1968 r = json_variant_new_string(&field_variant, field);
1969 if (r < 0)
1970 return r;
1971
1972 array[k++] = field_variant;
1973 array[k++] = value;
1974
1975 r = json_variant_new_object(&w, array, k);
1976 if (r < 0)
1977 return r;
1978
1979 json_variant_propagate_sensitive(*v, w);
1980 JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
1981
1982 return 1;
1983 }
1984
1985 int json_variant_set_fieldb(JsonVariant **v, const char *field, ...) {
1986 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1987 va_list ap;
1988 int r;
1989
1990 va_start(ap, field);
1991 r = json_buildv(&w, ap);
1992 va_end(ap);
1993 if (r < 0)
1994 return r;
1995
1996 return json_variant_set_field(v, field, w);
1997 }
1998
1999 int json_variant_set_field_string(JsonVariant **v, const char *field, const char *value) {
2000 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2001 int r;
2002
2003 r = json_variant_new_string(&m, value);
2004 if (r < 0)
2005 return r;
2006
2007 return json_variant_set_field(v, field, m);
2008 }
2009
2010 int json_variant_set_field_integer(JsonVariant **v, const char *field, int64_t i) {
2011 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2012 int r;
2013
2014 r = json_variant_new_integer(&m, i);
2015 if (r < 0)
2016 return r;
2017
2018 return json_variant_set_field(v, field, m);
2019 }
2020
2021 int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uint64_t u) {
2022 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2023 int r;
2024
2025 r = json_variant_new_unsigned(&m, u);
2026 if (r < 0)
2027 return r;
2028
2029 return json_variant_set_field(v, field, m);
2030 }
2031
2032 int json_variant_set_field_boolean(JsonVariant **v, const char *field, bool b) {
2033 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2034 int r;
2035
2036 r = json_variant_new_boolean(&m, b);
2037 if (r < 0)
2038 return r;
2039
2040 return json_variant_set_field(v, field, m);
2041 }
2042
2043 int json_variant_set_field_strv(JsonVariant **v, const char *field, char **l) {
2044 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2045 int r;
2046
2047 r = json_variant_new_array_strv(&m, l);
2048 if (r < 0)
2049 return r;
2050
2051 return json_variant_set_field(v, field, m);
2052 }
2053
2054 int json_variant_merge_object(JsonVariant **v, JsonVariant *m) {
2055 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
2056 _cleanup_free_ JsonVariant **array = NULL;
2057 size_t v_elements, m_elements, k;
2058 bool v_blank, m_blank;
2059 int r;
2060
2061 m = json_variant_dereference(m);
2062
2063 v_blank = json_variant_is_blank_object(*v);
2064 m_blank = json_variant_is_blank_object(m);
2065
2066 if (!v_blank && !json_variant_is_object(*v))
2067 return -EINVAL;
2068 if (!m_blank && !json_variant_is_object(m))
2069 return -EINVAL;
2070
2071 if (m_blank)
2072 return 0; /* nothing to do */
2073
2074 if (v_blank) {
2075 JSON_VARIANT_REPLACE(*v, json_variant_ref(m));
2076 return 1;
2077 }
2078
2079 v_elements = json_variant_elements(*v);
2080 m_elements = json_variant_elements(m);
2081 if (v_elements > SIZE_MAX - m_elements) /* overflow check */
2082 return -ENOMEM;
2083
2084 array = new(JsonVariant*, v_elements + m_elements);
2085 if (!array)
2086 return -ENOMEM;
2087
2088 k = 0;
2089 for (size_t i = 0; i < v_elements; i += 2) {
2090 JsonVariant *u;
2091
2092 u = json_variant_by_index(*v, i);
2093 if (!json_variant_is_string(u))
2094 return -EINVAL;
2095
2096 if (json_variant_by_key(m, json_variant_string(u)))
2097 continue; /* skip if exists in second variant */
2098
2099 array[k++] = u;
2100 array[k++] = json_variant_by_index(*v, i + 1);
2101 }
2102
2103 for (size_t i = 0; i < m_elements; i++)
2104 array[k++] = json_variant_by_index(m, i);
2105
2106 r = json_variant_new_object(&w, array, k);
2107 if (r < 0)
2108 return r;
2109
2110 json_variant_propagate_sensitive(*v, w);
2111 json_variant_propagate_sensitive(m, w);
2112 JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
2113
2114 return 1;
2115 }
2116
2117 int json_variant_merge_objectb(JsonVariant **v, ...) {
2118 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
2119 va_list ap;
2120 int r;
2121
2122 va_start(ap, v);
2123 r = json_buildv(&w, ap);
2124 va_end(ap);
2125 if (r < 0)
2126 return r;
2127
2128 return json_variant_merge_object(v, w);
2129 }
2130
2131 int json_variant_append_array(JsonVariant **v, JsonVariant *element) {
2132 _cleanup_(json_variant_unrefp) JsonVariant *nv = NULL;
2133 bool blank;
2134 int r;
2135
2136 assert(v);
2137 assert(element);
2138
2139 if (!*v || json_variant_is_null(*v))
2140 blank = true;
2141 else if (json_variant_is_array(*v))
2142 blank = json_variant_elements(*v) == 0;
2143 else
2144 return -EINVAL;
2145
2146 if (blank) {
2147 r = json_variant_new_array(&nv, (JsonVariant*[]) { element }, 1);
2148 if (r < 0)
2149 return r;
2150 } else if (json_variant_n_ref(*v) == 1) {
2151 /* Let's bump the reference count on element. We can't do the realloc if we're appending *v
2152 * to itself, or one of the objects embedded in *v to *v. If the reference count grows, we
2153 * need to fall back to the other method below. */
2154
2155 _unused_ _cleanup_(json_variant_unrefp) JsonVariant *dummy = json_variant_ref(element);
2156 if (json_variant_n_ref(*v) == 1) {
2157 /* We hold the only reference. Let's mutate the object. */
2158 size_t size = json_variant_elements(*v);
2159 void *old = *v;
2160
2161 if (!GREEDY_REALLOC(*v, size + 1 + 1))
2162 return -ENOMEM;
2163
2164 if (old != *v)
2165 /* Readjust the parent pointers to the new address */
2166 for (size_t i = 1; i < size; i++)
2167 (*v)[1 + i].parent = *v;
2168
2169 return _json_variant_array_put_element(*v, element);
2170 }
2171 }
2172
2173 if (!blank) {
2174 size_t size = json_variant_elements(*v);
2175
2176 _cleanup_free_ JsonVariant **array = new(JsonVariant*, size + 1);
2177 if (!array)
2178 return -ENOMEM;
2179
2180 for (size_t i = 0; i < size; i++)
2181 array[i] = json_variant_by_index(*v, i);
2182
2183 array[size] = element;
2184
2185 r = json_variant_new_array(&nv, array, size + 1);
2186 if (r < 0)
2187 return r;
2188 }
2189
2190 json_variant_propagate_sensitive(*v, nv);
2191 JSON_VARIANT_REPLACE(*v, TAKE_PTR(nv));
2192
2193 return 0;
2194 }
2195
2196 int json_variant_append_arrayb(JsonVariant **v, ...) {
2197 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
2198 va_list ap;
2199 int r;
2200
2201 va_start(ap, v);
2202 r = json_buildv(&w, ap);
2203 va_end(ap);
2204 if (r < 0)
2205 return r;
2206
2207 return json_variant_append_array(v, w);
2208 }
2209
2210 JsonVariant *json_variant_find(JsonVariant *haystack, JsonVariant *needle) {
2211 JsonVariant *i;
2212
2213 /* Find a json object in an array. Returns NULL if not found, or if the array is not actually an array. */
2214
2215 JSON_VARIANT_ARRAY_FOREACH(i, haystack)
2216 if (json_variant_equal(i, needle))
2217 return i;
2218
2219 return NULL;
2220 }
2221
2222 int json_variant_append_array_nodup(JsonVariant **v, JsonVariant *element) {
2223 assert(v);
2224
2225 if (json_variant_find(*v, element))
2226 return 0;
2227
2228 return json_variant_append_array(v, element);
2229 }
2230
2231 int json_variant_strv(JsonVariant *v, char ***ret) {
2232 char **l = NULL;
2233 bool sensitive;
2234 int r;
2235
2236 assert(ret);
2237
2238 if (!v || json_variant_is_null(v)) {
2239 l = new0(char*, 1);
2240 if (!l)
2241 return -ENOMEM;
2242
2243 *ret = l;
2244 return 0;
2245 }
2246
2247 if (!json_variant_is_array(v))
2248 return -EINVAL;
2249
2250 sensitive = json_variant_is_sensitive(v);
2251
2252 size_t n = json_variant_elements(v);
2253 l = new(char*, n+1);
2254 if (!l)
2255 return -ENOMEM;
2256
2257 for (size_t i = 0; i < n; i++) {
2258 JsonVariant *e;
2259
2260 assert_se(e = json_variant_by_index(v, i));
2261 sensitive = sensitive || json_variant_is_sensitive(e);
2262
2263 if (!json_variant_is_string(e)) {
2264 l[i] = NULL;
2265 r = -EINVAL;
2266 goto fail;
2267 }
2268
2269 l[i] = strdup(json_variant_string(e));
2270 if (!l[i]) {
2271 r = -ENOMEM;
2272 goto fail;
2273 }
2274 }
2275
2276 l[n] = NULL;
2277 *ret = TAKE_PTR(l);
2278
2279 return 0;
2280
2281 fail:
2282 if (sensitive)
2283 strv_free_erase(l);
2284 else
2285 strv_free(l);
2286
2287 return r;
2288 }
2289
2290 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
2291 JsonVariantType t;
2292 JsonVariant *c;
2293 JsonValue value;
2294 const void *source;
2295 size_t k;
2296
2297 assert(nv);
2298 assert(v);
2299
2300 /* Let's copy the simple types literally, and the larger types by references */
2301 t = json_variant_type(v);
2302 switch (t) {
2303 case JSON_VARIANT_INTEGER:
2304 k = sizeof(int64_t);
2305 value.integer = json_variant_integer(v);
2306 source = &value;
2307 break;
2308
2309 case JSON_VARIANT_UNSIGNED:
2310 k = sizeof(uint64_t);
2311 value.unsig = json_variant_unsigned(v);
2312 source = &value;
2313 break;
2314
2315 case JSON_VARIANT_REAL:
2316 k = sizeof(double);
2317 value.real = json_variant_real(v);
2318 source = &value;
2319 break;
2320
2321 case JSON_VARIANT_BOOLEAN:
2322 k = sizeof(bool);
2323 value.boolean = json_variant_boolean(v);
2324 source = &value;
2325 break;
2326
2327 case JSON_VARIANT_NULL:
2328 k = 0;
2329 source = NULL;
2330 break;
2331
2332 case JSON_VARIANT_STRING:
2333 source = json_variant_string(v);
2334 k = strnlen(source, INLINE_STRING_MAX + 1);
2335 if (k <= INLINE_STRING_MAX) {
2336 k++;
2337 break;
2338 }
2339
2340 _fallthrough_;
2341
2342 default:
2343 /* Everything else copy by reference */
2344
2345 c = malloc0(MAX(sizeof(JsonVariant),
2346 offsetof(JsonVariant, reference) + sizeof(JsonVariant*)));
2347 if (!c)
2348 return -ENOMEM;
2349
2350 c->n_ref = 1;
2351 c->type = t;
2352 c->is_reference = true;
2353 c->reference = json_variant_ref(json_variant_formalize(v));
2354
2355 *nv = c;
2356 return 0;
2357 }
2358
2359 c = malloc0(MAX(sizeof(JsonVariant),
2360 offsetof(JsonVariant, value) + k));
2361 if (!c)
2362 return -ENOMEM;
2363
2364 c->n_ref = 1;
2365 c->type = t;
2366
2367 memcpy_safe(&c->value, source, k);
2368
2369 json_variant_propagate_sensitive(v, c);
2370
2371 *nv = c;
2372 return 0;
2373 }
2374
2375 static bool json_single_ref(JsonVariant *v) {
2376
2377 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
2378
2379 if (!json_variant_is_regular(v))
2380 return false;
2381
2382 if (v->is_embedded)
2383 return json_single_ref(v->parent);
2384
2385 assert(v->n_ref > 0);
2386 return v->n_ref == 1;
2387 }
2388
2389 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
2390 JsonVariant *w;
2391 int r;
2392
2393 assert(v);
2394
2395 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole
2396 * referencer of the object. If not, allocates a new object, possibly a surrogate for the original
2397 * one */
2398
2399 if (!*v)
2400 return 0;
2401
2402 if (source && line > source->max_line)
2403 source->max_line = line;
2404 if (source && column > source->max_column)
2405 source->max_column = column;
2406
2407 if (!json_variant_is_regular(*v)) {
2408
2409 if (!source && line == 0 && column == 0)
2410 return 0;
2411
2412 } else {
2413 if (json_source_equal((*v)->source, source) &&
2414 (*v)->line == line &&
2415 (*v)->column == column)
2416 return 0;
2417
2418 if (json_single_ref(*v)) { /* Sole reference? */
2419 json_source_unref((*v)->source);
2420 (*v)->source = json_source_ref(source);
2421 (*v)->line = line;
2422 (*v)->column = column;
2423 return 1;
2424 }
2425 }
2426
2427 r = json_variant_copy(&w, *v);
2428 if (r < 0)
2429 return r;
2430
2431 assert(json_variant_is_regular(w));
2432 assert(!w->is_embedded);
2433 assert(w->n_ref == 1);
2434 assert(!w->source);
2435
2436 w->source = json_source_ref(source);
2437 w->line = line;
2438 w->column = column;
2439
2440 JSON_VARIANT_REPLACE(*v, w);
2441
2442 return 1;
2443 }
2444
2445 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
2446 assert(line);
2447 assert(column);
2448 assert(s || n == 0);
2449
2450 while (n > 0) {
2451 if (*s == '\n') {
2452 (*line)++;
2453 *column = 1;
2454 } else if ((signed char) *s >= 0 && *s < 127) /* Process ASCII chars quickly */
2455 (*column)++;
2456 else {
2457 int w;
2458
2459 w = utf8_encoded_valid_unichar(s, n);
2460 if (w < 0) /* count invalid unichars as normal characters */
2461 w = 1;
2462 else if ((size_t) w > n) /* never read more than the specified number of characters */
2463 w = (int) n;
2464
2465 (*column)++;
2466
2467 s += w;
2468 n -= w;
2469 continue;
2470 }
2471
2472 s++;
2473 n--;
2474 }
2475 }
2476
2477 static int unhex_ucs2(const char *c, uint16_t *ret) {
2478 int aa, bb, cc, dd;
2479 uint16_t x;
2480
2481 assert(c);
2482 assert(ret);
2483
2484 aa = unhexchar(c[0]);
2485 if (aa < 0)
2486 return -EINVAL;
2487
2488 bb = unhexchar(c[1]);
2489 if (bb < 0)
2490 return -EINVAL;
2491
2492 cc = unhexchar(c[2]);
2493 if (cc < 0)
2494 return -EINVAL;
2495
2496 dd = unhexchar(c[3]);
2497 if (dd < 0)
2498 return -EINVAL;
2499
2500 x = ((uint16_t) aa << 12) |
2501 ((uint16_t) bb << 8) |
2502 ((uint16_t) cc << 4) |
2503 ((uint16_t) dd);
2504
2505 if (x <= 0)
2506 return -EINVAL;
2507
2508 *ret = x;
2509
2510 return 0;
2511 }
2512
2513 static int json_parse_string(const char **p, char **ret) {
2514 _cleanup_free_ char *s = NULL;
2515 size_t n = 0;
2516 const char *c;
2517
2518 assert(p);
2519 assert(*p);
2520 assert(ret);
2521
2522 c = *p;
2523
2524 if (*c != '"')
2525 return -EINVAL;
2526
2527 c++;
2528
2529 for (;;) {
2530 int len;
2531
2532 /* Check for EOF */
2533 if (*c == 0)
2534 return -EINVAL;
2535
2536 /* Check for control characters 0x00..0x1f */
2537 if (*c > 0 && *c < ' ')
2538 return -EINVAL;
2539
2540 /* Check for control character 0x7f */
2541 if (*c == 0x7f)
2542 return -EINVAL;
2543
2544 if (*c == '"') {
2545 if (!s) {
2546 s = strdup("");
2547 if (!s)
2548 return -ENOMEM;
2549 } else
2550 s[n] = 0;
2551
2552 *p = c + 1;
2553
2554 *ret = TAKE_PTR(s);
2555 return JSON_TOKEN_STRING;
2556 }
2557
2558 if (*c == '\\') {
2559 char ch = 0;
2560 c++;
2561
2562 if (*c == 0)
2563 return -EINVAL;
2564
2565 if (IN_SET(*c, '"', '\\', '/'))
2566 ch = *c;
2567 else if (*c == 'b')
2568 ch = '\b';
2569 else if (*c == 'f')
2570 ch = '\f';
2571 else if (*c == 'n')
2572 ch = '\n';
2573 else if (*c == 'r')
2574 ch = '\r';
2575 else if (*c == 't')
2576 ch = '\t';
2577 else if (*c == 'u') {
2578 char16_t x;
2579 int r;
2580
2581 r = unhex_ucs2(c + 1, &x);
2582 if (r < 0)
2583 return r;
2584
2585 c += 5;
2586
2587 if (!GREEDY_REALLOC(s, n + 5))
2588 return -ENOMEM;
2589
2590 if (!utf16_is_surrogate(x))
2591 n += utf8_encode_unichar(s + n, (char32_t) x);
2592 else if (utf16_is_trailing_surrogate(x))
2593 return -EINVAL;
2594 else {
2595 char16_t y;
2596
2597 if (c[0] != '\\' || c[1] != 'u')
2598 return -EINVAL;
2599
2600 r = unhex_ucs2(c + 2, &y);
2601 if (r < 0)
2602 return r;
2603
2604 c += 6;
2605
2606 if (!utf16_is_trailing_surrogate(y))
2607 return -EINVAL;
2608
2609 n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
2610 }
2611
2612 continue;
2613 } else
2614 return -EINVAL;
2615
2616 if (!GREEDY_REALLOC(s, n + 2))
2617 return -ENOMEM;
2618
2619 s[n++] = ch;
2620 c++;
2621 continue;
2622 }
2623
2624 len = utf8_encoded_valid_unichar(c, SIZE_MAX);
2625 if (len < 0)
2626 return len;
2627
2628 if (!GREEDY_REALLOC(s, n + len + 1))
2629 return -ENOMEM;
2630
2631 memcpy(s + n, c, len);
2632 n += len;
2633 c += len;
2634 }
2635 }
2636
2637 static int json_parse_number(const char **p, JsonValue *ret) {
2638 bool negative = false, exponent_negative = false, is_real = false;
2639 double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
2640 int64_t i = 0;
2641 uint64_t u = 0;
2642 const char *c;
2643
2644 assert(p);
2645 assert(*p);
2646 assert(ret);
2647
2648 c = *p;
2649
2650 if (*c == '-') {
2651 negative = true;
2652 c++;
2653 }
2654
2655 if (*c == '0')
2656 c++;
2657 else {
2658 if (!strchr("123456789", *c) || *c == 0)
2659 return -EINVAL;
2660
2661 do {
2662 if (!is_real) {
2663 if (negative) {
2664
2665 if (i < INT64_MIN / 10) /* overflow */
2666 is_real = true;
2667 else {
2668 int64_t t = 10 * i;
2669
2670 if (t < INT64_MIN + (*c - '0')) /* overflow */
2671 is_real = true;
2672 else
2673 i = t - (*c - '0');
2674 }
2675 } else {
2676 if (u > UINT64_MAX / 10) /* overflow */
2677 is_real = true;
2678 else {
2679 uint64_t t = 10 * u;
2680
2681 if (t > UINT64_MAX - (*c - '0')) /* overflow */
2682 is_real = true;
2683 else
2684 u = t + (*c - '0');
2685 }
2686 }
2687 }
2688
2689 x = 10.0 * x + (*c - '0');
2690
2691 c++;
2692 } while (strchr("0123456789", *c) && *c != 0);
2693 }
2694
2695 if (*c == '.') {
2696 is_real = true;
2697 c++;
2698
2699 if (!strchr("0123456789", *c) || *c == 0)
2700 return -EINVAL;
2701
2702 do {
2703 y = 10.0 * y + (*c - '0');
2704 shift = 10.0 * shift;
2705 c++;
2706 } while (strchr("0123456789", *c) && *c != 0);
2707 }
2708
2709 if (IN_SET(*c, 'e', 'E')) {
2710 is_real = true;
2711 c++;
2712
2713 if (*c == '-') {
2714 exponent_negative = true;
2715 c++;
2716 } else if (*c == '+')
2717 c++;
2718
2719 if (!strchr("0123456789", *c) || *c == 0)
2720 return -EINVAL;
2721
2722 do {
2723 exponent = 10.0 * exponent + (*c - '0');
2724 c++;
2725 } while (strchr("0123456789", *c) && *c != 0);
2726 }
2727
2728 *p = c;
2729
2730 if (is_real) {
2731 ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10((exponent_negative ? -1.0 : 1.0) * exponent);
2732 return JSON_TOKEN_REAL;
2733 } else if (negative) {
2734 ret->integer = i;
2735 return JSON_TOKEN_INTEGER;
2736 } else {
2737 ret->unsig = u;
2738 return JSON_TOKEN_UNSIGNED;
2739 }
2740 }
2741
2742 int json_tokenize(
2743 const char **p,
2744 char **ret_string,
2745 JsonValue *ret_value,
2746 unsigned *ret_line, /* 'ret_line' returns the line at the beginning of this token */
2747 unsigned *ret_column,
2748 void **state,
2749 unsigned *line, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2750 unsigned *column) {
2751
2752 unsigned start_line, start_column;
2753 const char *start, *c;
2754 size_t n;
2755 int t, r;
2756
2757 enum {
2758 STATE_NULL,
2759 STATE_VALUE,
2760 STATE_VALUE_POST,
2761 };
2762
2763 assert(p);
2764 assert(*p);
2765 assert(ret_string);
2766 assert(ret_value);
2767 assert(ret_line);
2768 assert(ret_column);
2769 assert(line);
2770 assert(column);
2771 assert(state);
2772
2773 t = PTR_TO_INT(*state);
2774 if (t == STATE_NULL) {
2775 *line = 1;
2776 *column = 1;
2777 t = STATE_VALUE;
2778 }
2779
2780 /* Skip over the whitespace */
2781 n = strspn(*p, WHITESPACE);
2782 inc_lines_columns(line, column, *p, n);
2783 c = *p + n;
2784
2785 /* Remember where we started processing this token */
2786 start = c;
2787 start_line = *line;
2788 start_column = *column;
2789
2790 if (*c == 0) {
2791 *ret_string = NULL;
2792 *ret_value = JSON_VALUE_NULL;
2793 r = JSON_TOKEN_END;
2794 goto finish;
2795 }
2796
2797 switch (t) {
2798
2799 case STATE_VALUE:
2800
2801 if (*c == '{') {
2802 c++;
2803 *state = INT_TO_PTR(STATE_VALUE);
2804 r = JSON_TOKEN_OBJECT_OPEN;
2805 goto null_return;
2806
2807 } else if (*c == '}') {
2808 c++;
2809 *state = INT_TO_PTR(STATE_VALUE_POST);
2810 r = JSON_TOKEN_OBJECT_CLOSE;
2811 goto null_return;
2812
2813 } else if (*c == '[') {
2814 c++;
2815 *state = INT_TO_PTR(STATE_VALUE);
2816 r = JSON_TOKEN_ARRAY_OPEN;
2817 goto null_return;
2818
2819 } else if (*c == ']') {
2820 c++;
2821 *state = INT_TO_PTR(STATE_VALUE_POST);
2822 r = JSON_TOKEN_ARRAY_CLOSE;
2823 goto null_return;
2824
2825 } else if (*c == '"') {
2826
2827 r = json_parse_string(&c, ret_string);
2828 if (r < 0)
2829 return r;
2830
2831 *ret_value = JSON_VALUE_NULL;
2832 *state = INT_TO_PTR(STATE_VALUE_POST);
2833 goto finish;
2834
2835 } else if (strchr("-0123456789", *c)) {
2836
2837 r = json_parse_number(&c, ret_value);
2838 if (r < 0)
2839 return r;
2840
2841 *ret_string = NULL;
2842 *state = INT_TO_PTR(STATE_VALUE_POST);
2843 goto finish;
2844
2845 } else if (startswith(c, "true")) {
2846 *ret_string = NULL;
2847 ret_value->boolean = true;
2848 c += 4;
2849 *state = INT_TO_PTR(STATE_VALUE_POST);
2850 r = JSON_TOKEN_BOOLEAN;
2851 goto finish;
2852
2853 } else if (startswith(c, "false")) {
2854 *ret_string = NULL;
2855 ret_value->boolean = false;
2856 c += 5;
2857 *state = INT_TO_PTR(STATE_VALUE_POST);
2858 r = JSON_TOKEN_BOOLEAN;
2859 goto finish;
2860
2861 } else if (startswith(c, "null")) {
2862 *ret_string = NULL;
2863 *ret_value = JSON_VALUE_NULL;
2864 c += 4;
2865 *state = INT_TO_PTR(STATE_VALUE_POST);
2866 r = JSON_TOKEN_NULL;
2867 goto finish;
2868
2869 }
2870
2871 return -EINVAL;
2872
2873 case STATE_VALUE_POST:
2874
2875 if (*c == ':') {
2876 c++;
2877 *state = INT_TO_PTR(STATE_VALUE);
2878 r = JSON_TOKEN_COLON;
2879 goto null_return;
2880
2881 } else if (*c == ',') {
2882 c++;
2883 *state = INT_TO_PTR(STATE_VALUE);
2884 r = JSON_TOKEN_COMMA;
2885 goto null_return;
2886
2887 } else if (*c == '}') {
2888 c++;
2889 *state = INT_TO_PTR(STATE_VALUE_POST);
2890 r = JSON_TOKEN_OBJECT_CLOSE;
2891 goto null_return;
2892
2893 } else if (*c == ']') {
2894 c++;
2895 *state = INT_TO_PTR(STATE_VALUE_POST);
2896 r = JSON_TOKEN_ARRAY_CLOSE;
2897 goto null_return;
2898 }
2899
2900 return -EINVAL;
2901
2902 default:
2903 assert_not_reached();
2904 }
2905
2906 null_return:
2907 *ret_string = NULL;
2908 *ret_value = JSON_VALUE_NULL;
2909
2910 finish:
2911 inc_lines_columns(line, column, start, c - start);
2912 *p = c;
2913
2914 *ret_line = start_line;
2915 *ret_column = start_column;
2916
2917 return r;
2918 }
2919
2920 typedef enum JsonExpect {
2921 /* The following values are used by json_parse() */
2922 EXPECT_TOPLEVEL,
2923 EXPECT_END,
2924 EXPECT_OBJECT_FIRST_KEY,
2925 EXPECT_OBJECT_NEXT_KEY,
2926 EXPECT_OBJECT_COLON,
2927 EXPECT_OBJECT_VALUE,
2928 EXPECT_OBJECT_COMMA,
2929 EXPECT_ARRAY_FIRST_ELEMENT,
2930 EXPECT_ARRAY_NEXT_ELEMENT,
2931 EXPECT_ARRAY_COMMA,
2932
2933 /* And these are used by json_build() */
2934 EXPECT_ARRAY_ELEMENT,
2935 EXPECT_OBJECT_KEY,
2936 } JsonExpect;
2937
2938 typedef struct JsonStack {
2939 JsonExpect expect;
2940 JsonVariant **elements;
2941 size_t n_elements;
2942 unsigned line_before;
2943 unsigned column_before;
2944 size_t n_suppress; /* When building: if > 0, suppress this many subsequent elements. If == SIZE_MAX, suppress all subsequent elements */
2945 } JsonStack;
2946
2947 static void json_stack_release(JsonStack *s) {
2948 assert(s);
2949
2950 CLEANUP_ARRAY(s->elements, s->n_elements, json_variant_unref_many);
2951 }
2952
2953 static int json_parse_internal(
2954 const char **input,
2955 JsonSource *source,
2956 JsonParseFlags flags,
2957 JsonVariant **ret,
2958 unsigned *line,
2959 unsigned *column,
2960 bool continue_end) {
2961
2962 size_t n_stack = 1;
2963 unsigned line_buffer = 0, column_buffer = 0;
2964 void *tokenizer_state = NULL;
2965 JsonStack *stack = NULL;
2966 const char *p;
2967 int r;
2968
2969 assert_return(input, -EINVAL);
2970 assert_return(ret, -EINVAL);
2971
2972 p = *input;
2973
2974 if (!GREEDY_REALLOC(stack, n_stack))
2975 return -ENOMEM;
2976
2977 stack[0] = (JsonStack) {
2978 .expect = EXPECT_TOPLEVEL,
2979 };
2980
2981 if (!line)
2982 line = &line_buffer;
2983 if (!column)
2984 column = &column_buffer;
2985
2986 for (;;) {
2987 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL;
2988 _cleanup_free_ char *string = NULL;
2989 unsigned line_token, column_token;
2990 JsonStack *current;
2991 JsonValue value;
2992 int token;
2993
2994 assert(n_stack > 0);
2995 current = stack + n_stack - 1;
2996
2997 if (continue_end && current->expect == EXPECT_END)
2998 goto done;
2999
3000 token = json_tokenize(&p, &string, &value, &line_token, &column_token, &tokenizer_state, line, column);
3001 if (token < 0) {
3002 r = token;
3003 goto finish;
3004 }
3005
3006 switch (token) {
3007
3008 case JSON_TOKEN_END:
3009 if (current->expect != EXPECT_END) {
3010 r = -EINVAL;
3011 goto finish;
3012 }
3013
3014 assert(current->n_elements == 1);
3015 assert(n_stack == 1);
3016 goto done;
3017
3018 case JSON_TOKEN_COLON:
3019
3020 if (current->expect != EXPECT_OBJECT_COLON) {
3021 r = -EINVAL;
3022 goto finish;
3023 }
3024
3025 current->expect = EXPECT_OBJECT_VALUE;
3026 break;
3027
3028 case JSON_TOKEN_COMMA:
3029
3030 if (current->expect == EXPECT_OBJECT_COMMA)
3031 current->expect = EXPECT_OBJECT_NEXT_KEY;
3032 else if (current->expect == EXPECT_ARRAY_COMMA)
3033 current->expect = EXPECT_ARRAY_NEXT_ELEMENT;
3034 else {
3035 r = -EINVAL;
3036 goto finish;
3037 }
3038
3039 break;
3040
3041 case JSON_TOKEN_OBJECT_OPEN:
3042
3043 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3044 r = -EINVAL;
3045 goto finish;
3046 }
3047
3048 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3049 r = -ENOMEM;
3050 goto finish;
3051 }
3052 current = stack + n_stack - 1;
3053
3054 /* Prepare the expect for when we return from the child */
3055 if (current->expect == EXPECT_TOPLEVEL)
3056 current->expect = EXPECT_END;
3057 else if (current->expect == EXPECT_OBJECT_VALUE)
3058 current->expect = EXPECT_OBJECT_COMMA;
3059 else {
3060 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3061 current->expect = EXPECT_ARRAY_COMMA;
3062 }
3063
3064 stack[n_stack++] = (JsonStack) {
3065 .expect = EXPECT_OBJECT_FIRST_KEY,
3066 .line_before = line_token,
3067 .column_before = column_token,
3068 };
3069
3070 current = stack + n_stack - 1;
3071 break;
3072
3073 case JSON_TOKEN_OBJECT_CLOSE:
3074 if (!IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_COMMA)) {
3075 r = -EINVAL;
3076 goto finish;
3077 }
3078
3079 assert(n_stack > 1);
3080
3081 r = json_variant_new_object(&add, current->elements, current->n_elements);
3082 if (r < 0)
3083 goto finish;
3084
3085 line_token = current->line_before;
3086 column_token = current->column_before;
3087
3088 json_stack_release(current);
3089 n_stack--, current--;
3090
3091 break;
3092
3093 case JSON_TOKEN_ARRAY_OPEN:
3094 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3095 r = -EINVAL;
3096 goto finish;
3097 }
3098
3099 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3100 r = -ENOMEM;
3101 goto finish;
3102 }
3103 current = stack + n_stack - 1;
3104
3105 /* Prepare the expect for when we return from the child */
3106 if (current->expect == EXPECT_TOPLEVEL)
3107 current->expect = EXPECT_END;
3108 else if (current->expect == EXPECT_OBJECT_VALUE)
3109 current->expect = EXPECT_OBJECT_COMMA;
3110 else {
3111 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3112 current->expect = EXPECT_ARRAY_COMMA;
3113 }
3114
3115 stack[n_stack++] = (JsonStack) {
3116 .expect = EXPECT_ARRAY_FIRST_ELEMENT,
3117 .line_before = line_token,
3118 .column_before = column_token,
3119 };
3120
3121 break;
3122
3123 case JSON_TOKEN_ARRAY_CLOSE:
3124 if (!IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_COMMA)) {
3125 r = -EINVAL;
3126 goto finish;
3127 }
3128
3129 assert(n_stack > 1);
3130
3131 r = json_variant_new_array(&add, current->elements, current->n_elements);
3132 if (r < 0)
3133 goto finish;
3134
3135 line_token = current->line_before;
3136 column_token = current->column_before;
3137
3138 json_stack_release(current);
3139 n_stack--, current--;
3140 break;
3141
3142 case JSON_TOKEN_STRING:
3143 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_NEXT_KEY, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3144 r = -EINVAL;
3145 goto finish;
3146 }
3147
3148 r = json_variant_new_string(&add, string);
3149 if (r < 0)
3150 goto finish;
3151
3152 if (current->expect == EXPECT_TOPLEVEL)
3153 current->expect = EXPECT_END;
3154 else if (IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_NEXT_KEY))
3155 current->expect = EXPECT_OBJECT_COLON;
3156 else if (current->expect == EXPECT_OBJECT_VALUE)
3157 current->expect = EXPECT_OBJECT_COMMA;
3158 else {
3159 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3160 current->expect = EXPECT_ARRAY_COMMA;
3161 }
3162
3163 break;
3164
3165 case JSON_TOKEN_REAL:
3166 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3167 r = -EINVAL;
3168 goto finish;
3169 }
3170
3171 r = json_variant_new_real(&add, value.real);
3172 if (r < 0)
3173 goto finish;
3174
3175 if (current->expect == EXPECT_TOPLEVEL)
3176 current->expect = EXPECT_END;
3177 else if (current->expect == EXPECT_OBJECT_VALUE)
3178 current->expect = EXPECT_OBJECT_COMMA;
3179 else {
3180 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3181 current->expect = EXPECT_ARRAY_COMMA;
3182 }
3183
3184 break;
3185
3186 case JSON_TOKEN_INTEGER:
3187 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3188 r = -EINVAL;
3189 goto finish;
3190 }
3191
3192 r = json_variant_new_integer(&add, value.integer);
3193 if (r < 0)
3194 goto finish;
3195
3196 if (current->expect == EXPECT_TOPLEVEL)
3197 current->expect = EXPECT_END;
3198 else if (current->expect == EXPECT_OBJECT_VALUE)
3199 current->expect = EXPECT_OBJECT_COMMA;
3200 else {
3201 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3202 current->expect = EXPECT_ARRAY_COMMA;
3203 }
3204
3205 break;
3206
3207 case JSON_TOKEN_UNSIGNED:
3208 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3209 r = -EINVAL;
3210 goto finish;
3211 }
3212
3213 r = json_variant_new_unsigned(&add, value.unsig);
3214 if (r < 0)
3215 goto finish;
3216
3217 if (current->expect == EXPECT_TOPLEVEL)
3218 current->expect = EXPECT_END;
3219 else if (current->expect == EXPECT_OBJECT_VALUE)
3220 current->expect = EXPECT_OBJECT_COMMA;
3221 else {
3222 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3223 current->expect = EXPECT_ARRAY_COMMA;
3224 }
3225
3226 break;
3227
3228 case JSON_TOKEN_BOOLEAN:
3229 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3230 r = -EINVAL;
3231 goto finish;
3232 }
3233
3234 r = json_variant_new_boolean(&add, value.boolean);
3235 if (r < 0)
3236 goto finish;
3237
3238 if (current->expect == EXPECT_TOPLEVEL)
3239 current->expect = EXPECT_END;
3240 else if (current->expect == EXPECT_OBJECT_VALUE)
3241 current->expect = EXPECT_OBJECT_COMMA;
3242 else {
3243 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3244 current->expect = EXPECT_ARRAY_COMMA;
3245 }
3246
3247 break;
3248
3249 case JSON_TOKEN_NULL:
3250 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3251 r = -EINVAL;
3252 goto finish;
3253 }
3254
3255 r = json_variant_new_null(&add);
3256 if (r < 0)
3257 goto finish;
3258
3259 if (current->expect == EXPECT_TOPLEVEL)
3260 current->expect = EXPECT_END;
3261 else if (current->expect == EXPECT_OBJECT_VALUE)
3262 current->expect = EXPECT_OBJECT_COMMA;
3263 else {
3264 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3265 current->expect = EXPECT_ARRAY_COMMA;
3266 }
3267
3268 break;
3269
3270 default:
3271 assert_not_reached();
3272 }
3273
3274 if (add) {
3275 /* If we are asked to make this parsed object sensitive, then let's apply this
3276 * immediately after allocating each variant, so that when we abort half-way
3277 * everything we already allocated that is then freed is correctly marked. */
3278 if (FLAGS_SET(flags, JSON_PARSE_SENSITIVE))
3279 json_variant_sensitive(add);
3280
3281 (void) json_variant_set_source(&add, source, line_token, column_token);
3282
3283 if (!GREEDY_REALLOC(current->elements, current->n_elements + 1)) {
3284 r = -ENOMEM;
3285 goto finish;
3286 }
3287
3288 current->elements[current->n_elements++] = TAKE_PTR(add);
3289 }
3290 }
3291
3292 done:
3293 assert(n_stack == 1);
3294 assert(stack[0].n_elements == 1);
3295
3296 *ret = json_variant_ref(stack[0].elements[0]);
3297 *input = p;
3298 r = 0;
3299
3300 finish:
3301 for (size_t i = 0; i < n_stack; i++)
3302 json_stack_release(stack + i);
3303
3304 free(stack);
3305
3306 return r;
3307 }
3308
3309 int json_parse_with_source(
3310 const char *input,
3311 const char *source,
3312 JsonParseFlags flags,
3313 JsonVariant **ret,
3314 unsigned *ret_line,
3315 unsigned *ret_column) {
3316
3317 _cleanup_(json_source_unrefp) JsonSource *s = NULL;
3318
3319 if (source) {
3320 s = json_source_new(source);
3321 if (!s)
3322 return -ENOMEM;
3323 }
3324
3325 return json_parse_internal(&input, s, flags, ret, ret_line, ret_column, false);
3326 }
3327
3328 int json_parse_with_source_continue(
3329 const char **p,
3330 const char *source,
3331 JsonParseFlags flags,
3332 JsonVariant **ret,
3333 unsigned *ret_line,
3334 unsigned *ret_column) {
3335
3336 _cleanup_(json_source_unrefp) JsonSource *s = NULL;
3337
3338 if (source) {
3339 s = json_source_new(source);
3340 if (!s)
3341 return -ENOMEM;
3342 }
3343
3344 return json_parse_internal(p, s, flags, ret, ret_line, ret_column, true);
3345 }
3346
3347 int json_parse_file_at(
3348 FILE *f,
3349 int dir_fd,
3350 const char *path,
3351 JsonParseFlags flags,
3352 JsonVariant **ret,
3353 unsigned *ret_line,
3354 unsigned *ret_column) {
3355
3356 _cleanup_free_ char *text = NULL;
3357 int r;
3358
3359 if (f)
3360 r = read_full_stream(f, &text, NULL);
3361 else if (path)
3362 r = read_full_file_full(dir_fd, path, UINT64_MAX, SIZE_MAX, 0, NULL, &text, NULL);
3363 else
3364 return -EINVAL;
3365 if (r < 0)
3366 return r;
3367
3368 if (isempty(text))
3369 return -ENODATA;
3370
3371 return json_parse_with_source(text, path, flags, ret, ret_line, ret_column);
3372 }
3373
3374 int json_buildv(JsonVariant **ret, va_list ap) {
3375 JsonStack *stack = NULL;
3376 size_t n_stack = 1;
3377 const char *name = NULL;
3378 int r;
3379
3380 assert_return(ret, -EINVAL);
3381
3382 if (!GREEDY_REALLOC(stack, n_stack))
3383 return -ENOMEM;
3384
3385 stack[0] = (JsonStack) {
3386 .expect = EXPECT_TOPLEVEL,
3387 };
3388
3389 for (;;) {
3390 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL, *add_more = NULL;
3391 size_t n_subtract = 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
3392 * have been added to the current variant */
3393 JsonStack *current;
3394 int command;
3395
3396 assert(n_stack > 0);
3397 current = stack + n_stack - 1;
3398
3399 if (current->expect == EXPECT_END)
3400 goto done;
3401
3402 command = va_arg(ap, int);
3403
3404 switch (command) {
3405
3406 case _JSON_BUILD_STRING: {
3407 const char *p;
3408
3409 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3410 r = -EINVAL;
3411 goto finish;
3412 }
3413
3414 p = va_arg(ap, const char *);
3415
3416 if (current->n_suppress == 0) {
3417 r = json_variant_new_string(&add, p);
3418 if (r < 0)
3419 goto finish;
3420 }
3421
3422 n_subtract = 1;
3423
3424 if (current->expect == EXPECT_TOPLEVEL)
3425 current->expect = EXPECT_END;
3426 else if (current->expect == EXPECT_OBJECT_VALUE)
3427 current->expect = EXPECT_OBJECT_KEY;
3428 else
3429 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3430
3431 break;
3432 }
3433
3434 case _JSON_BUILD_INTEGER: {
3435 int64_t j;
3436
3437 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3438 r = -EINVAL;
3439 goto finish;
3440 }
3441
3442 j = va_arg(ap, int64_t);
3443
3444 if (current->n_suppress == 0) {
3445 r = json_variant_new_integer(&add, j);
3446 if (r < 0)
3447 goto finish;
3448 }
3449
3450 n_subtract = 1;
3451
3452 if (current->expect == EXPECT_TOPLEVEL)
3453 current->expect = EXPECT_END;
3454 else if (current->expect == EXPECT_OBJECT_VALUE)
3455 current->expect = EXPECT_OBJECT_KEY;
3456 else
3457 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3458
3459 break;
3460 }
3461
3462 case _JSON_BUILD_UNSIGNED: {
3463 uint64_t j;
3464
3465 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3466 r = -EINVAL;
3467 goto finish;
3468 }
3469
3470 j = va_arg(ap, uint64_t);
3471
3472 if (current->n_suppress == 0) {
3473 r = json_variant_new_unsigned(&add, j);
3474 if (r < 0)
3475 goto finish;
3476 }
3477
3478 n_subtract = 1;
3479
3480 if (current->expect == EXPECT_TOPLEVEL)
3481 current->expect = EXPECT_END;
3482 else if (current->expect == EXPECT_OBJECT_VALUE)
3483 current->expect = EXPECT_OBJECT_KEY;
3484 else
3485 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3486
3487 break;
3488 }
3489
3490 case _JSON_BUILD_REAL: {
3491 double d;
3492
3493 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3494 r = -EINVAL;
3495 goto finish;
3496 }
3497
3498 d = va_arg(ap, double);
3499
3500 if (current->n_suppress == 0) {
3501 r = json_variant_new_real(&add, d);
3502 if (r < 0)
3503 goto finish;
3504 }
3505
3506 n_subtract = 1;
3507
3508 if (current->expect == EXPECT_TOPLEVEL)
3509 current->expect = EXPECT_END;
3510 else if (current->expect == EXPECT_OBJECT_VALUE)
3511 current->expect = EXPECT_OBJECT_KEY;
3512 else
3513 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3514
3515 break;
3516 }
3517
3518 case _JSON_BUILD_BOOLEAN: {
3519 bool b;
3520
3521 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3522 r = -EINVAL;
3523 goto finish;
3524 }
3525
3526 b = va_arg(ap, int);
3527
3528 if (current->n_suppress == 0) {
3529 r = json_variant_new_boolean(&add, b);
3530 if (r < 0)
3531 goto finish;
3532 }
3533
3534 n_subtract = 1;
3535
3536 if (current->expect == EXPECT_TOPLEVEL)
3537 current->expect = EXPECT_END;
3538 else if (current->expect == EXPECT_OBJECT_VALUE)
3539 current->expect = EXPECT_OBJECT_KEY;
3540 else
3541 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3542
3543 break;
3544 }
3545
3546 case _JSON_BUILD_NULL:
3547
3548 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3549 r = -EINVAL;
3550 goto finish;
3551 }
3552
3553 if (current->n_suppress == 0) {
3554 r = json_variant_new_null(&add);
3555 if (r < 0)
3556 goto finish;
3557 }
3558
3559 n_subtract = 1;
3560
3561 if (current->expect == EXPECT_TOPLEVEL)
3562 current->expect = EXPECT_END;
3563 else if (current->expect == EXPECT_OBJECT_VALUE)
3564 current->expect = EXPECT_OBJECT_KEY;
3565 else
3566 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3567
3568 break;
3569
3570 case _JSON_BUILD_VARIANT:
3571
3572 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3573 r = -EINVAL;
3574 goto finish;
3575 }
3576
3577 /* Note that we don't care for current->n_suppress here, after all the variant is already
3578 * allocated anyway... */
3579 add = va_arg(ap, JsonVariant*);
3580 if (!add)
3581 add = JSON_VARIANT_MAGIC_NULL;
3582 else
3583 json_variant_ref(add);
3584
3585 n_subtract = 1;
3586
3587 if (current->expect == EXPECT_TOPLEVEL)
3588 current->expect = EXPECT_END;
3589 else if (current->expect == EXPECT_OBJECT_VALUE)
3590 current->expect = EXPECT_OBJECT_KEY;
3591 else
3592 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3593
3594 break;
3595
3596 case _JSON_BUILD_VARIANT_ARRAY: {
3597 JsonVariant **array;
3598 size_t n;
3599
3600 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3601 r = -EINVAL;
3602 goto finish;
3603 }
3604
3605 array = va_arg(ap, JsonVariant**);
3606 n = va_arg(ap, size_t);
3607
3608 if (current->n_suppress == 0) {
3609 r = json_variant_new_array(&add, array, n);
3610 if (r < 0)
3611 goto finish;
3612 }
3613
3614 n_subtract = 1;
3615
3616 if (current->expect == EXPECT_TOPLEVEL)
3617 current->expect = EXPECT_END;
3618 else if (current->expect == EXPECT_OBJECT_VALUE)
3619 current->expect = EXPECT_OBJECT_KEY;
3620 else
3621 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3622
3623 break;
3624 }
3625
3626 case _JSON_BUILD_LITERAL: {
3627 const char *l;
3628
3629 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3630 r = -EINVAL;
3631 goto finish;
3632 }
3633
3634 l = va_arg(ap, const char *);
3635
3636 if (l) {
3637 /* Note that we don't care for current->n_suppress here, we should generate parsing
3638 * errors even in suppressed object properties */
3639
3640 r = json_parse(l, 0, &add, NULL, NULL);
3641 if (r < 0)
3642 goto finish;
3643 } else
3644 add = JSON_VARIANT_MAGIC_NULL;
3645
3646 n_subtract = 1;
3647
3648 if (current->expect == EXPECT_TOPLEVEL)
3649 current->expect = EXPECT_END;
3650 else if (current->expect == EXPECT_OBJECT_VALUE)
3651 current->expect = EXPECT_OBJECT_KEY;
3652 else
3653 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3654
3655 break;
3656 }
3657
3658 case _JSON_BUILD_ARRAY_BEGIN:
3659
3660 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3661 r = -EINVAL;
3662 goto finish;
3663 }
3664
3665 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3666 r = -ENOMEM;
3667 goto finish;
3668 }
3669 current = stack + n_stack - 1;
3670
3671 if (current->expect == EXPECT_TOPLEVEL)
3672 current->expect = EXPECT_END;
3673 else if (current->expect == EXPECT_OBJECT_VALUE)
3674 current->expect = EXPECT_OBJECT_KEY;
3675 else
3676 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3677
3678 stack[n_stack++] = (JsonStack) {
3679 .expect = EXPECT_ARRAY_ELEMENT,
3680 .n_suppress = current->n_suppress != 0 ? SIZE_MAX : 0, /* if we shall suppress the
3681 * new array, then we should
3682 * also suppress all array
3683 * members */
3684 };
3685
3686 break;
3687
3688 case _JSON_BUILD_ARRAY_END:
3689 if (current->expect != EXPECT_ARRAY_ELEMENT) {
3690 r = -EINVAL;
3691 goto finish;
3692 }
3693
3694 assert(n_stack > 1);
3695
3696 if (current->n_suppress == 0) {
3697 r = json_variant_new_array(&add, current->elements, current->n_elements);
3698 if (r < 0)
3699 goto finish;
3700 }
3701
3702 n_subtract = 1;
3703
3704 json_stack_release(current);
3705 n_stack--, current--;
3706
3707 break;
3708
3709 case _JSON_BUILD_STRV: {
3710 char **l;
3711
3712 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3713 r = -EINVAL;
3714 goto finish;
3715 }
3716
3717 l = va_arg(ap, char **);
3718
3719 if (current->n_suppress == 0) {
3720 r = json_variant_new_array_strv(&add, l);
3721 if (r < 0)
3722 goto finish;
3723 }
3724
3725 n_subtract = 1;
3726
3727 if (current->expect == EXPECT_TOPLEVEL)
3728 current->expect = EXPECT_END;
3729 else if (current->expect == EXPECT_OBJECT_VALUE)
3730 current->expect = EXPECT_OBJECT_KEY;
3731 else
3732 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3733
3734 break;
3735 }
3736
3737 case _JSON_BUILD_STRV_ENV_PAIR: {
3738 char **l;
3739
3740 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3741 r = -EINVAL;
3742 goto finish;
3743 }
3744
3745 l = va_arg(ap, char **);
3746
3747 _cleanup_strv_free_ char **el = NULL;
3748 STRV_FOREACH_PAIR(x, y, l) {
3749 char *n = NULL;
3750
3751 n = strjoin(*x, "=", *y);
3752 if (!n) {
3753 r = -ENOMEM;
3754 goto finish;
3755 }
3756
3757 r = strv_consume(&el, n);
3758 if (r < 0)
3759 goto finish;
3760 }
3761
3762 if (current->n_suppress == 0) {
3763 r = json_variant_new_array_strv(&add, el);
3764 if (r < 0)
3765 goto finish;
3766 }
3767
3768 n_subtract = 1;
3769
3770 if (current->expect == EXPECT_TOPLEVEL)
3771 current->expect = EXPECT_END;
3772 else if (current->expect == EXPECT_OBJECT_VALUE)
3773 current->expect = EXPECT_OBJECT_KEY;
3774 else
3775 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3776
3777 break;
3778 }
3779
3780 case _JSON_BUILD_BASE64:
3781 case _JSON_BUILD_BASE32HEX:
3782 case _JSON_BUILD_HEX:
3783 case _JSON_BUILD_OCTESCAPE: {
3784 const void *p;
3785 size_t n;
3786
3787 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3788 r = -EINVAL;
3789 goto finish;
3790 }
3791
3792 p = va_arg(ap, const void *);
3793 n = va_arg(ap, size_t);
3794
3795 if (current->n_suppress == 0) {
3796 r = command == _JSON_BUILD_BASE64 ? json_variant_new_base64(&add, p, n) :
3797 command == _JSON_BUILD_BASE32HEX ? json_variant_new_base32hex(&add, p, n) :
3798 command == _JSON_BUILD_HEX ? json_variant_new_hex(&add, p, n) :
3799 json_variant_new_octescape(&add, p, n);
3800 if (r < 0)
3801 goto finish;
3802 }
3803
3804 n_subtract = 1;
3805
3806 if (current->expect == EXPECT_TOPLEVEL)
3807 current->expect = EXPECT_END;
3808 else if (current->expect == EXPECT_OBJECT_VALUE)
3809 current->expect = EXPECT_OBJECT_KEY;
3810 else
3811 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3812
3813 break;
3814 }
3815
3816 case _JSON_BUILD_IOVEC_BASE64:
3817 case _JSON_BUILD_IOVEC_HEX: {
3818 const struct iovec *iov;
3819
3820 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3821 r = -EINVAL;
3822 goto finish;
3823 }
3824
3825 iov = va_arg(ap, const struct iovec*);
3826
3827 if (current->n_suppress == 0) {
3828 if (iov)
3829 r = command == _JSON_BUILD_IOVEC_BASE64 ? json_variant_new_base64(&add, iov->iov_base, iov->iov_len) :
3830 json_variant_new_hex(&add, iov->iov_base, iov->iov_len);
3831 else
3832 r = json_variant_new_string(&add, "");
3833 if (r < 0)
3834 goto finish;
3835 }
3836
3837 n_subtract = 1;
3838
3839 if (current->expect == EXPECT_TOPLEVEL)
3840 current->expect = EXPECT_END;
3841 else if (current->expect == EXPECT_OBJECT_VALUE)
3842 current->expect = EXPECT_OBJECT_KEY;
3843 else
3844 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3845
3846 break;
3847 }
3848
3849 case _JSON_BUILD_ID128:
3850 case _JSON_BUILD_UUID: {
3851 const sd_id128_t *id;
3852
3853 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3854 r = -EINVAL;
3855 goto finish;
3856 }
3857
3858 assert_se(id = va_arg(ap, sd_id128_t*));
3859
3860 if (current->n_suppress == 0) {
3861 r = command == _JSON_BUILD_ID128 ?
3862 json_variant_new_id128(&add, *id) :
3863 json_variant_new_uuid(&add, *id);
3864 if (r < 0)
3865 goto finish;
3866 }
3867
3868 n_subtract = 1;
3869
3870 if (current->expect == EXPECT_TOPLEVEL)
3871 current->expect = EXPECT_END;
3872 else if (current->expect == EXPECT_OBJECT_VALUE)
3873 current->expect = EXPECT_OBJECT_KEY;
3874 else
3875 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3876
3877 break;
3878 }
3879
3880 case _JSON_BUILD_BYTE_ARRAY: {
3881 const void *array;
3882 size_t n;
3883
3884 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3885 r = -EINVAL;
3886 goto finish;
3887 }
3888
3889 array = va_arg(ap, const void*);
3890 n = va_arg(ap, size_t);
3891
3892 if (current->n_suppress == 0) {
3893 r = json_variant_new_array_bytes(&add, array, n);
3894 if (r < 0)
3895 goto finish;
3896 }
3897
3898 n_subtract = 1;
3899
3900 if (current->expect == EXPECT_TOPLEVEL)
3901 current->expect = EXPECT_END;
3902 else if (current->expect == EXPECT_OBJECT_VALUE)
3903 current->expect = EXPECT_OBJECT_KEY;
3904 else
3905 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3906
3907 break;
3908 }
3909
3910 case _JSON_BUILD_HW_ADDR: {
3911 const struct hw_addr_data *hw_addr;
3912
3913 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3914 r = -EINVAL;
3915 goto finish;
3916 }
3917
3918 assert_se(hw_addr = va_arg(ap, struct hw_addr_data*));
3919
3920 if (current->n_suppress == 0) {
3921 r = json_variant_new_array_bytes(&add, hw_addr->bytes, hw_addr->length);
3922 if (r < 0)
3923 goto finish;
3924 }
3925
3926 n_subtract = 1;
3927
3928 if (current->expect == EXPECT_TOPLEVEL)
3929 current->expect = EXPECT_END;
3930 else if (current->expect == EXPECT_OBJECT_VALUE)
3931 current->expect = EXPECT_OBJECT_KEY;
3932 else
3933 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3934
3935 break;
3936 }
3937
3938 case _JSON_BUILD_STRING_SET: {
3939 Set *set;
3940
3941 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3942 r = -EINVAL;
3943 goto finish;
3944 }
3945
3946 set = va_arg(ap, Set*);
3947
3948 if (current->n_suppress == 0) {
3949 _cleanup_free_ char **sorted = NULL;
3950
3951 r = set_dump_sorted(set, (void ***) &sorted, NULL);
3952 if (r < 0)
3953 goto finish;
3954
3955 r = json_variant_new_array_strv(&add, sorted);
3956 if (r < 0)
3957 goto finish;
3958 }
3959
3960 n_subtract = 1;
3961
3962 if (current->expect == EXPECT_TOPLEVEL)
3963 current->expect = EXPECT_END;
3964 else if (current->expect == EXPECT_OBJECT_VALUE)
3965 current->expect = EXPECT_OBJECT_KEY;
3966 else
3967 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3968
3969 break;
3970 }
3971
3972 case _JSON_BUILD_CALLBACK: {
3973 JsonBuildCallback cb;
3974 void *userdata;
3975
3976 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3977 r = -EINVAL;
3978 goto finish;
3979 }
3980
3981 cb = va_arg(ap, JsonBuildCallback);
3982 userdata = va_arg(ap, void *);
3983
3984 if (current->n_suppress == 0) {
3985 if (cb) {
3986 r = cb(&add, name, userdata);
3987 if (r < 0)
3988 goto finish;
3989 }
3990
3991 if (!add)
3992 add = JSON_VARIANT_MAGIC_NULL;
3993
3994 name = NULL;
3995 }
3996
3997 n_subtract = 1;
3998
3999 if (current->expect == EXPECT_TOPLEVEL)
4000 current->expect = EXPECT_END;
4001 else if (current->expect == EXPECT_OBJECT_VALUE)
4002 current->expect = EXPECT_OBJECT_KEY;
4003 else
4004 assert(current->expect == EXPECT_ARRAY_ELEMENT);
4005
4006 break;
4007 }
4008
4009 case _JSON_BUILD_OBJECT_BEGIN:
4010
4011 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
4012 r = -EINVAL;
4013 goto finish;
4014 }
4015
4016 if (!GREEDY_REALLOC(stack, n_stack+1)) {
4017 r = -ENOMEM;
4018 goto finish;
4019 }
4020 current = stack + n_stack - 1;
4021
4022 if (current->expect == EXPECT_TOPLEVEL)
4023 current->expect = EXPECT_END;
4024 else if (current->expect == EXPECT_OBJECT_VALUE)
4025 current->expect = EXPECT_OBJECT_KEY;
4026 else
4027 assert(current->expect == EXPECT_ARRAY_ELEMENT);
4028
4029 stack[n_stack++] = (JsonStack) {
4030 .expect = EXPECT_OBJECT_KEY,
4031 .n_suppress = current->n_suppress != 0 ? SIZE_MAX : 0, /* If we shall suppress the
4032 * new object, then we should
4033 * also suppress all object
4034 * members. */
4035 };
4036
4037 break;
4038
4039 case _JSON_BUILD_OBJECT_END:
4040
4041 if (current->expect != EXPECT_OBJECT_KEY) {
4042 r = -EINVAL;
4043 goto finish;
4044 }
4045
4046 assert(n_stack > 1);
4047
4048 if (current->n_suppress == 0) {
4049 r = json_variant_new_object(&add, current->elements, current->n_elements);
4050 if (r < 0)
4051 goto finish;
4052 }
4053
4054 n_subtract = 1;
4055
4056 json_stack_release(current);
4057 n_stack--, current--;
4058
4059 break;
4060
4061 case _JSON_BUILD_PAIR: {
4062
4063 if (current->expect != EXPECT_OBJECT_KEY) {
4064 r = -EINVAL;
4065 goto finish;
4066 }
4067
4068 name = va_arg(ap, const char *);
4069
4070 if (current->n_suppress == 0) {
4071 r = json_variant_new_string(&add, name);
4072 if (r < 0)
4073 goto finish;
4074 }
4075
4076 n_subtract = 1;
4077
4078 current->expect = EXPECT_OBJECT_VALUE;
4079 break;
4080 }
4081
4082 case _JSON_BUILD_PAIR_CONDITION: {
4083 bool b;
4084
4085 if (current->expect != EXPECT_OBJECT_KEY) {
4086 r = -EINVAL;
4087 goto finish;
4088 }
4089
4090 b = va_arg(ap, int);
4091 name = va_arg(ap, const char *);
4092
4093 if (b && current->n_suppress == 0) {
4094 r = json_variant_new_string(&add, name);
4095 if (r < 0)
4096 goto finish;
4097 }
4098
4099 n_subtract = 1; /* we generated one item */
4100
4101 if (!b && current->n_suppress != SIZE_MAX)
4102 current->n_suppress += 2; /* Suppress this one and the next item */
4103
4104 current->expect = EXPECT_OBJECT_VALUE;
4105 break;
4106 }
4107
4108 case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO: {
4109 const char *n;
4110 uint64_t u;
4111
4112 if (current->expect != EXPECT_OBJECT_KEY) {
4113 r = -EINVAL;
4114 goto finish;
4115 }
4116
4117 n = va_arg(ap, const char *);
4118 u = va_arg(ap, uint64_t);
4119
4120 if (u != 0 && current->n_suppress == 0) {
4121 r = json_variant_new_string(&add, n);
4122 if (r < 0)
4123 goto finish;
4124
4125 r = json_variant_new_unsigned(&add_more, u);
4126 if (r < 0)
4127 goto finish;
4128 }
4129
4130 n_subtract = 2; /* we generated two item */
4131
4132 current->expect = EXPECT_OBJECT_KEY;
4133 break;
4134 }
4135
4136 case _JSON_BUILD_PAIR_FINITE_USEC: {
4137 const char *n;
4138 usec_t u;
4139
4140 if (current->expect != EXPECT_OBJECT_KEY) {
4141 r = -EINVAL;
4142 goto finish;
4143 }
4144
4145 n = va_arg(ap, const char *);
4146 u = va_arg(ap, usec_t);
4147
4148 if (u != USEC_INFINITY && current->n_suppress == 0) {
4149 r = json_variant_new_string(&add, n);
4150 if (r < 0)
4151 goto finish;
4152
4153 r = json_variant_new_unsigned(&add_more, u);
4154 if (r < 0)
4155 goto finish;
4156 }
4157
4158 n_subtract = 2; /* we generated two item */
4159
4160 current->expect = EXPECT_OBJECT_KEY;
4161 break;
4162 }
4163
4164 case _JSON_BUILD_PAIR_STRING_NON_EMPTY: {
4165 const char *n, *s;
4166
4167 if (current->expect != EXPECT_OBJECT_KEY) {
4168 r = -EINVAL;
4169 goto finish;
4170 }
4171
4172 n = va_arg(ap, const char *);
4173 s = va_arg(ap, const char *);
4174
4175 if (!isempty(s) && current->n_suppress == 0) {
4176 r = json_variant_new_string(&add, n);
4177 if (r < 0)
4178 goto finish;
4179
4180 r = json_variant_new_string(&add_more, s);
4181 if (r < 0)
4182 goto finish;
4183 }
4184
4185 n_subtract = 2; /* we generated two item */
4186
4187 current->expect = EXPECT_OBJECT_KEY;
4188 break;
4189 }
4190
4191 case _JSON_BUILD_PAIR_STRV_NON_EMPTY: {
4192 const char *n;
4193 char **l;
4194
4195 if (current->expect != EXPECT_OBJECT_KEY) {
4196 r = -EINVAL;
4197 goto finish;
4198 }
4199
4200 n = va_arg(ap, const char *);
4201 l = va_arg(ap, char **);
4202
4203 if (!strv_isempty(l) && current->n_suppress == 0) {
4204 r = json_variant_new_string(&add, n);
4205 if (r < 0)
4206 goto finish;
4207
4208 r = json_variant_new_array_strv(&add_more, l);
4209 if (r < 0)
4210 goto finish;
4211 }
4212
4213 n_subtract = 2; /* we generated two item */
4214
4215 current->expect = EXPECT_OBJECT_KEY;
4216 break;
4217 }
4218
4219 case _JSON_BUILD_PAIR_VARIANT_NON_NULL: {
4220 JsonVariant *v;
4221 const char *n;
4222
4223 if (current->expect != EXPECT_OBJECT_KEY) {
4224 r = -EINVAL;
4225 goto finish;
4226 }
4227
4228 n = va_arg(ap, const char *);
4229 v = va_arg(ap, JsonVariant *);
4230
4231 if (v && !json_variant_is_null(v) && current->n_suppress == 0) {
4232 r = json_variant_new_string(&add, n);
4233 if (r < 0)
4234 goto finish;
4235
4236 add_more = json_variant_ref(v);
4237 }
4238
4239 n_subtract = 2; /* we generated two item */
4240
4241 current->expect = EXPECT_OBJECT_KEY;
4242 break;
4243 }
4244
4245 case _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL: {
4246 const struct in_addr *a;
4247 const char *n;
4248
4249 if (current->expect != EXPECT_OBJECT_KEY) {
4250 r = -EINVAL;
4251 goto finish;
4252 }
4253
4254 n = va_arg(ap, const char *);
4255 a = va_arg(ap, const struct in_addr *);
4256
4257 if (a && in4_addr_is_set(a) && current->n_suppress == 0) {
4258 r = json_variant_new_string(&add, n);
4259 if (r < 0)
4260 goto finish;
4261
4262 r = json_variant_new_array_bytes(&add_more, a, sizeof(struct in_addr));
4263 if (r < 0)
4264 goto finish;
4265 }
4266
4267 n_subtract = 2; /* we generated two item */
4268
4269 current->expect = EXPECT_OBJECT_KEY;
4270 break;
4271 }
4272
4273 case _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL: {
4274 const struct in6_addr *a;
4275 const char *n;
4276
4277 if (current->expect != EXPECT_OBJECT_KEY) {
4278 r = -EINVAL;
4279 goto finish;
4280 }
4281
4282 n = va_arg(ap, const char *);
4283 a = va_arg(ap, const struct in6_addr *);
4284
4285 if (a && in6_addr_is_set(a) && current->n_suppress == 0) {
4286 r = json_variant_new_string(&add, n);
4287 if (r < 0)
4288 goto finish;
4289
4290 r = json_variant_new_array_bytes(&add_more, a, sizeof(struct in6_addr));
4291 if (r < 0)
4292 goto finish;
4293 }
4294
4295 n_subtract = 2; /* we generated two item */
4296
4297 current->expect = EXPECT_OBJECT_KEY;
4298 break;
4299 }
4300
4301 case _JSON_BUILD_PAIR_IN_ADDR_NON_NULL: {
4302 const union in_addr_union *a;
4303 const char *n;
4304 int f;
4305
4306 if (current->expect != EXPECT_OBJECT_KEY) {
4307 r = -EINVAL;
4308 goto finish;
4309 }
4310
4311 n = va_arg(ap, const char *);
4312 a = va_arg(ap, const union in_addr_union *);
4313 f = va_arg(ap, int);
4314
4315 if (a && in_addr_is_set(f, a) && current->n_suppress == 0) {
4316 r = json_variant_new_string(&add, n);
4317 if (r < 0)
4318 goto finish;
4319
4320 r = json_variant_new_array_bytes(&add_more, a->bytes, FAMILY_ADDRESS_SIZE(f));
4321 if (r < 0)
4322 goto finish;
4323 }
4324
4325 n_subtract = 2; /* we generated two item */
4326
4327 current->expect = EXPECT_OBJECT_KEY;
4328 break;
4329 }
4330
4331 case _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL: {
4332 const struct ether_addr *a;
4333 const char *n;
4334
4335 if (current->expect != EXPECT_OBJECT_KEY) {
4336 r = -EINVAL;
4337 goto finish;
4338 }
4339
4340 n = va_arg(ap, const char *);
4341 a = va_arg(ap, const struct ether_addr *);
4342
4343 if (a && !ether_addr_is_null(a) && current->n_suppress == 0) {
4344 r = json_variant_new_string(&add, n);
4345 if (r < 0)
4346 goto finish;
4347
4348 r = json_variant_new_array_bytes(&add_more, a->ether_addr_octet, sizeof(struct ether_addr));
4349 if (r < 0)
4350 goto finish;
4351 }
4352
4353 n_subtract = 2; /* we generated two item */
4354
4355 current->expect = EXPECT_OBJECT_KEY;
4356 break;
4357 }
4358
4359 case _JSON_BUILD_PAIR_HW_ADDR_NON_NULL: {
4360 const struct hw_addr_data *a;
4361 const char *n;
4362
4363 if (current->expect != EXPECT_OBJECT_KEY) {
4364 r = -EINVAL;
4365 goto finish;
4366 }
4367
4368 n = va_arg(ap, const char *);
4369 a = va_arg(ap, const struct hw_addr_data *);
4370
4371 if (a && !hw_addr_is_null(a) && current->n_suppress == 0) {
4372 r = json_variant_new_string(&add, n);
4373 if (r < 0)
4374 goto finish;
4375
4376 r = json_variant_new_array_bytes(&add_more, a->bytes, a->length);
4377 if (r < 0)
4378 goto finish;
4379 }
4380
4381 n_subtract = 2; /* we generated two item */
4382
4383 current->expect = EXPECT_OBJECT_KEY;
4384 break;
4385 }
4386 }
4387
4388 /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */
4389 if (add && current->n_suppress == 0) {
4390 if (!GREEDY_REALLOC(current->elements, current->n_elements + 1 + !!add_more)) {
4391 r = -ENOMEM;
4392 goto finish;
4393 }
4394
4395 current->elements[current->n_elements++] = TAKE_PTR(add);
4396 if (add_more)
4397 current->elements[current->n_elements++] = TAKE_PTR(add_more);
4398 }
4399
4400 /* If we are supposed to suppress items, let's subtract how many items where generated from
4401 * that counter. Except if the counter is SIZE_MAX, i.e. we shall suppress an infinite number
4402 * of elements on this stack level */
4403 if (current->n_suppress != SIZE_MAX) {
4404 if (current->n_suppress <= n_subtract) /* Saturated */
4405 current->n_suppress = 0;
4406 else
4407 current->n_suppress -= n_subtract;
4408 }
4409 }
4410
4411 done:
4412 assert(n_stack == 1);
4413 assert(stack[0].n_elements == 1);
4414
4415 *ret = json_variant_ref(stack[0].elements[0]);
4416 r = 0;
4417
4418 finish:
4419 for (size_t i = 0; i < n_stack; i++)
4420 json_stack_release(stack + i);
4421
4422 free(stack);
4423
4424 return r;
4425 }
4426
4427 int json_build(JsonVariant **ret, ...) {
4428 va_list ap;
4429 int r;
4430
4431 va_start(ap, ret);
4432 r = json_buildv(ret, ap);
4433 va_end(ap);
4434
4435 return r;
4436 }
4437
4438 int json_log_internal(
4439 JsonVariant *variant,
4440 int level,
4441 int error,
4442 const char *file,
4443 int line,
4444 const char *func,
4445 const char *format, ...) {
4446
4447 PROTECT_ERRNO;
4448
4449 unsigned source_line, source_column;
4450 char buffer[LINE_MAX];
4451 const char *source;
4452 va_list ap;
4453 int r;
4454
4455 errno = ERRNO_VALUE(error);
4456
4457 va_start(ap, format);
4458 (void) vsnprintf(buffer, sizeof buffer, format, ap);
4459 va_end(ap);
4460
4461 if (variant) {
4462 r = json_variant_get_source(variant, &source, &source_line, &source_column);
4463 if (r < 0)
4464 return r;
4465 } else {
4466 source = NULL;
4467 source_line = 0;
4468 source_column = 0;
4469 }
4470
4471 if (source && source_line > 0 && source_column > 0)
4472 return log_struct_internal(
4473 level,
4474 error,
4475 file, line, func,
4476 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
4477 "CONFIG_FILE=%s", source,
4478 "CONFIG_LINE=%u", source_line,
4479 "CONFIG_COLUMN=%u", source_column,
4480 LOG_MESSAGE("%s:%u:%u: %s", source, source_line, source_column, buffer),
4481 NULL);
4482 else if (source_line > 0 && source_column > 0)
4483 return log_struct_internal(
4484 level,
4485 error,
4486 file, line, func,
4487 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
4488 "CONFIG_LINE=%u", source_line,
4489 "CONFIG_COLUMN=%u", source_column,
4490 LOG_MESSAGE("(string):%u:%u: %s", source_line, source_column, buffer),
4491 NULL);
4492 else
4493 return log_struct_internal(
4494 level,
4495 error,
4496 file, line, func,
4497 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
4498 LOG_MESSAGE("%s", buffer),
4499 NULL);
4500 }
4501
4502 static void *dispatch_userdata(const JsonDispatch *p, void *userdata) {
4503
4504 /* When the userdata pointer is passed in as NULL, then we'll just use the offset as a literal
4505 * address, and convert it to a pointer. Note that might as well just add the offset to the NULL
4506 * pointer, but UndefinedBehaviourSanitizer doesn't like pointer arithmetics based on NULL pointers,
4507 * hence we code this explicitly here. */
4508
4509 if (userdata)
4510 return (uint8_t*) userdata + p->offset;
4511
4512 return SIZE_TO_PTR(p->offset);
4513 }
4514
4515 int json_dispatch_full(
4516 JsonVariant *v,
4517 const JsonDispatch table[],
4518 JsonDispatchCallback bad,
4519 JsonDispatchFlags flags,
4520 void *userdata,
4521 const char **reterr_bad_field) {
4522 size_t m;
4523 int r, done = 0;
4524 bool *found;
4525
4526 if (!json_variant_is_object(v)) {
4527 json_log(v, flags, 0, "JSON variant is not an object.");
4528
4529 if (flags & JSON_PERMISSIVE)
4530 return 0;
4531
4532 if (reterr_bad_field)
4533 *reterr_bad_field = NULL;
4534
4535 return -EINVAL;
4536 }
4537
4538 m = 0;
4539 for (const JsonDispatch *p = table; p->name; p++)
4540 m++;
4541
4542 found = newa0(bool, m);
4543
4544 size_t n = json_variant_elements(v);
4545 for (size_t i = 0; i < n; i += 2) {
4546 JsonVariant *key, *value;
4547 const JsonDispatch *p;
4548
4549 assert_se(key = json_variant_by_index(v, i));
4550 assert_se(value = json_variant_by_index(v, i+1));
4551
4552 for (p = table; p->name; p++)
4553 if (p->name == POINTER_MAX ||
4554 streq_ptr(json_variant_string(key), p->name))
4555 break;
4556
4557 if (p->name) { /* Found a matching entry! 🙂 */
4558 JsonDispatchFlags merged_flags;
4559
4560 merged_flags = flags | p->flags;
4561
4562 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
4563 !json_variant_has_type(value, p->type)) {
4564
4565 json_log(value, merged_flags, 0,
4566 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
4567 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
4568
4569 if (merged_flags & JSON_PERMISSIVE)
4570 continue;
4571
4572 if (reterr_bad_field)
4573 *reterr_bad_field = p->name;
4574
4575 return -EINVAL;
4576 }
4577
4578 if (found[p-table]) {
4579 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
4580
4581 if (merged_flags & JSON_PERMISSIVE)
4582 continue;
4583
4584 if (reterr_bad_field)
4585 *reterr_bad_field = p->name;
4586
4587 return -ENOTUNIQ;
4588 }
4589
4590 found[p-table] = true;
4591
4592 if (p->callback) {
4593 r = p->callback(json_variant_string(key), value, merged_flags, dispatch_userdata(p, userdata));
4594 if (r < 0) {
4595 if (merged_flags & JSON_PERMISSIVE)
4596 continue;
4597
4598 if (reterr_bad_field)
4599 *reterr_bad_field = json_variant_string(key);
4600
4601 return r;
4602 }
4603 }
4604
4605 done++;
4606
4607 } else { /* Didn't find a matching entry! ☹️ */
4608
4609 if (bad) {
4610 r = bad(json_variant_string(key), value, flags, userdata);
4611 if (r < 0) {
4612 if (flags & JSON_PERMISSIVE)
4613 continue;
4614
4615 if (reterr_bad_field)
4616 *reterr_bad_field = json_variant_string(key);
4617
4618 return r;
4619 } else
4620 done++;
4621
4622 } else {
4623 if (flags & JSON_ALLOW_EXTENSIONS) {
4624 json_log(value, flags, 0, "Unrecognized object field '%s', assuming extension.", json_variant_string(key));
4625 continue;
4626 }
4627
4628 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
4629 if (flags & JSON_PERMISSIVE)
4630 continue;
4631
4632 if (reterr_bad_field)
4633 *reterr_bad_field = json_variant_string(key);
4634
4635 return -EADDRNOTAVAIL;
4636 }
4637 }
4638 }
4639
4640 for (const JsonDispatch *p = table; p->name; p++) {
4641 JsonDispatchFlags merged_flags = p->flags | flags;
4642
4643 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
4644 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
4645
4646 if ((merged_flags & JSON_PERMISSIVE))
4647 continue;
4648
4649 if (reterr_bad_field)
4650 *reterr_bad_field = p->name;
4651
4652 return -ENXIO;
4653 }
4654 }
4655
4656 return done;
4657 }
4658
4659 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4660 bool *b = ASSERT_PTR(userdata);
4661
4662 assert(variant);
4663
4664 if (!json_variant_is_boolean(variant))
4665 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name));
4666
4667 *b = json_variant_boolean(variant);
4668 return 0;
4669 }
4670
4671 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4672 int *b = ASSERT_PTR(userdata);
4673
4674 assert(variant);
4675
4676 if (json_variant_is_null(variant)) {
4677 *b = -1;
4678 return 0;
4679 }
4680
4681 if (!json_variant_is_boolean(variant))
4682 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name));
4683
4684 *b = json_variant_boolean(variant);
4685 return 0;
4686 }
4687
4688 int json_dispatch_int64(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4689 int64_t *i = ASSERT_PTR(userdata);
4690
4691 assert(variant);
4692
4693 /* Also accept numbers formatted as string, to increase compatibility with less capable JSON
4694 * implementations that cannot do 64bit integers. */
4695 if (json_variant_is_string(variant) && safe_atoi64(json_variant_string(variant), i) >= 0)
4696 return 0;
4697
4698 if (!json_variant_is_integer(variant))
4699 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer, nor one formatted as decimal string.", strna(name));
4700
4701 *i = json_variant_integer(variant);
4702 return 0;
4703 }
4704
4705 int json_dispatch_uint64(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4706 uint64_t *u = ASSERT_PTR(userdata);
4707
4708 assert(variant);
4709
4710 /* Since 64bit values (in particular unsigned ones) in JSON are problematic, let's also accept them
4711 * formatted as strings. If this is not desired make sure to set the .type field in JsonDispatch to
4712 * JSON_UNSIGNED rather than _JSON_VARIANT_TYPE_INVALID, so that json_dispatch() already filters out
4713 * the non-matching type. */
4714
4715 if (json_variant_is_string(variant) && safe_atou64(json_variant_string(variant), u) >= 0)
4716 return 0;
4717
4718 if (!json_variant_is_unsigned(variant))
4719 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer, nor one formatted as decimal string.", strna(name));
4720
4721 *u = json_variant_unsigned(variant);
4722 return 0;
4723 }
4724
4725 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4726 uint32_t *u = ASSERT_PTR(userdata);
4727 uint64_t u64;
4728 int r;
4729
4730 assert(variant);
4731
4732 r = json_dispatch_uint64(name, variant, flags, &u64);
4733 if (r < 0)
4734 return r;
4735
4736 if (u64 > UINT32_MAX)
4737 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4738
4739 *u = (uint32_t) u64;
4740 return 0;
4741 }
4742
4743 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4744 int32_t *i = ASSERT_PTR(userdata);
4745 int64_t i64;
4746 int r;
4747
4748 assert(variant);
4749
4750 r = json_dispatch_int64(name, variant, flags, &i64);
4751 if (r < 0)
4752 return r;
4753
4754 if (i64 < INT32_MIN || i64 > INT32_MAX)
4755 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4756
4757 *i = (int32_t) i64;
4758 return 0;
4759 }
4760
4761 int json_dispatch_int16(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4762 int16_t *i = ASSERT_PTR(userdata);
4763 int64_t i64;
4764 int r;
4765
4766 assert(variant);
4767
4768 r = json_dispatch_int64(name, variant, flags, &i64);
4769 if (r < 0)
4770 return r;
4771
4772 if (i64 < INT16_MIN || i64 > INT16_MAX)
4773 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4774
4775 *i = (int16_t) i64;
4776 return 0;
4777 }
4778
4779 int json_dispatch_uint16(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4780 uint16_t *u = ASSERT_PTR(userdata);
4781 uint64_t u64;
4782 int r;
4783
4784 assert(variant);
4785
4786 r = json_dispatch_uint64(name, variant, flags, &u64);
4787 if (r < 0)
4788 return r;
4789
4790 if (u64 > UINT16_MAX)
4791 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4792
4793 *u = (uint16_t) u64;
4794 return 0;
4795 }
4796
4797 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4798 char **s = ASSERT_PTR(userdata);
4799 int r;
4800
4801 assert(variant);
4802
4803 if (json_variant_is_null(variant)) {
4804 *s = mfree(*s);
4805 return 0;
4806 }
4807
4808 if (!json_variant_is_string(variant))
4809 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4810
4811 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
4812 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4813
4814 r = free_and_strdup(s, json_variant_string(variant));
4815 if (r < 0)
4816 return json_log(variant, flags, r, "Failed to allocate string: %m");
4817
4818 return 0;
4819 }
4820
4821 int json_dispatch_const_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4822 const char **s = ASSERT_PTR(userdata);
4823
4824 assert(variant);
4825
4826 if (json_variant_is_null(variant)) {
4827 *s = NULL;
4828 return 0;
4829 }
4830
4831 if (!json_variant_is_string(variant))
4832 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4833
4834 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
4835 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4836
4837 *s = json_variant_string(variant);
4838 return 0;
4839 }
4840
4841 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4842 _cleanup_strv_free_ char **l = NULL;
4843 char ***s = ASSERT_PTR(userdata);
4844 JsonVariant *e;
4845 int r;
4846
4847 assert(variant);
4848
4849 if (json_variant_is_null(variant)) {
4850 *s = strv_free(*s);
4851 return 0;
4852 }
4853
4854 /* Let's be flexible here: accept a single string in place of a single-item array */
4855 if (json_variant_is_string(variant)) {
4856 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
4857 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4858
4859 l = strv_new(json_variant_string(variant));
4860 if (!l)
4861 return log_oom();
4862
4863 strv_free_and_replace(*s, l);
4864 return 0;
4865 }
4866
4867 if (!json_variant_is_array(variant))
4868 return json_log(variant, SYNTHETIC_ERRNO(EINVAL), flags, "JSON field '%s' is not an array.", strna(name));
4869
4870 JSON_VARIANT_ARRAY_FOREACH(e, variant) {
4871 if (!json_variant_is_string(e))
4872 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON array element is not a string.");
4873
4874 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(e)))
4875 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4876
4877 r = strv_extend(&l, json_variant_string(e));
4878 if (r < 0)
4879 return json_log(e, flags, r, "Failed to append array element: %m");
4880 }
4881
4882 strv_free_and_replace(*s, l);
4883 return 0;
4884 }
4885
4886 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4887 JsonVariant **p = ASSERT_PTR(userdata);
4888 assert(variant);
4889
4890 /* Takes a reference */
4891 JSON_VARIANT_REPLACE(*p, json_variant_ref(variant));
4892 return 0;
4893 }
4894
4895 int json_dispatch_variant_noref(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4896 JsonVariant **p = ASSERT_PTR(userdata);
4897 assert(variant);
4898
4899 /* Doesn't take a reference */
4900 *p = variant;
4901 return 0;
4902 }
4903
4904 int json_dispatch_uid_gid(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4905 uid_t *uid = userdata;
4906 uint64_t k;
4907
4908 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
4909 assert_cc(sizeof(gid_t) == sizeof(uint32_t));
4910
4911 DISABLE_WARNING_TYPE_LIMITS;
4912 assert_cc((UID_INVALID < (uid_t) 0) == (GID_INVALID < (gid_t) 0));
4913 REENABLE_WARNING;
4914
4915 if (json_variant_is_null(variant)) {
4916 *uid = UID_INVALID;
4917 return 0;
4918 }
4919
4920 if (!json_variant_is_unsigned(variant))
4921 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
4922
4923 k = json_variant_unsigned(variant);
4924 if (k > UINT32_MAX || !uid_is_valid(k))
4925 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid UID/GID.", strna(name));
4926
4927 *uid = k;
4928 return 0;
4929 }
4930
4931 int json_dispatch_user_group_name(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4932 char **s = userdata;
4933 const char *n;
4934 int r;
4935
4936 if (json_variant_is_null(variant)) {
4937 *s = mfree(*s);
4938 return 0;
4939 }
4940
4941 if (!json_variant_is_string(variant))
4942 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4943
4944 n = json_variant_string(variant);
4945 if (!valid_user_group_name(n, FLAGS_SET(flags, JSON_RELAX) ? VALID_USER_RELAX : 0))
4946 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid user/group name.", strna(name));
4947
4948 r = free_and_strdup(s, n);
4949 if (r < 0)
4950 return json_log(variant, flags, r, "Failed to allocate string: %m");
4951
4952 return 0;
4953 }
4954
4955 int json_dispatch_id128(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4956 sd_id128_t *uuid = userdata;
4957 int r;
4958
4959 if (json_variant_is_null(variant)) {
4960 *uuid = SD_ID128_NULL;
4961 return 0;
4962 }
4963
4964 if (!json_variant_is_string(variant))
4965 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4966
4967 r = sd_id128_from_string(json_variant_string(variant), uuid);
4968 if (r < 0)
4969 return json_log(variant, flags, r, "JSON field '%s' is not a valid UID.", strna(name));
4970
4971 return 0;
4972 }
4973
4974 int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4975 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not allowed in this object.", strna(name));
4976 }
4977
4978 int json_dispatch_unbase64_iovec(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4979 _cleanup_free_ void *buffer = NULL;
4980 struct iovec *iov = ASSERT_PTR(userdata);
4981 size_t sz;
4982 int r;
4983
4984 if (!json_variant_is_string(variant))
4985 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4986
4987 r = json_variant_unbase64(variant, &buffer, &sz);
4988 if (r < 0)
4989 return json_log(variant, flags, r, "JSON field '%s' is not valid Base64 data.", strna(name));
4990
4991 free_and_replace(iov->iov_base, buffer);
4992 iov->iov_len = sz;
4993 return 0;
4994 }
4995
4996 static int json_cmp_strings(const void *x, const void *y) {
4997 JsonVariant *const *a = x, *const *b = y;
4998
4999 if (!json_variant_is_string(*a) || !json_variant_is_string(*b))
5000 return CMP(*a, *b);
5001
5002 return strcmp(json_variant_string(*a), json_variant_string(*b));
5003 }
5004
5005 int json_variant_sort(JsonVariant **v) {
5006 _cleanup_free_ JsonVariant **a = NULL;
5007 _cleanup_(json_variant_unrefp) JsonVariant *n = NULL;
5008 size_t m;
5009 int r;
5010
5011 assert(v);
5012
5013 if (json_variant_is_sorted(*v))
5014 return 0;
5015
5016 if (!json_variant_is_object(*v))
5017 return -EMEDIUMTYPE;
5018
5019 /* Sorts they key/value pairs in an object variant */
5020
5021 m = json_variant_elements(*v);
5022 a = new(JsonVariant*, m);
5023 if (!a)
5024 return -ENOMEM;
5025
5026 for (size_t i = 0; i < m; i++)
5027 a[i] = json_variant_by_index(*v, i);
5028
5029 qsort(a, m/2, sizeof(JsonVariant*)*2, json_cmp_strings);
5030
5031 r = json_variant_new_object(&n, a, m);
5032 if (r < 0)
5033 return r;
5034
5035 json_variant_propagate_sensitive(*v, n);
5036
5037 if (!n->sorted) /* Check if this worked. This will fail if there are multiple identical keys used. */
5038 return -ENOTUNIQ;
5039
5040 JSON_VARIANT_REPLACE(*v, TAKE_PTR(n));
5041
5042 return 1;
5043 }
5044
5045 int json_variant_normalize(JsonVariant **v) {
5046 _cleanup_free_ JsonVariant **a = NULL;
5047 _cleanup_(json_variant_unrefp) JsonVariant *n = NULL;
5048 size_t i, m;
5049 int r;
5050
5051 assert(v);
5052
5053 if (json_variant_is_normalized(*v))
5054 return 0;
5055
5056 if (!json_variant_is_object(*v) && !json_variant_is_array(*v))
5057 return -EMEDIUMTYPE;
5058
5059 /* Sorts the key/value pairs in an object variant anywhere down the tree in the specified variant */
5060
5061 m = json_variant_elements(*v);
5062 a = new(JsonVariant*, m);
5063 if (!a)
5064 return -ENOMEM;
5065
5066 for (i = 0; i < m; ) {
5067 a[i] = json_variant_ref(json_variant_by_index(*v, i));
5068 i++;
5069
5070 r = json_variant_normalize(&a[i-1]);
5071 if (r < 0)
5072 goto finish;
5073 }
5074
5075 qsort(a, m/2, sizeof(JsonVariant*)*2, json_cmp_strings);
5076
5077 if (json_variant_is_object(*v))
5078 r = json_variant_new_object(&n, a, m);
5079 else {
5080 assert(json_variant_is_array(*v));
5081 r = json_variant_new_array(&n, a, m);
5082 }
5083 if (r < 0)
5084 goto finish;
5085
5086 json_variant_propagate_sensitive(*v, n);
5087
5088 if (!n->normalized) { /* Let's see if normalization worked. It will fail if there are multiple
5089 * identical keys used in the same object anywhere, or if there are floating
5090 * point numbers used (see below) */
5091 r = -ENOTUNIQ;
5092 goto finish;
5093 }
5094
5095 JSON_VARIANT_REPLACE(*v, TAKE_PTR(n));
5096
5097 r = 1;
5098
5099 finish:
5100 for (size_t j = 0; j < i; j++)
5101 json_variant_unref(a[j]);
5102
5103 return r;
5104 }
5105
5106 bool json_variant_is_normalized(JsonVariant *v) {
5107 /* For now, let's consider anything containing numbers not expressible as integers as non-normalized.
5108 * That's because we cannot sensibly compare them due to accuracy issues, nor even store them if they
5109 * are too large. */
5110 if (json_variant_is_real(v) && !json_variant_is_integer(v) && !json_variant_is_unsigned(v))
5111 return false;
5112
5113 /* The concept only applies to variants that include other variants, i.e. objects and arrays. All
5114 * others are normalized anyway. */
5115 if (!json_variant_is_object(v) && !json_variant_is_array(v))
5116 return true;
5117
5118 /* Empty objects/arrays don't include any other variant, hence are always normalized too */
5119 if (json_variant_elements(v) == 0)
5120 return true;
5121
5122 return v->normalized; /* For everything else there's an explicit boolean we maintain */
5123 }
5124
5125 bool json_variant_is_sorted(JsonVariant *v) {
5126
5127 /* Returns true if all key/value pairs of an object are properly sorted. Note that this only applies
5128 * to objects, not arrays. */
5129
5130 if (!json_variant_is_object(v))
5131 return true;
5132 if (json_variant_elements(v) <= 1)
5133 return true;
5134
5135 return v->sorted;
5136 }
5137
5138 int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size) {
5139 if (!json_variant_is_string(v))
5140 return -EINVAL;
5141
5142 return unbase64mem(json_variant_string(v), ret, ret_size);
5143 }
5144
5145 int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size) {
5146 if (!json_variant_is_string(v))
5147 return -EINVAL;
5148
5149 return unhexmem(json_variant_string(v), ret, ret_size);
5150 }
5151
5152 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
5153 [JSON_VARIANT_STRING] = "string",
5154 [JSON_VARIANT_INTEGER] = "integer",
5155 [JSON_VARIANT_UNSIGNED] = "unsigned",
5156 [JSON_VARIANT_REAL] = "real",
5157 [JSON_VARIANT_NUMBER] = "number",
5158 [JSON_VARIANT_BOOLEAN] = "boolean",
5159 [JSON_VARIANT_ARRAY] = "array",
5160 [JSON_VARIANT_OBJECT] = "object",
5161 [JSON_VARIANT_NULL] = "null",
5162 };
5163
5164 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);