]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/json.c
db3581dfd4afc9ccd4f978baeabcc3aa97bdc0c6
[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 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
1775 _cleanup_(memstream_done) MemStream m = {};
1776 size_t sz;
1777 FILE *f;
1778 int r;
1779
1780 /* Returns the length of the generated string (without the terminating NUL),
1781 * or negative on error. */
1782
1783 assert_return(v, -EINVAL);
1784 assert_return(ret, -EINVAL);
1785
1786 if (flags & JSON_FORMAT_OFF)
1787 return -ENOEXEC;
1788
1789 f = memstream_init(&m);
1790 if (!f)
1791 return -ENOMEM;
1792
1793 r = json_variant_dump(v, flags, f, NULL);
1794 if (r < 0)
1795 return r;
1796
1797 r = memstream_finalize(&m, ret, &sz);
1798 if (r < 0)
1799 return r;
1800
1801 return sz;
1802 }
1803
1804 int json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) {
1805 if (!v) {
1806 if (flags & JSON_FORMAT_EMPTY_ARRAY)
1807 v = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
1808 else
1809 return 0;
1810 }
1811
1812 if (!f)
1813 f = stdout;
1814
1815 print_source(f, v, flags, false);
1816
1817 if (((flags & (JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_COLOR)) == JSON_FORMAT_COLOR_AUTO) && colors_enabled())
1818 flags |= JSON_FORMAT_COLOR;
1819
1820 if (((flags & (JSON_FORMAT_PRETTY_AUTO|JSON_FORMAT_PRETTY)) == JSON_FORMAT_PRETTY_AUTO))
1821 flags |= on_tty() ? JSON_FORMAT_PRETTY : JSON_FORMAT_NEWLINE;
1822
1823 if (flags & JSON_FORMAT_SSE)
1824 fputs("data: ", f);
1825 if (flags & JSON_FORMAT_SEQ)
1826 fputc('\x1e', f); /* ASCII Record Separator */
1827
1828 json_format(f, v, flags, prefix);
1829
1830 if (flags & (JSON_FORMAT_PRETTY|JSON_FORMAT_SEQ|JSON_FORMAT_SSE|JSON_FORMAT_NEWLINE))
1831 fputc('\n', f);
1832 if (flags & JSON_FORMAT_SSE)
1833 fputc('\n', f); /* In case of SSE add a second newline */
1834
1835 if (flags & JSON_FORMAT_FLUSH)
1836 return fflush_and_check(f);
1837 return 0;
1838 }
1839
1840 int json_variant_filter(JsonVariant **v, char **to_remove) {
1841 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1842 _cleanup_free_ JsonVariant **array = NULL;
1843 size_t n = 0, k = 0;
1844 int r;
1845
1846 assert(v);
1847
1848 if (json_variant_is_blank_object(*v))
1849 return 0;
1850 if (!json_variant_is_object(*v))
1851 return -EINVAL;
1852
1853 if (strv_isempty(to_remove))
1854 return 0;
1855
1856 for (size_t i = 0; i < json_variant_elements(*v); i += 2) {
1857 JsonVariant *p;
1858
1859 p = json_variant_by_index(*v, i);
1860 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1861 return -EINVAL;
1862
1863 if (strv_contains(to_remove, json_variant_string(p))) {
1864 if (!array) {
1865 array = new(JsonVariant*, json_variant_elements(*v) - 2);
1866 if (!array)
1867 return -ENOMEM;
1868
1869 for (k = 0; k < i; k++)
1870 array[k] = json_variant_by_index(*v, k);
1871 }
1872
1873 n++;
1874 } else if (array) {
1875 array[k++] = p;
1876 array[k++] = json_variant_by_index(*v, i + 1);
1877 }
1878 }
1879
1880 if (n == 0)
1881 return 0;
1882
1883 r = json_variant_new_object(&w, array, k);
1884 if (r < 0)
1885 return r;
1886
1887 json_variant_propagate_sensitive(*v, w);
1888 JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
1889
1890 return (int) n;
1891 }
1892
1893 int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value) {
1894 _cleanup_(json_variant_unrefp) JsonVariant *field_variant = NULL, *w = NULL;
1895 _cleanup_free_ JsonVariant **array = NULL;
1896 size_t k = 0;
1897 int r;
1898
1899 assert(v);
1900 assert(field);
1901
1902 if (json_variant_is_blank_object(*v)) {
1903 array = new(JsonVariant*, 2);
1904 if (!array)
1905 return -ENOMEM;
1906
1907 } else {
1908 if (!json_variant_is_object(*v))
1909 return -EINVAL;
1910
1911 for (size_t i = 0; i < json_variant_elements(*v); i += 2) {
1912 JsonVariant *p;
1913
1914 p = json_variant_by_index(*v, i);
1915 if (!json_variant_is_string(p))
1916 return -EINVAL;
1917
1918 if (streq(json_variant_string(p), field)) {
1919
1920 if (!array) {
1921 array = new(JsonVariant*, json_variant_elements(*v));
1922 if (!array)
1923 return -ENOMEM;
1924
1925 for (k = 0; k < i; k++)
1926 array[k] = json_variant_by_index(*v, k);
1927 }
1928
1929 } else if (array) {
1930 array[k++] = p;
1931 array[k++] = json_variant_by_index(*v, i + 1);
1932 }
1933 }
1934
1935 if (!array) {
1936 array = new(JsonVariant*, json_variant_elements(*v) + 2);
1937 if (!array)
1938 return -ENOMEM;
1939
1940 for (k = 0; k < json_variant_elements(*v); k++)
1941 array[k] = json_variant_by_index(*v, k);
1942 }
1943 }
1944
1945 r = json_variant_new_string(&field_variant, field);
1946 if (r < 0)
1947 return r;
1948
1949 array[k++] = field_variant;
1950 array[k++] = value;
1951
1952 r = json_variant_new_object(&w, array, k);
1953 if (r < 0)
1954 return r;
1955
1956 json_variant_propagate_sensitive(*v, w);
1957 JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
1958
1959 return 1;
1960 }
1961
1962 int json_variant_set_fieldb(JsonVariant **v, const char *field, ...) {
1963 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1964 va_list ap;
1965 int r;
1966
1967 va_start(ap, field);
1968 r = json_buildv(&w, ap);
1969 va_end(ap);
1970 if (r < 0)
1971 return r;
1972
1973 return json_variant_set_field(v, field, w);
1974 }
1975
1976 int json_variant_set_field_string(JsonVariant **v, const char *field, const char *value) {
1977 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
1978 int r;
1979
1980 r = json_variant_new_string(&m, value);
1981 if (r < 0)
1982 return r;
1983
1984 return json_variant_set_field(v, field, m);
1985 }
1986
1987 int json_variant_set_field_integer(JsonVariant **v, const char *field, int64_t i) {
1988 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
1989 int r;
1990
1991 r = json_variant_new_integer(&m, i);
1992 if (r < 0)
1993 return r;
1994
1995 return json_variant_set_field(v, field, m);
1996 }
1997
1998 int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uint64_t u) {
1999 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2000 int r;
2001
2002 r = json_variant_new_unsigned(&m, u);
2003 if (r < 0)
2004 return r;
2005
2006 return json_variant_set_field(v, field, m);
2007 }
2008
2009 int json_variant_set_field_boolean(JsonVariant **v, const char *field, bool b) {
2010 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2011 int r;
2012
2013 r = json_variant_new_boolean(&m, b);
2014 if (r < 0)
2015 return r;
2016
2017 return json_variant_set_field(v, field, m);
2018 }
2019
2020 int json_variant_set_field_strv(JsonVariant **v, const char *field, char **l) {
2021 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
2022 int r;
2023
2024 r = json_variant_new_array_strv(&m, l);
2025 if (r < 0)
2026 return r;
2027
2028 return json_variant_set_field(v, field, m);
2029 }
2030
2031 int json_variant_merge_object(JsonVariant **v, JsonVariant *m) {
2032 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
2033 _cleanup_free_ JsonVariant **array = NULL;
2034 size_t v_elements, m_elements, k;
2035 bool v_blank, m_blank;
2036 int r;
2037
2038 m = json_variant_dereference(m);
2039
2040 v_blank = json_variant_is_blank_object(*v);
2041 m_blank = json_variant_is_blank_object(m);
2042
2043 if (!v_blank && !json_variant_is_object(*v))
2044 return -EINVAL;
2045 if (!m_blank && !json_variant_is_object(m))
2046 return -EINVAL;
2047
2048 if (m_blank)
2049 return 0; /* nothing to do */
2050
2051 if (v_blank) {
2052 JSON_VARIANT_REPLACE(*v, json_variant_ref(m));
2053 return 1;
2054 }
2055
2056 v_elements = json_variant_elements(*v);
2057 m_elements = json_variant_elements(m);
2058 if (v_elements > SIZE_MAX - m_elements) /* overflow check */
2059 return -ENOMEM;
2060
2061 array = new(JsonVariant*, v_elements + m_elements);
2062 if (!array)
2063 return -ENOMEM;
2064
2065 k = 0;
2066 for (size_t i = 0; i < v_elements; i += 2) {
2067 JsonVariant *u;
2068
2069 u = json_variant_by_index(*v, i);
2070 if (!json_variant_is_string(u))
2071 return -EINVAL;
2072
2073 if (json_variant_by_key(m, json_variant_string(u)))
2074 continue; /* skip if exists in second variant */
2075
2076 array[k++] = u;
2077 array[k++] = json_variant_by_index(*v, i + 1);
2078 }
2079
2080 for (size_t i = 0; i < m_elements; i++)
2081 array[k++] = json_variant_by_index(m, i);
2082
2083 r = json_variant_new_object(&w, array, k);
2084 if (r < 0)
2085 return r;
2086
2087 json_variant_propagate_sensitive(*v, w);
2088 json_variant_propagate_sensitive(m, w);
2089 JSON_VARIANT_REPLACE(*v, TAKE_PTR(w));
2090
2091 return 1;
2092 }
2093
2094 int json_variant_merge_objectb(JsonVariant **v, ...) {
2095 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
2096 va_list ap;
2097 int r;
2098
2099 va_start(ap, v);
2100 r = json_buildv(&w, ap);
2101 va_end(ap);
2102 if (r < 0)
2103 return r;
2104
2105 return json_variant_merge_object(v, w);
2106 }
2107
2108 int json_variant_append_array(JsonVariant **v, JsonVariant *element) {
2109 _cleanup_(json_variant_unrefp) JsonVariant *nv = NULL;
2110 bool blank;
2111 int r;
2112
2113 assert(v);
2114 assert(element);
2115
2116 if (!*v || json_variant_is_null(*v))
2117 blank = true;
2118 else if (json_variant_is_array(*v))
2119 blank = json_variant_elements(*v) == 0;
2120 else
2121 return -EINVAL;
2122
2123 if (blank) {
2124 r = json_variant_new_array(&nv, (JsonVariant*[]) { element }, 1);
2125 if (r < 0)
2126 return r;
2127 } else if (json_variant_n_ref(*v) == 1) {
2128 /* Let's bump the reference count on element. We can't do the realloc if we're appending *v
2129 * to itself, or one of the objects embedded in *v to *v. If the reference count grows, we
2130 * need to fall back to the other method below. */
2131
2132 _unused_ _cleanup_(json_variant_unrefp) JsonVariant *dummy = json_variant_ref(element);
2133 if (json_variant_n_ref(*v) == 1) {
2134 /* We hold the only reference. Let's mutate the object. */
2135 size_t size = json_variant_elements(*v);
2136 void *old = *v;
2137
2138 if (!GREEDY_REALLOC(*v, size + 1 + 1))
2139 return -ENOMEM;
2140
2141 if (old != *v)
2142 /* Readjust the parent pointers to the new address */
2143 for (size_t i = 1; i < size; i++)
2144 (*v)[1 + i].parent = *v;
2145
2146 return _json_variant_array_put_element(*v, element);
2147 }
2148 }
2149
2150 if (!blank) {
2151 size_t size = json_variant_elements(*v);
2152
2153 _cleanup_free_ JsonVariant **array = new(JsonVariant*, size + 1);
2154 if (!array)
2155 return -ENOMEM;
2156
2157 for (size_t i = 0; i < size; i++)
2158 array[i] = json_variant_by_index(*v, i);
2159
2160 array[size] = element;
2161
2162 r = json_variant_new_array(&nv, array, size + 1);
2163 if (r < 0)
2164 return r;
2165 }
2166
2167 json_variant_propagate_sensitive(*v, nv);
2168 JSON_VARIANT_REPLACE(*v, TAKE_PTR(nv));
2169
2170 return 0;
2171 }
2172
2173 int json_variant_append_arrayb(JsonVariant **v, ...) {
2174 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
2175 va_list ap;
2176 int r;
2177
2178 va_start(ap, v);
2179 r = json_buildv(&w, ap);
2180 va_end(ap);
2181 if (r < 0)
2182 return r;
2183
2184 return json_variant_append_array(v, w);
2185 }
2186
2187 JsonVariant *json_variant_find(JsonVariant *haystack, JsonVariant *needle) {
2188 JsonVariant *i;
2189
2190 /* Find a json object in an array. Returns NULL if not found, or if the array is not actually an array. */
2191
2192 JSON_VARIANT_ARRAY_FOREACH(i, haystack)
2193 if (json_variant_equal(i, needle))
2194 return i;
2195
2196 return NULL;
2197 }
2198
2199 int json_variant_append_array_nodup(JsonVariant **v, JsonVariant *element) {
2200 assert(v);
2201
2202 if (json_variant_find(*v, element))
2203 return 0;
2204
2205 return json_variant_append_array(v, element);
2206 }
2207
2208 int json_variant_strv(JsonVariant *v, char ***ret) {
2209 char **l = NULL;
2210 bool sensitive;
2211 int r;
2212
2213 assert(ret);
2214
2215 if (!v || json_variant_is_null(v)) {
2216 l = new0(char*, 1);
2217 if (!l)
2218 return -ENOMEM;
2219
2220 *ret = l;
2221 return 0;
2222 }
2223
2224 if (!json_variant_is_array(v))
2225 return -EINVAL;
2226
2227 sensitive = json_variant_is_sensitive(v);
2228
2229 size_t n = json_variant_elements(v);
2230 l = new(char*, n+1);
2231 if (!l)
2232 return -ENOMEM;
2233
2234 for (size_t i = 0; i < n; i++) {
2235 JsonVariant *e;
2236
2237 assert_se(e = json_variant_by_index(v, i));
2238 sensitive = sensitive || json_variant_is_sensitive(e);
2239
2240 if (!json_variant_is_string(e)) {
2241 l[i] = NULL;
2242 r = -EINVAL;
2243 goto fail;
2244 }
2245
2246 l[i] = strdup(json_variant_string(e));
2247 if (!l[i]) {
2248 r = -ENOMEM;
2249 goto fail;
2250 }
2251 }
2252
2253 l[n] = NULL;
2254 *ret = TAKE_PTR(l);
2255
2256 return 0;
2257
2258 fail:
2259 if (sensitive)
2260 strv_free_erase(l);
2261 else
2262 strv_free(l);
2263
2264 return r;
2265 }
2266
2267 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
2268 JsonVariantType t;
2269 JsonVariant *c;
2270 JsonValue value;
2271 const void *source;
2272 size_t k;
2273
2274 assert(nv);
2275 assert(v);
2276
2277 /* Let's copy the simple types literally, and the larger types by references */
2278 t = json_variant_type(v);
2279 switch (t) {
2280 case JSON_VARIANT_INTEGER:
2281 k = sizeof(int64_t);
2282 value.integer = json_variant_integer(v);
2283 source = &value;
2284 break;
2285
2286 case JSON_VARIANT_UNSIGNED:
2287 k = sizeof(uint64_t);
2288 value.unsig = json_variant_unsigned(v);
2289 source = &value;
2290 break;
2291
2292 case JSON_VARIANT_REAL:
2293 k = sizeof(double);
2294 value.real = json_variant_real(v);
2295 source = &value;
2296 break;
2297
2298 case JSON_VARIANT_BOOLEAN:
2299 k = sizeof(bool);
2300 value.boolean = json_variant_boolean(v);
2301 source = &value;
2302 break;
2303
2304 case JSON_VARIANT_NULL:
2305 k = 0;
2306 source = NULL;
2307 break;
2308
2309 case JSON_VARIANT_STRING:
2310 source = json_variant_string(v);
2311 k = strnlen(source, INLINE_STRING_MAX + 1);
2312 if (k <= INLINE_STRING_MAX) {
2313 k ++;
2314 break;
2315 }
2316
2317 _fallthrough_;
2318
2319 default:
2320 /* Everything else copy by reference */
2321
2322 c = malloc0(MAX(sizeof(JsonVariant),
2323 offsetof(JsonVariant, reference) + sizeof(JsonVariant*)));
2324 if (!c)
2325 return -ENOMEM;
2326
2327 c->n_ref = 1;
2328 c->type = t;
2329 c->is_reference = true;
2330 c->reference = json_variant_ref(json_variant_formalize(v));
2331
2332 *nv = c;
2333 return 0;
2334 }
2335
2336 c = malloc0(MAX(sizeof(JsonVariant),
2337 offsetof(JsonVariant, value) + k));
2338 if (!c)
2339 return -ENOMEM;
2340
2341 c->n_ref = 1;
2342 c->type = t;
2343
2344 memcpy_safe(&c->value, source, k);
2345
2346 json_variant_propagate_sensitive(v, c);
2347
2348 *nv = c;
2349 return 0;
2350 }
2351
2352 static bool json_single_ref(JsonVariant *v) {
2353
2354 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
2355
2356 if (!json_variant_is_regular(v))
2357 return false;
2358
2359 if (v->is_embedded)
2360 return json_single_ref(v->parent);
2361
2362 assert(v->n_ref > 0);
2363 return v->n_ref == 1;
2364 }
2365
2366 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
2367 JsonVariant *w;
2368 int r;
2369
2370 assert(v);
2371
2372 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole
2373 * referencer of the object. If not, allocates a new object, possibly a surrogate for the original
2374 * one */
2375
2376 if (!*v)
2377 return 0;
2378
2379 if (source && line > source->max_line)
2380 source->max_line = line;
2381 if (source && column > source->max_column)
2382 source->max_column = column;
2383
2384 if (!json_variant_is_regular(*v)) {
2385
2386 if (!source && line == 0 && column == 0)
2387 return 0;
2388
2389 } else {
2390 if (json_source_equal((*v)->source, source) &&
2391 (*v)->line == line &&
2392 (*v)->column == column)
2393 return 0;
2394
2395 if (json_single_ref(*v)) { /* Sole reference? */
2396 json_source_unref((*v)->source);
2397 (*v)->source = json_source_ref(source);
2398 (*v)->line = line;
2399 (*v)->column = column;
2400 return 1;
2401 }
2402 }
2403
2404 r = json_variant_copy(&w, *v);
2405 if (r < 0)
2406 return r;
2407
2408 assert(json_variant_is_regular(w));
2409 assert(!w->is_embedded);
2410 assert(w->n_ref == 1);
2411 assert(!w->source);
2412
2413 w->source = json_source_ref(source);
2414 w->line = line;
2415 w->column = column;
2416
2417 JSON_VARIANT_REPLACE(*v, w);
2418
2419 return 1;
2420 }
2421
2422 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
2423 assert(line);
2424 assert(column);
2425 assert(s || n == 0);
2426
2427 while (n > 0) {
2428 if (*s == '\n') {
2429 (*line)++;
2430 *column = 1;
2431 } else if ((signed char) *s >= 0 && *s < 127) /* Process ASCII chars quickly */
2432 (*column)++;
2433 else {
2434 int w;
2435
2436 w = utf8_encoded_valid_unichar(s, n);
2437 if (w < 0) /* count invalid unichars as normal characters */
2438 w = 1;
2439 else if ((size_t) w > n) /* never read more than the specified number of characters */
2440 w = (int) n;
2441
2442 (*column)++;
2443
2444 s += w;
2445 n -= w;
2446 continue;
2447 }
2448
2449 s++;
2450 n--;
2451 }
2452 }
2453
2454 static int unhex_ucs2(const char *c, uint16_t *ret) {
2455 int aa, bb, cc, dd;
2456 uint16_t x;
2457
2458 assert(c);
2459 assert(ret);
2460
2461 aa = unhexchar(c[0]);
2462 if (aa < 0)
2463 return -EINVAL;
2464
2465 bb = unhexchar(c[1]);
2466 if (bb < 0)
2467 return -EINVAL;
2468
2469 cc = unhexchar(c[2]);
2470 if (cc < 0)
2471 return -EINVAL;
2472
2473 dd = unhexchar(c[3]);
2474 if (dd < 0)
2475 return -EINVAL;
2476
2477 x = ((uint16_t) aa << 12) |
2478 ((uint16_t) bb << 8) |
2479 ((uint16_t) cc << 4) |
2480 ((uint16_t) dd);
2481
2482 if (x <= 0)
2483 return -EINVAL;
2484
2485 *ret = x;
2486
2487 return 0;
2488 }
2489
2490 static int json_parse_string(const char **p, char **ret) {
2491 _cleanup_free_ char *s = NULL;
2492 size_t n = 0;
2493 const char *c;
2494
2495 assert(p);
2496 assert(*p);
2497 assert(ret);
2498
2499 c = *p;
2500
2501 if (*c != '"')
2502 return -EINVAL;
2503
2504 c++;
2505
2506 for (;;) {
2507 int len;
2508
2509 /* Check for EOF */
2510 if (*c == 0)
2511 return -EINVAL;
2512
2513 /* Check for control characters 0x00..0x1f */
2514 if (*c > 0 && *c < ' ')
2515 return -EINVAL;
2516
2517 /* Check for control character 0x7f */
2518 if (*c == 0x7f)
2519 return -EINVAL;
2520
2521 if (*c == '"') {
2522 if (!s) {
2523 s = strdup("");
2524 if (!s)
2525 return -ENOMEM;
2526 } else
2527 s[n] = 0;
2528
2529 *p = c + 1;
2530
2531 *ret = TAKE_PTR(s);
2532 return JSON_TOKEN_STRING;
2533 }
2534
2535 if (*c == '\\') {
2536 char ch = 0;
2537 c++;
2538
2539 if (*c == 0)
2540 return -EINVAL;
2541
2542 if (IN_SET(*c, '"', '\\', '/'))
2543 ch = *c;
2544 else if (*c == 'b')
2545 ch = '\b';
2546 else if (*c == 'f')
2547 ch = '\f';
2548 else if (*c == 'n')
2549 ch = '\n';
2550 else if (*c == 'r')
2551 ch = '\r';
2552 else if (*c == 't')
2553 ch = '\t';
2554 else if (*c == 'u') {
2555 char16_t x;
2556 int r;
2557
2558 r = unhex_ucs2(c + 1, &x);
2559 if (r < 0)
2560 return r;
2561
2562 c += 5;
2563
2564 if (!GREEDY_REALLOC(s, n + 5))
2565 return -ENOMEM;
2566
2567 if (!utf16_is_surrogate(x))
2568 n += utf8_encode_unichar(s + n, (char32_t) x);
2569 else if (utf16_is_trailing_surrogate(x))
2570 return -EINVAL;
2571 else {
2572 char16_t y;
2573
2574 if (c[0] != '\\' || c[1] != 'u')
2575 return -EINVAL;
2576
2577 r = unhex_ucs2(c + 2, &y);
2578 if (r < 0)
2579 return r;
2580
2581 c += 6;
2582
2583 if (!utf16_is_trailing_surrogate(y))
2584 return -EINVAL;
2585
2586 n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
2587 }
2588
2589 continue;
2590 } else
2591 return -EINVAL;
2592
2593 if (!GREEDY_REALLOC(s, n + 2))
2594 return -ENOMEM;
2595
2596 s[n++] = ch;
2597 c ++;
2598 continue;
2599 }
2600
2601 len = utf8_encoded_valid_unichar(c, SIZE_MAX);
2602 if (len < 0)
2603 return len;
2604
2605 if (!GREEDY_REALLOC(s, n + len + 1))
2606 return -ENOMEM;
2607
2608 memcpy(s + n, c, len);
2609 n += len;
2610 c += len;
2611 }
2612 }
2613
2614 static int json_parse_number(const char **p, JsonValue *ret) {
2615 bool negative = false, exponent_negative = false, is_real = false;
2616 double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
2617 int64_t i = 0;
2618 uint64_t u = 0;
2619 const char *c;
2620
2621 assert(p);
2622 assert(*p);
2623 assert(ret);
2624
2625 c = *p;
2626
2627 if (*c == '-') {
2628 negative = true;
2629 c++;
2630 }
2631
2632 if (*c == '0')
2633 c++;
2634 else {
2635 if (!strchr("123456789", *c) || *c == 0)
2636 return -EINVAL;
2637
2638 do {
2639 if (!is_real) {
2640 if (negative) {
2641
2642 if (i < INT64_MIN / 10) /* overflow */
2643 is_real = true;
2644 else {
2645 int64_t t = 10 * i;
2646
2647 if (t < INT64_MIN + (*c - '0')) /* overflow */
2648 is_real = true;
2649 else
2650 i = t - (*c - '0');
2651 }
2652 } else {
2653 if (u > UINT64_MAX / 10) /* overflow */
2654 is_real = true;
2655 else {
2656 uint64_t t = 10 * u;
2657
2658 if (t > UINT64_MAX - (*c - '0')) /* overflow */
2659 is_real = true;
2660 else
2661 u = t + (*c - '0');
2662 }
2663 }
2664 }
2665
2666 x = 10.0 * x + (*c - '0');
2667
2668 c++;
2669 } while (strchr("0123456789", *c) && *c != 0);
2670 }
2671
2672 if (*c == '.') {
2673 is_real = true;
2674 c++;
2675
2676 if (!strchr("0123456789", *c) || *c == 0)
2677 return -EINVAL;
2678
2679 do {
2680 y = 10.0 * y + (*c - '0');
2681 shift = 10.0 * shift;
2682 c++;
2683 } while (strchr("0123456789", *c) && *c != 0);
2684 }
2685
2686 if (IN_SET(*c, 'e', 'E')) {
2687 is_real = true;
2688 c++;
2689
2690 if (*c == '-') {
2691 exponent_negative = true;
2692 c++;
2693 } else if (*c == '+')
2694 c++;
2695
2696 if (!strchr("0123456789", *c) || *c == 0)
2697 return -EINVAL;
2698
2699 do {
2700 exponent = 10.0 * exponent + (*c - '0');
2701 c++;
2702 } while (strchr("0123456789", *c) && *c != 0);
2703 }
2704
2705 *p = c;
2706
2707 if (is_real) {
2708 ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10((exponent_negative ? -1.0 : 1.0) * exponent);
2709 return JSON_TOKEN_REAL;
2710 } else if (negative) {
2711 ret->integer = i;
2712 return JSON_TOKEN_INTEGER;
2713 } else {
2714 ret->unsig = u;
2715 return JSON_TOKEN_UNSIGNED;
2716 }
2717 }
2718
2719 int json_tokenize(
2720 const char **p,
2721 char **ret_string,
2722 JsonValue *ret_value,
2723 unsigned *ret_line, /* 'ret_line' returns the line at the beginning of this token */
2724 unsigned *ret_column,
2725 void **state,
2726 unsigned *line, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2727 unsigned *column) {
2728
2729 unsigned start_line, start_column;
2730 const char *start, *c;
2731 size_t n;
2732 int t, r;
2733
2734 enum {
2735 STATE_NULL,
2736 STATE_VALUE,
2737 STATE_VALUE_POST,
2738 };
2739
2740 assert(p);
2741 assert(*p);
2742 assert(ret_string);
2743 assert(ret_value);
2744 assert(ret_line);
2745 assert(ret_column);
2746 assert(line);
2747 assert(column);
2748 assert(state);
2749
2750 t = PTR_TO_INT(*state);
2751 if (t == STATE_NULL) {
2752 *line = 1;
2753 *column = 1;
2754 t = STATE_VALUE;
2755 }
2756
2757 /* Skip over the whitespace */
2758 n = strspn(*p, WHITESPACE);
2759 inc_lines_columns(line, column, *p, n);
2760 c = *p + n;
2761
2762 /* Remember where we started processing this token */
2763 start = c;
2764 start_line = *line;
2765 start_column = *column;
2766
2767 if (*c == 0) {
2768 *ret_string = NULL;
2769 *ret_value = JSON_VALUE_NULL;
2770 r = JSON_TOKEN_END;
2771 goto finish;
2772 }
2773
2774 switch (t) {
2775
2776 case STATE_VALUE:
2777
2778 if (*c == '{') {
2779 c++;
2780 *state = INT_TO_PTR(STATE_VALUE);
2781 r = JSON_TOKEN_OBJECT_OPEN;
2782 goto null_return;
2783
2784 } else if (*c == '}') {
2785 c++;
2786 *state = INT_TO_PTR(STATE_VALUE_POST);
2787 r = JSON_TOKEN_OBJECT_CLOSE;
2788 goto null_return;
2789
2790 } else if (*c == '[') {
2791 c++;
2792 *state = INT_TO_PTR(STATE_VALUE);
2793 r = JSON_TOKEN_ARRAY_OPEN;
2794 goto null_return;
2795
2796 } else if (*c == ']') {
2797 c++;
2798 *state = INT_TO_PTR(STATE_VALUE_POST);
2799 r = JSON_TOKEN_ARRAY_CLOSE;
2800 goto null_return;
2801
2802 } else if (*c == '"') {
2803
2804 r = json_parse_string(&c, ret_string);
2805 if (r < 0)
2806 return r;
2807
2808 *ret_value = JSON_VALUE_NULL;
2809 *state = INT_TO_PTR(STATE_VALUE_POST);
2810 goto finish;
2811
2812 } else if (strchr("-0123456789", *c)) {
2813
2814 r = json_parse_number(&c, ret_value);
2815 if (r < 0)
2816 return r;
2817
2818 *ret_string = NULL;
2819 *state = INT_TO_PTR(STATE_VALUE_POST);
2820 goto finish;
2821
2822 } else if (startswith(c, "true")) {
2823 *ret_string = NULL;
2824 ret_value->boolean = true;
2825 c += 4;
2826 *state = INT_TO_PTR(STATE_VALUE_POST);
2827 r = JSON_TOKEN_BOOLEAN;
2828 goto finish;
2829
2830 } else if (startswith(c, "false")) {
2831 *ret_string = NULL;
2832 ret_value->boolean = false;
2833 c += 5;
2834 *state = INT_TO_PTR(STATE_VALUE_POST);
2835 r = JSON_TOKEN_BOOLEAN;
2836 goto finish;
2837
2838 } else if (startswith(c, "null")) {
2839 *ret_string = NULL;
2840 *ret_value = JSON_VALUE_NULL;
2841 c += 4;
2842 *state = INT_TO_PTR(STATE_VALUE_POST);
2843 r = JSON_TOKEN_NULL;
2844 goto finish;
2845
2846 }
2847
2848 return -EINVAL;
2849
2850 case STATE_VALUE_POST:
2851
2852 if (*c == ':') {
2853 c++;
2854 *state = INT_TO_PTR(STATE_VALUE);
2855 r = JSON_TOKEN_COLON;
2856 goto null_return;
2857
2858 } else if (*c == ',') {
2859 c++;
2860 *state = INT_TO_PTR(STATE_VALUE);
2861 r = JSON_TOKEN_COMMA;
2862 goto null_return;
2863
2864 } else if (*c == '}') {
2865 c++;
2866 *state = INT_TO_PTR(STATE_VALUE_POST);
2867 r = JSON_TOKEN_OBJECT_CLOSE;
2868 goto null_return;
2869
2870 } else if (*c == ']') {
2871 c++;
2872 *state = INT_TO_PTR(STATE_VALUE_POST);
2873 r = JSON_TOKEN_ARRAY_CLOSE;
2874 goto null_return;
2875 }
2876
2877 return -EINVAL;
2878
2879 default:
2880 assert_not_reached();
2881 }
2882
2883 null_return:
2884 *ret_string = NULL;
2885 *ret_value = JSON_VALUE_NULL;
2886
2887 finish:
2888 inc_lines_columns(line, column, start, c - start);
2889 *p = c;
2890
2891 *ret_line = start_line;
2892 *ret_column = start_column;
2893
2894 return r;
2895 }
2896
2897 typedef enum JsonExpect {
2898 /* The following values are used by json_parse() */
2899 EXPECT_TOPLEVEL,
2900 EXPECT_END,
2901 EXPECT_OBJECT_FIRST_KEY,
2902 EXPECT_OBJECT_NEXT_KEY,
2903 EXPECT_OBJECT_COLON,
2904 EXPECT_OBJECT_VALUE,
2905 EXPECT_OBJECT_COMMA,
2906 EXPECT_ARRAY_FIRST_ELEMENT,
2907 EXPECT_ARRAY_NEXT_ELEMENT,
2908 EXPECT_ARRAY_COMMA,
2909
2910 /* And these are used by json_build() */
2911 EXPECT_ARRAY_ELEMENT,
2912 EXPECT_OBJECT_KEY,
2913 } JsonExpect;
2914
2915 typedef struct JsonStack {
2916 JsonExpect expect;
2917 JsonVariant **elements;
2918 size_t n_elements;
2919 unsigned line_before;
2920 unsigned column_before;
2921 size_t n_suppress; /* When building: if > 0, suppress this many subsequent elements. If == SIZE_MAX, suppress all subsequent elements */
2922 } JsonStack;
2923
2924 static void json_stack_release(JsonStack *s) {
2925 assert(s);
2926
2927 CLEANUP_ARRAY(s->elements, s->n_elements, json_variant_unref_many);
2928 }
2929
2930 static int json_parse_internal(
2931 const char **input,
2932 JsonSource *source,
2933 JsonParseFlags flags,
2934 JsonVariant **ret,
2935 unsigned *line,
2936 unsigned *column,
2937 bool continue_end) {
2938
2939 size_t n_stack = 1;
2940 unsigned line_buffer = 0, column_buffer = 0;
2941 void *tokenizer_state = NULL;
2942 JsonStack *stack = NULL;
2943 const char *p;
2944 int r;
2945
2946 assert_return(input, -EINVAL);
2947 assert_return(ret, -EINVAL);
2948
2949 p = *input;
2950
2951 if (!GREEDY_REALLOC(stack, n_stack))
2952 return -ENOMEM;
2953
2954 stack[0] = (JsonStack) {
2955 .expect = EXPECT_TOPLEVEL,
2956 };
2957
2958 if (!line)
2959 line = &line_buffer;
2960 if (!column)
2961 column = &column_buffer;
2962
2963 for (;;) {
2964 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL;
2965 _cleanup_free_ char *string = NULL;
2966 unsigned line_token, column_token;
2967 JsonStack *current;
2968 JsonValue value;
2969 int token;
2970
2971 assert(n_stack > 0);
2972 current = stack + n_stack - 1;
2973
2974 if (continue_end && current->expect == EXPECT_END)
2975 goto done;
2976
2977 token = json_tokenize(&p, &string, &value, &line_token, &column_token, &tokenizer_state, line, column);
2978 if (token < 0) {
2979 r = token;
2980 goto finish;
2981 }
2982
2983 switch (token) {
2984
2985 case JSON_TOKEN_END:
2986 if (current->expect != EXPECT_END) {
2987 r = -EINVAL;
2988 goto finish;
2989 }
2990
2991 assert(current->n_elements == 1);
2992 assert(n_stack == 1);
2993 goto done;
2994
2995 case JSON_TOKEN_COLON:
2996
2997 if (current->expect != EXPECT_OBJECT_COLON) {
2998 r = -EINVAL;
2999 goto finish;
3000 }
3001
3002 current->expect = EXPECT_OBJECT_VALUE;
3003 break;
3004
3005 case JSON_TOKEN_COMMA:
3006
3007 if (current->expect == EXPECT_OBJECT_COMMA)
3008 current->expect = EXPECT_OBJECT_NEXT_KEY;
3009 else if (current->expect == EXPECT_ARRAY_COMMA)
3010 current->expect = EXPECT_ARRAY_NEXT_ELEMENT;
3011 else {
3012 r = -EINVAL;
3013 goto finish;
3014 }
3015
3016 break;
3017
3018 case JSON_TOKEN_OBJECT_OPEN:
3019
3020 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3021 r = -EINVAL;
3022 goto finish;
3023 }
3024
3025 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3026 r = -ENOMEM;
3027 goto finish;
3028 }
3029 current = stack + n_stack - 1;
3030
3031 /* Prepare the expect for when we return from the child */
3032 if (current->expect == EXPECT_TOPLEVEL)
3033 current->expect = EXPECT_END;
3034 else if (current->expect == EXPECT_OBJECT_VALUE)
3035 current->expect = EXPECT_OBJECT_COMMA;
3036 else {
3037 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3038 current->expect = EXPECT_ARRAY_COMMA;
3039 }
3040
3041 stack[n_stack++] = (JsonStack) {
3042 .expect = EXPECT_OBJECT_FIRST_KEY,
3043 .line_before = line_token,
3044 .column_before = column_token,
3045 };
3046
3047 current = stack + n_stack - 1;
3048 break;
3049
3050 case JSON_TOKEN_OBJECT_CLOSE:
3051 if (!IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_COMMA)) {
3052 r = -EINVAL;
3053 goto finish;
3054 }
3055
3056 assert(n_stack > 1);
3057
3058 r = json_variant_new_object(&add, current->elements, current->n_elements);
3059 if (r < 0)
3060 goto finish;
3061
3062 line_token = current->line_before;
3063 column_token = current->column_before;
3064
3065 json_stack_release(current);
3066 n_stack--, current--;
3067
3068 break;
3069
3070 case JSON_TOKEN_ARRAY_OPEN:
3071 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3072 r = -EINVAL;
3073 goto finish;
3074 }
3075
3076 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3077 r = -ENOMEM;
3078 goto finish;
3079 }
3080 current = stack + n_stack - 1;
3081
3082 /* Prepare the expect for when we return from the child */
3083 if (current->expect == EXPECT_TOPLEVEL)
3084 current->expect = EXPECT_END;
3085 else if (current->expect == EXPECT_OBJECT_VALUE)
3086 current->expect = EXPECT_OBJECT_COMMA;
3087 else {
3088 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3089 current->expect = EXPECT_ARRAY_COMMA;
3090 }
3091
3092 stack[n_stack++] = (JsonStack) {
3093 .expect = EXPECT_ARRAY_FIRST_ELEMENT,
3094 .line_before = line_token,
3095 .column_before = column_token,
3096 };
3097
3098 break;
3099
3100 case JSON_TOKEN_ARRAY_CLOSE:
3101 if (!IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_COMMA)) {
3102 r = -EINVAL;
3103 goto finish;
3104 }
3105
3106 assert(n_stack > 1);
3107
3108 r = json_variant_new_array(&add, current->elements, current->n_elements);
3109 if (r < 0)
3110 goto finish;
3111
3112 line_token = current->line_before;
3113 column_token = current->column_before;
3114
3115 json_stack_release(current);
3116 n_stack--, current--;
3117 break;
3118
3119 case JSON_TOKEN_STRING:
3120 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)) {
3121 r = -EINVAL;
3122 goto finish;
3123 }
3124
3125 r = json_variant_new_string(&add, string);
3126 if (r < 0)
3127 goto finish;
3128
3129 if (current->expect == EXPECT_TOPLEVEL)
3130 current->expect = EXPECT_END;
3131 else if (IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_NEXT_KEY))
3132 current->expect = EXPECT_OBJECT_COLON;
3133 else if (current->expect == EXPECT_OBJECT_VALUE)
3134 current->expect = EXPECT_OBJECT_COMMA;
3135 else {
3136 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3137 current->expect = EXPECT_ARRAY_COMMA;
3138 }
3139
3140 break;
3141
3142 case JSON_TOKEN_REAL:
3143 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3144 r = -EINVAL;
3145 goto finish;
3146 }
3147
3148 r = json_variant_new_real(&add, value.real);
3149 if (r < 0)
3150 goto finish;
3151
3152 if (current->expect == EXPECT_TOPLEVEL)
3153 current->expect = EXPECT_END;
3154 else if (current->expect == EXPECT_OBJECT_VALUE)
3155 current->expect = EXPECT_OBJECT_COMMA;
3156 else {
3157 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3158 current->expect = EXPECT_ARRAY_COMMA;
3159 }
3160
3161 break;
3162
3163 case JSON_TOKEN_INTEGER:
3164 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3165 r = -EINVAL;
3166 goto finish;
3167 }
3168
3169 r = json_variant_new_integer(&add, value.integer);
3170 if (r < 0)
3171 goto finish;
3172
3173 if (current->expect == EXPECT_TOPLEVEL)
3174 current->expect = EXPECT_END;
3175 else if (current->expect == EXPECT_OBJECT_VALUE)
3176 current->expect = EXPECT_OBJECT_COMMA;
3177 else {
3178 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3179 current->expect = EXPECT_ARRAY_COMMA;
3180 }
3181
3182 break;
3183
3184 case JSON_TOKEN_UNSIGNED:
3185 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3186 r = -EINVAL;
3187 goto finish;
3188 }
3189
3190 r = json_variant_new_unsigned(&add, value.unsig);
3191 if (r < 0)
3192 goto finish;
3193
3194 if (current->expect == EXPECT_TOPLEVEL)
3195 current->expect = EXPECT_END;
3196 else if (current->expect == EXPECT_OBJECT_VALUE)
3197 current->expect = EXPECT_OBJECT_COMMA;
3198 else {
3199 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3200 current->expect = EXPECT_ARRAY_COMMA;
3201 }
3202
3203 break;
3204
3205 case JSON_TOKEN_BOOLEAN:
3206 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3207 r = -EINVAL;
3208 goto finish;
3209 }
3210
3211 r = json_variant_new_boolean(&add, value.boolean);
3212 if (r < 0)
3213 goto finish;
3214
3215 if (current->expect == EXPECT_TOPLEVEL)
3216 current->expect = EXPECT_END;
3217 else if (current->expect == EXPECT_OBJECT_VALUE)
3218 current->expect = EXPECT_OBJECT_COMMA;
3219 else {
3220 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3221 current->expect = EXPECT_ARRAY_COMMA;
3222 }
3223
3224 break;
3225
3226 case JSON_TOKEN_NULL:
3227 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3228 r = -EINVAL;
3229 goto finish;
3230 }
3231
3232 r = json_variant_new_null(&add);
3233 if (r < 0)
3234 goto finish;
3235
3236 if (current->expect == EXPECT_TOPLEVEL)
3237 current->expect = EXPECT_END;
3238 else if (current->expect == EXPECT_OBJECT_VALUE)
3239 current->expect = EXPECT_OBJECT_COMMA;
3240 else {
3241 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3242 current->expect = EXPECT_ARRAY_COMMA;
3243 }
3244
3245 break;
3246
3247 default:
3248 assert_not_reached();
3249 }
3250
3251 if (add) {
3252 /* If we are asked to make this parsed object sensitive, then let's apply this
3253 * immediately after allocating each variant, so that when we abort half-way
3254 * everything we already allocated that is then freed is correctly marked. */
3255 if (FLAGS_SET(flags, JSON_PARSE_SENSITIVE))
3256 json_variant_sensitive(add);
3257
3258 (void) json_variant_set_source(&add, source, line_token, column_token);
3259
3260 if (!GREEDY_REALLOC(current->elements, current->n_elements + 1)) {
3261 r = -ENOMEM;
3262 goto finish;
3263 }
3264
3265 current->elements[current->n_elements++] = TAKE_PTR(add);
3266 }
3267 }
3268
3269 done:
3270 assert(n_stack == 1);
3271 assert(stack[0].n_elements == 1);
3272
3273 *ret = json_variant_ref(stack[0].elements[0]);
3274 *input = p;
3275 r = 0;
3276
3277 finish:
3278 for (size_t i = 0; i < n_stack; i++)
3279 json_stack_release(stack + i);
3280
3281 free(stack);
3282
3283 return r;
3284 }
3285
3286 int json_parse_with_source(
3287 const char *input,
3288 const char *source,
3289 JsonParseFlags flags,
3290 JsonVariant **ret,
3291 unsigned *ret_line,
3292 unsigned *ret_column) {
3293
3294 _cleanup_(json_source_unrefp) JsonSource *s = NULL;
3295
3296 if (source) {
3297 s = json_source_new(source);
3298 if (!s)
3299 return -ENOMEM;
3300 }
3301
3302 return json_parse_internal(&input, s, flags, ret, ret_line, ret_column, false);
3303 }
3304
3305 int json_parse_with_source_continue(
3306 const char **p,
3307 const char *source,
3308 JsonParseFlags flags,
3309 JsonVariant **ret,
3310 unsigned *ret_line,
3311 unsigned *ret_column) {
3312
3313 _cleanup_(json_source_unrefp) JsonSource *s = NULL;
3314
3315 if (source) {
3316 s = json_source_new(source);
3317 if (!s)
3318 return -ENOMEM;
3319 }
3320
3321 return json_parse_internal(p, s, flags, ret, ret_line, ret_column, true);
3322 }
3323
3324 int json_parse_file_at(
3325 FILE *f,
3326 int dir_fd,
3327 const char *path,
3328 JsonParseFlags flags,
3329 JsonVariant **ret,
3330 unsigned *ret_line,
3331 unsigned *ret_column) {
3332
3333 _cleanup_free_ char *text = NULL;
3334 int r;
3335
3336 if (f)
3337 r = read_full_stream(f, &text, NULL);
3338 else if (path)
3339 r = read_full_file_full(dir_fd, path, UINT64_MAX, SIZE_MAX, 0, NULL, &text, NULL);
3340 else
3341 return -EINVAL;
3342 if (r < 0)
3343 return r;
3344
3345 if (isempty(text))
3346 return -ENODATA;
3347
3348 return json_parse_with_source(text, path, flags, ret, ret_line, ret_column);
3349 }
3350
3351 int json_buildv(JsonVariant **ret, va_list ap) {
3352 JsonStack *stack = NULL;
3353 size_t n_stack = 1;
3354 int r;
3355
3356 assert_return(ret, -EINVAL);
3357
3358 if (!GREEDY_REALLOC(stack, n_stack))
3359 return -ENOMEM;
3360
3361 stack[0] = (JsonStack) {
3362 .expect = EXPECT_TOPLEVEL,
3363 };
3364
3365 for (;;) {
3366 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL, *add_more = NULL;
3367 size_t n_subtract = 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
3368 * have been added to the current variant */
3369 JsonStack *current;
3370 int command;
3371
3372 assert(n_stack > 0);
3373 current = stack + n_stack - 1;
3374
3375 if (current->expect == EXPECT_END)
3376 goto done;
3377
3378 command = va_arg(ap, int);
3379
3380 switch (command) {
3381
3382 case _JSON_BUILD_STRING: {
3383 const char *p;
3384
3385 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3386 r = -EINVAL;
3387 goto finish;
3388 }
3389
3390 p = va_arg(ap, const char *);
3391
3392 if (current->n_suppress == 0) {
3393 r = json_variant_new_string(&add, p);
3394 if (r < 0)
3395 goto finish;
3396 }
3397
3398 n_subtract = 1;
3399
3400 if (current->expect == EXPECT_TOPLEVEL)
3401 current->expect = EXPECT_END;
3402 else if (current->expect == EXPECT_OBJECT_VALUE)
3403 current->expect = EXPECT_OBJECT_KEY;
3404 else
3405 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3406
3407 break;
3408 }
3409
3410 case _JSON_BUILD_INTEGER: {
3411 int64_t j;
3412
3413 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3414 r = -EINVAL;
3415 goto finish;
3416 }
3417
3418 j = va_arg(ap, int64_t);
3419
3420 if (current->n_suppress == 0) {
3421 r = json_variant_new_integer(&add, j);
3422 if (r < 0)
3423 goto finish;
3424 }
3425
3426 n_subtract = 1;
3427
3428 if (current->expect == EXPECT_TOPLEVEL)
3429 current->expect = EXPECT_END;
3430 else if (current->expect == EXPECT_OBJECT_VALUE)
3431 current->expect = EXPECT_OBJECT_KEY;
3432 else
3433 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3434
3435 break;
3436 }
3437
3438 case _JSON_BUILD_UNSIGNED: {
3439 uint64_t j;
3440
3441 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3442 r = -EINVAL;
3443 goto finish;
3444 }
3445
3446 j = va_arg(ap, uint64_t);
3447
3448 if (current->n_suppress == 0) {
3449 r = json_variant_new_unsigned(&add, j);
3450 if (r < 0)
3451 goto finish;
3452 }
3453
3454 n_subtract = 1;
3455
3456 if (current->expect == EXPECT_TOPLEVEL)
3457 current->expect = EXPECT_END;
3458 else if (current->expect == EXPECT_OBJECT_VALUE)
3459 current->expect = EXPECT_OBJECT_KEY;
3460 else
3461 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3462
3463 break;
3464 }
3465
3466 case _JSON_BUILD_REAL: {
3467 double d;
3468
3469 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3470 r = -EINVAL;
3471 goto finish;
3472 }
3473
3474 d = va_arg(ap, double);
3475
3476 if (current->n_suppress == 0) {
3477 r = json_variant_new_real(&add, d);
3478 if (r < 0)
3479 goto finish;
3480 }
3481
3482 n_subtract = 1;
3483
3484 if (current->expect == EXPECT_TOPLEVEL)
3485 current->expect = EXPECT_END;
3486 else if (current->expect == EXPECT_OBJECT_VALUE)
3487 current->expect = EXPECT_OBJECT_KEY;
3488 else
3489 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3490
3491 break;
3492 }
3493
3494 case _JSON_BUILD_BOOLEAN: {
3495 bool b;
3496
3497 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3498 r = -EINVAL;
3499 goto finish;
3500 }
3501
3502 b = va_arg(ap, int);
3503
3504 if (current->n_suppress == 0) {
3505 r = json_variant_new_boolean(&add, b);
3506 if (r < 0)
3507 goto finish;
3508 }
3509
3510 n_subtract = 1;
3511
3512 if (current->expect == EXPECT_TOPLEVEL)
3513 current->expect = EXPECT_END;
3514 else if (current->expect == EXPECT_OBJECT_VALUE)
3515 current->expect = EXPECT_OBJECT_KEY;
3516 else
3517 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3518
3519 break;
3520 }
3521
3522 case _JSON_BUILD_NULL:
3523
3524 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3525 r = -EINVAL;
3526 goto finish;
3527 }
3528
3529 if (current->n_suppress == 0) {
3530 r = json_variant_new_null(&add);
3531 if (r < 0)
3532 goto finish;
3533 }
3534
3535 n_subtract = 1;
3536
3537 if (current->expect == EXPECT_TOPLEVEL)
3538 current->expect = EXPECT_END;
3539 else if (current->expect == EXPECT_OBJECT_VALUE)
3540 current->expect = EXPECT_OBJECT_KEY;
3541 else
3542 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3543
3544 break;
3545
3546 case _JSON_BUILD_VARIANT:
3547
3548 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3549 r = -EINVAL;
3550 goto finish;
3551 }
3552
3553 /* Note that we don't care for current->n_suppress here, after all the variant is already
3554 * allocated anyway... */
3555 add = va_arg(ap, JsonVariant*);
3556 if (!add)
3557 add = JSON_VARIANT_MAGIC_NULL;
3558 else
3559 json_variant_ref(add);
3560
3561 n_subtract = 1;
3562
3563 if (current->expect == EXPECT_TOPLEVEL)
3564 current->expect = EXPECT_END;
3565 else if (current->expect == EXPECT_OBJECT_VALUE)
3566 current->expect = EXPECT_OBJECT_KEY;
3567 else
3568 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3569
3570 break;
3571
3572 case _JSON_BUILD_VARIANT_ARRAY: {
3573 JsonVariant **array;
3574 size_t n;
3575
3576 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3577 r = -EINVAL;
3578 goto finish;
3579 }
3580
3581 array = va_arg(ap, JsonVariant**);
3582 n = va_arg(ap, size_t);
3583
3584 if (current->n_suppress == 0) {
3585 r = json_variant_new_array(&add, array, n);
3586 if (r < 0)
3587 goto finish;
3588 }
3589
3590 n_subtract = 1;
3591
3592 if (current->expect == EXPECT_TOPLEVEL)
3593 current->expect = EXPECT_END;
3594 else if (current->expect == EXPECT_OBJECT_VALUE)
3595 current->expect = EXPECT_OBJECT_KEY;
3596 else
3597 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3598
3599 break;
3600 }
3601
3602 case _JSON_BUILD_LITERAL: {
3603 const char *l;
3604
3605 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3606 r = -EINVAL;
3607 goto finish;
3608 }
3609
3610 l = va_arg(ap, const char *);
3611
3612 if (l) {
3613 /* Note that we don't care for current->n_suppress here, we should generate parsing
3614 * errors even in suppressed object properties */
3615
3616 r = json_parse(l, 0, &add, NULL, NULL);
3617 if (r < 0)
3618 goto finish;
3619 } else
3620 add = JSON_VARIANT_MAGIC_NULL;
3621
3622 n_subtract = 1;
3623
3624 if (current->expect == EXPECT_TOPLEVEL)
3625 current->expect = EXPECT_END;
3626 else if (current->expect == EXPECT_OBJECT_VALUE)
3627 current->expect = EXPECT_OBJECT_KEY;
3628 else
3629 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3630
3631 break;
3632 }
3633
3634 case _JSON_BUILD_ARRAY_BEGIN:
3635
3636 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3637 r = -EINVAL;
3638 goto finish;
3639 }
3640
3641 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3642 r = -ENOMEM;
3643 goto finish;
3644 }
3645 current = stack + n_stack - 1;
3646
3647 if (current->expect == EXPECT_TOPLEVEL)
3648 current->expect = EXPECT_END;
3649 else if (current->expect == EXPECT_OBJECT_VALUE)
3650 current->expect = EXPECT_OBJECT_KEY;
3651 else
3652 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3653
3654 stack[n_stack++] = (JsonStack) {
3655 .expect = EXPECT_ARRAY_ELEMENT,
3656 .n_suppress = current->n_suppress != 0 ? SIZE_MAX : 0, /* if we shall suppress the
3657 * new array, then we should
3658 * also suppress all array
3659 * members */
3660 };
3661
3662 break;
3663
3664 case _JSON_BUILD_ARRAY_END:
3665 if (current->expect != EXPECT_ARRAY_ELEMENT) {
3666 r = -EINVAL;
3667 goto finish;
3668 }
3669
3670 assert(n_stack > 1);
3671
3672 if (current->n_suppress == 0) {
3673 r = json_variant_new_array(&add, current->elements, current->n_elements);
3674 if (r < 0)
3675 goto finish;
3676 }
3677
3678 n_subtract = 1;
3679
3680 json_stack_release(current);
3681 n_stack--, current--;
3682
3683 break;
3684
3685 case _JSON_BUILD_STRV: {
3686 char **l;
3687
3688 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3689 r = -EINVAL;
3690 goto finish;
3691 }
3692
3693 l = va_arg(ap, char **);
3694
3695 if (current->n_suppress == 0) {
3696 r = json_variant_new_array_strv(&add, l);
3697 if (r < 0)
3698 goto finish;
3699 }
3700
3701 n_subtract = 1;
3702
3703 if (current->expect == EXPECT_TOPLEVEL)
3704 current->expect = EXPECT_END;
3705 else if (current->expect == EXPECT_OBJECT_VALUE)
3706 current->expect = EXPECT_OBJECT_KEY;
3707 else
3708 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3709
3710 break;
3711 }
3712
3713 case _JSON_BUILD_STRV_ENV_PAIR: {
3714 char **l;
3715
3716 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3717 r = -EINVAL;
3718 goto finish;
3719 }
3720
3721 l = va_arg(ap, char **);
3722
3723 _cleanup_strv_free_ char **el = NULL;
3724 STRV_FOREACH_PAIR(x, y, l) {
3725 char *n = NULL;
3726
3727 n = strjoin(*x, "=", *y);
3728 if (!n) {
3729 r = -ENOMEM;
3730 goto finish;
3731 }
3732
3733 r = strv_consume(&el, n);
3734 if (r < 0)
3735 goto finish;
3736 }
3737
3738 if (current->n_suppress == 0) {
3739 r = json_variant_new_array_strv(&add, el);
3740 if (r < 0)
3741 goto finish;
3742 }
3743
3744 n_subtract = 1;
3745
3746 if (current->expect == EXPECT_TOPLEVEL)
3747 current->expect = EXPECT_END;
3748 else if (current->expect == EXPECT_OBJECT_VALUE)
3749 current->expect = EXPECT_OBJECT_KEY;
3750 else
3751 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3752
3753 break;
3754 }
3755
3756 case _JSON_BUILD_BASE64:
3757 case _JSON_BUILD_BASE32HEX:
3758 case _JSON_BUILD_HEX:
3759 case _JSON_BUILD_OCTESCAPE: {
3760 const void *p;
3761 size_t n;
3762
3763 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3764 r = -EINVAL;
3765 goto finish;
3766 }
3767
3768 p = va_arg(ap, const void *);
3769 n = va_arg(ap, size_t);
3770
3771 if (current->n_suppress == 0) {
3772 r = command == _JSON_BUILD_BASE64 ? json_variant_new_base64(&add, p, n) :
3773 command == _JSON_BUILD_BASE32HEX ? json_variant_new_base32hex(&add, p, n) :
3774 command == _JSON_BUILD_HEX ? json_variant_new_hex(&add, p, n) :
3775 json_variant_new_octescape(&add, p, n);
3776 if (r < 0)
3777 goto finish;
3778 }
3779
3780 n_subtract = 1;
3781
3782 if (current->expect == EXPECT_TOPLEVEL)
3783 current->expect = EXPECT_END;
3784 else if (current->expect == EXPECT_OBJECT_VALUE)
3785 current->expect = EXPECT_OBJECT_KEY;
3786 else
3787 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3788
3789 break;
3790 }
3791
3792 case _JSON_BUILD_ID128:
3793 case _JSON_BUILD_UUID: {
3794 const sd_id128_t *id;
3795
3796 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3797 r = -EINVAL;
3798 goto finish;
3799 }
3800
3801 assert_se(id = va_arg(ap, sd_id128_t*));
3802
3803 if (current->n_suppress == 0) {
3804 r = command == _JSON_BUILD_ID128 ?
3805 json_variant_new_id128(&add, *id) :
3806 json_variant_new_uuid(&add, *id);
3807 if (r < 0)
3808 goto finish;
3809 }
3810
3811 n_subtract = 1;
3812
3813 if (current->expect == EXPECT_TOPLEVEL)
3814 current->expect = EXPECT_END;
3815 else if (current->expect == EXPECT_OBJECT_VALUE)
3816 current->expect = EXPECT_OBJECT_KEY;
3817 else
3818 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3819
3820 break;
3821 }
3822
3823 case _JSON_BUILD_BYTE_ARRAY: {
3824 const void *array;
3825 size_t n;
3826
3827 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3828 r = -EINVAL;
3829 goto finish;
3830 }
3831
3832 array = va_arg(ap, const void*);
3833 n = va_arg(ap, size_t);
3834
3835 if (current->n_suppress == 0) {
3836 r = json_variant_new_array_bytes(&add, array, n);
3837 if (r < 0)
3838 goto finish;
3839 }
3840
3841 n_subtract = 1;
3842
3843 if (current->expect == EXPECT_TOPLEVEL)
3844 current->expect = EXPECT_END;
3845 else if (current->expect == EXPECT_OBJECT_VALUE)
3846 current->expect = EXPECT_OBJECT_KEY;
3847 else
3848 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3849
3850 break;
3851 }
3852
3853 case _JSON_BUILD_HW_ADDR: {
3854 const struct hw_addr_data *hw_addr;
3855
3856 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3857 r = -EINVAL;
3858 goto finish;
3859 }
3860
3861 assert_se(hw_addr = va_arg(ap, struct hw_addr_data*));
3862
3863 if (current->n_suppress == 0) {
3864 r = json_variant_new_array_bytes(&add, hw_addr->bytes, hw_addr->length);
3865 if (r < 0)
3866 goto finish;
3867 }
3868
3869 n_subtract = 1;
3870
3871 if (current->expect == EXPECT_TOPLEVEL)
3872 current->expect = EXPECT_END;
3873 else if (current->expect == EXPECT_OBJECT_VALUE)
3874 current->expect = EXPECT_OBJECT_KEY;
3875 else
3876 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3877
3878 break;
3879 }
3880
3881 case _JSON_BUILD_STRING_SET: {
3882 Set *set;
3883
3884 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3885 r = -EINVAL;
3886 goto finish;
3887 }
3888
3889 set = va_arg(ap, Set*);
3890
3891 if (current->n_suppress == 0) {
3892 _cleanup_free_ char **sorted = NULL;
3893
3894 r = set_dump_sorted(set, (void ***) &sorted, NULL);
3895 if (r < 0)
3896 goto finish;
3897
3898 r = json_variant_new_array_strv(&add, sorted);
3899 if (r < 0)
3900 goto finish;
3901 }
3902
3903 n_subtract = 1;
3904
3905 if (current->expect == EXPECT_TOPLEVEL)
3906 current->expect = EXPECT_END;
3907 else if (current->expect == EXPECT_OBJECT_VALUE)
3908 current->expect = EXPECT_OBJECT_KEY;
3909 else
3910 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3911
3912 break;
3913 }
3914
3915 case _JSON_BUILD_OBJECT_BEGIN:
3916
3917 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3918 r = -EINVAL;
3919 goto finish;
3920 }
3921
3922 if (!GREEDY_REALLOC(stack, n_stack+1)) {
3923 r = -ENOMEM;
3924 goto finish;
3925 }
3926 current = stack + n_stack - 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 stack[n_stack++] = (JsonStack) {
3936 .expect = EXPECT_OBJECT_KEY,
3937 .n_suppress = current->n_suppress != 0 ? SIZE_MAX : 0, /* If we shall suppress the
3938 * new object, then we should
3939 * also suppress all object
3940 * members. */
3941 };
3942
3943 break;
3944
3945 case _JSON_BUILD_OBJECT_END:
3946
3947 if (current->expect != EXPECT_OBJECT_KEY) {
3948 r = -EINVAL;
3949 goto finish;
3950 }
3951
3952 assert(n_stack > 1);
3953
3954 if (current->n_suppress == 0) {
3955 r = json_variant_new_object(&add, current->elements, current->n_elements);
3956 if (r < 0)
3957 goto finish;
3958 }
3959
3960 n_subtract = 1;
3961
3962 json_stack_release(current);
3963 n_stack--, current--;
3964
3965 break;
3966
3967 case _JSON_BUILD_PAIR: {
3968 const char *n;
3969
3970 if (current->expect != EXPECT_OBJECT_KEY) {
3971 r = -EINVAL;
3972 goto finish;
3973 }
3974
3975 n = va_arg(ap, const char *);
3976
3977 if (current->n_suppress == 0) {
3978 r = json_variant_new_string(&add, n);
3979 if (r < 0)
3980 goto finish;
3981 }
3982
3983 n_subtract = 1;
3984
3985 current->expect = EXPECT_OBJECT_VALUE;
3986 break;
3987 }
3988
3989 case _JSON_BUILD_PAIR_CONDITION: {
3990 const char *n;
3991 bool b;
3992
3993 if (current->expect != EXPECT_OBJECT_KEY) {
3994 r = -EINVAL;
3995 goto finish;
3996 }
3997
3998 b = va_arg(ap, int);
3999 n = va_arg(ap, const char *);
4000
4001 if (b && current->n_suppress == 0) {
4002 r = json_variant_new_string(&add, n);
4003 if (r < 0)
4004 goto finish;
4005 }
4006
4007 n_subtract = 1; /* we generated one item */
4008
4009 if (!b && current->n_suppress != SIZE_MAX)
4010 current->n_suppress += 2; /* Suppress this one and the next item */
4011
4012 current->expect = EXPECT_OBJECT_VALUE;
4013 break;
4014 }
4015
4016 case _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO: {
4017 const char *n;
4018 uint64_t u;
4019
4020 if (current->expect != EXPECT_OBJECT_KEY) {
4021 r = -EINVAL;
4022 goto finish;
4023 }
4024
4025 n = va_arg(ap, const char *);
4026 u = va_arg(ap, uint64_t);
4027
4028 if (u != 0 && current->n_suppress == 0) {
4029 r = json_variant_new_string(&add, n);
4030 if (r < 0)
4031 goto finish;
4032
4033 r = json_variant_new_unsigned(&add_more, u);
4034 if (r < 0)
4035 goto finish;
4036 }
4037
4038 n_subtract = 2; /* we generated two item */
4039
4040 current->expect = EXPECT_OBJECT_KEY;
4041 break;
4042 }
4043
4044 case _JSON_BUILD_PAIR_FINITE_USEC: {
4045 const char *n;
4046 usec_t u;
4047
4048 if (current->expect != EXPECT_OBJECT_KEY) {
4049 r = -EINVAL;
4050 goto finish;
4051 }
4052
4053 n = va_arg(ap, const char *);
4054 u = va_arg(ap, usec_t);
4055
4056 if (u != USEC_INFINITY && current->n_suppress == 0) {
4057 r = json_variant_new_string(&add, n);
4058 if (r < 0)
4059 goto finish;
4060
4061 r = json_variant_new_unsigned(&add_more, u);
4062 if (r < 0)
4063 goto finish;
4064 }
4065
4066 n_subtract = 2; /* we generated two item */
4067
4068 current->expect = EXPECT_OBJECT_KEY;
4069 break;
4070 }
4071
4072 case _JSON_BUILD_PAIR_STRING_NON_EMPTY: {
4073 const char *n, *s;
4074
4075 if (current->expect != EXPECT_OBJECT_KEY) {
4076 r = -EINVAL;
4077 goto finish;
4078 }
4079
4080 n = va_arg(ap, const char *);
4081 s = va_arg(ap, const char *);
4082
4083 if (!isempty(s) && current->n_suppress == 0) {
4084 r = json_variant_new_string(&add, n);
4085 if (r < 0)
4086 goto finish;
4087
4088 r = json_variant_new_string(&add_more, s);
4089 if (r < 0)
4090 goto finish;
4091 }
4092
4093 n_subtract = 2; /* we generated two item */
4094
4095 current->expect = EXPECT_OBJECT_KEY;
4096 break;
4097 }
4098
4099 case _JSON_BUILD_PAIR_STRV_NON_EMPTY: {
4100 const char *n;
4101 char **l;
4102
4103 if (current->expect != EXPECT_OBJECT_KEY) {
4104 r = -EINVAL;
4105 goto finish;
4106 }
4107
4108 n = va_arg(ap, const char *);
4109 l = va_arg(ap, char **);
4110
4111 if (!strv_isempty(l) && current->n_suppress == 0) {
4112 r = json_variant_new_string(&add, n);
4113 if (r < 0)
4114 goto finish;
4115
4116 r = json_variant_new_array_strv(&add_more, l);
4117 if (r < 0)
4118 goto finish;
4119 }
4120
4121 n_subtract = 2; /* we generated two item */
4122
4123 current->expect = EXPECT_OBJECT_KEY;
4124 break;
4125 }
4126
4127 case _JSON_BUILD_PAIR_VARIANT_NON_NULL: {
4128 JsonVariant *v;
4129 const char *n;
4130
4131 if (current->expect != EXPECT_OBJECT_KEY) {
4132 r = -EINVAL;
4133 goto finish;
4134 }
4135
4136 n = va_arg(ap, const char *);
4137 v = va_arg(ap, JsonVariant *);
4138
4139 if (v && !json_variant_is_null(v) && current->n_suppress == 0) {
4140 r = json_variant_new_string(&add, n);
4141 if (r < 0)
4142 goto finish;
4143
4144 add_more = json_variant_ref(v);
4145 }
4146
4147 n_subtract = 2; /* we generated two item */
4148
4149 current->expect = EXPECT_OBJECT_KEY;
4150 break;
4151 }
4152
4153 case _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL: {
4154 const struct in_addr *a;
4155 const char *n;
4156
4157 if (current->expect != EXPECT_OBJECT_KEY) {
4158 r = -EINVAL;
4159 goto finish;
4160 }
4161
4162 n = va_arg(ap, const char *);
4163 a = va_arg(ap, const struct in_addr *);
4164
4165 if (a && in4_addr_is_set(a) && current->n_suppress == 0) {
4166 r = json_variant_new_string(&add, n);
4167 if (r < 0)
4168 goto finish;
4169
4170 r = json_variant_new_array_bytes(&add_more, a, sizeof(struct in_addr));
4171 if (r < 0)
4172 goto finish;
4173 }
4174
4175 n_subtract = 2; /* we generated two item */
4176
4177 current->expect = EXPECT_OBJECT_KEY;
4178 break;
4179 }
4180
4181 case _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL: {
4182 const struct in6_addr *a;
4183 const char *n;
4184
4185 if (current->expect != EXPECT_OBJECT_KEY) {
4186 r = -EINVAL;
4187 goto finish;
4188 }
4189
4190 n = va_arg(ap, const char *);
4191 a = va_arg(ap, const struct in6_addr *);
4192
4193 if (a && in6_addr_is_set(a) && current->n_suppress == 0) {
4194 r = json_variant_new_string(&add, n);
4195 if (r < 0)
4196 goto finish;
4197
4198 r = json_variant_new_array_bytes(&add_more, a, sizeof(struct in6_addr));
4199 if (r < 0)
4200 goto finish;
4201 }
4202
4203 n_subtract = 2; /* we generated two item */
4204
4205 current->expect = EXPECT_OBJECT_KEY;
4206 break;
4207 }
4208
4209 case _JSON_BUILD_PAIR_IN_ADDR_NON_NULL: {
4210 const union in_addr_union *a;
4211 const char *n;
4212 int f;
4213
4214 if (current->expect != EXPECT_OBJECT_KEY) {
4215 r = -EINVAL;
4216 goto finish;
4217 }
4218
4219 n = va_arg(ap, const char *);
4220 a = va_arg(ap, const union in_addr_union *);
4221 f = va_arg(ap, int);
4222
4223 if (a && in_addr_is_set(f, a) && current->n_suppress == 0) {
4224 r = json_variant_new_string(&add, n);
4225 if (r < 0)
4226 goto finish;
4227
4228 r = json_variant_new_array_bytes(&add_more, a->bytes, FAMILY_ADDRESS_SIZE(f));
4229 if (r < 0)
4230 goto finish;
4231 }
4232
4233 n_subtract = 2; /* we generated two item */
4234
4235 current->expect = EXPECT_OBJECT_KEY;
4236 break;
4237 }
4238
4239 case _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL: {
4240 const struct ether_addr *a;
4241 const char *n;
4242
4243 if (current->expect != EXPECT_OBJECT_KEY) {
4244 r = -EINVAL;
4245 goto finish;
4246 }
4247
4248 n = va_arg(ap, const char *);
4249 a = va_arg(ap, const struct ether_addr *);
4250
4251 if (a && !ether_addr_is_null(a) && current->n_suppress == 0) {
4252 r = json_variant_new_string(&add, n);
4253 if (r < 0)
4254 goto finish;
4255
4256 r = json_variant_new_array_bytes(&add_more, a->ether_addr_octet, sizeof(struct ether_addr));
4257 if (r < 0)
4258 goto finish;
4259 }
4260
4261 n_subtract = 2; /* we generated two item */
4262
4263 current->expect = EXPECT_OBJECT_KEY;
4264 break;
4265 }
4266
4267 case _JSON_BUILD_PAIR_HW_ADDR_NON_NULL: {
4268 const struct hw_addr_data *a;
4269 const char *n;
4270
4271 if (current->expect != EXPECT_OBJECT_KEY) {
4272 r = -EINVAL;
4273 goto finish;
4274 }
4275
4276 n = va_arg(ap, const char *);
4277 a = va_arg(ap, const struct hw_addr_data *);
4278
4279 if (a && !hw_addr_is_null(a) && current->n_suppress == 0) {
4280 r = json_variant_new_string(&add, n);
4281 if (r < 0)
4282 goto finish;
4283
4284 r = json_variant_new_array_bytes(&add_more, a->bytes, a->length);
4285 if (r < 0)
4286 goto finish;
4287 }
4288
4289 n_subtract = 2; /* we generated two item */
4290
4291 current->expect = EXPECT_OBJECT_KEY;
4292 break;
4293 }
4294 }
4295
4296 /* If variants were generated, add them to our current variant, but only if we are not supposed to suppress additions */
4297 if (add && current->n_suppress == 0) {
4298 if (!GREEDY_REALLOC(current->elements, current->n_elements + 1 + !!add_more)) {
4299 r = -ENOMEM;
4300 goto finish;
4301 }
4302
4303 current->elements[current->n_elements++] = TAKE_PTR(add);
4304 if (add_more)
4305 current->elements[current->n_elements++] = TAKE_PTR(add_more);
4306 }
4307
4308 /* If we are supposed to suppress items, let's subtract how many items where generated from
4309 * that counter. Except if the counter is SIZE_MAX, i.e. we shall suppress an infinite number
4310 * of elements on this stack level */
4311 if (current->n_suppress != SIZE_MAX) {
4312 if (current->n_suppress <= n_subtract) /* Saturated */
4313 current->n_suppress = 0;
4314 else
4315 current->n_suppress -= n_subtract;
4316 }
4317 }
4318
4319 done:
4320 assert(n_stack == 1);
4321 assert(stack[0].n_elements == 1);
4322
4323 *ret = json_variant_ref(stack[0].elements[0]);
4324 r = 0;
4325
4326 finish:
4327 for (size_t i = 0; i < n_stack; i++)
4328 json_stack_release(stack + i);
4329
4330 free(stack);
4331
4332 return r;
4333 }
4334
4335 int json_build(JsonVariant **ret, ...) {
4336 va_list ap;
4337 int r;
4338
4339 va_start(ap, ret);
4340 r = json_buildv(ret, ap);
4341 va_end(ap);
4342
4343 return r;
4344 }
4345
4346 int json_log_internal(
4347 JsonVariant *variant,
4348 int level,
4349 int error,
4350 const char *file,
4351 int line,
4352 const char *func,
4353 const char *format, ...) {
4354
4355 PROTECT_ERRNO;
4356
4357 unsigned source_line, source_column;
4358 char buffer[LINE_MAX];
4359 const char *source;
4360 va_list ap;
4361 int r;
4362
4363 errno = ERRNO_VALUE(error);
4364
4365 va_start(ap, format);
4366 (void) vsnprintf(buffer, sizeof buffer, format, ap);
4367 va_end(ap);
4368
4369 if (variant) {
4370 r = json_variant_get_source(variant, &source, &source_line, &source_column);
4371 if (r < 0)
4372 return r;
4373 } else {
4374 source = NULL;
4375 source_line = 0;
4376 source_column = 0;
4377 }
4378
4379 if (source && source_line > 0 && source_column > 0)
4380 return log_struct_internal(
4381 level,
4382 error,
4383 file, line, func,
4384 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
4385 "CONFIG_FILE=%s", source,
4386 "CONFIG_LINE=%u", source_line,
4387 "CONFIG_COLUMN=%u", source_column,
4388 LOG_MESSAGE("%s:%u:%u: %s", source, source_line, source_column, buffer),
4389 NULL);
4390 else if (source_line > 0 && source_column > 0)
4391 return log_struct_internal(
4392 level,
4393 error,
4394 file, line, func,
4395 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
4396 "CONFIG_LINE=%u", source_line,
4397 "CONFIG_COLUMN=%u", source_column,
4398 LOG_MESSAGE("(string):%u:%u: %s", source_line, source_column, buffer),
4399 NULL);
4400 else
4401 return log_struct_internal(
4402 level,
4403 error,
4404 file, line, func,
4405 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
4406 LOG_MESSAGE("%s", buffer),
4407 NULL);
4408 }
4409
4410 static void *dispatch_userdata(const JsonDispatch *p, void *userdata) {
4411
4412 /* When the userdata pointer is passed in as NULL, then we'll just use the offset as a literal
4413 * address, and convert it to a pointer. Note that might as well just add the offset to the NULL
4414 * pointer, but UndefinedBehaviourSanitizer doesn't like pointer arithmetics based on NULL pointers,
4415 * hence we code this explicitly here. */
4416
4417 if (userdata)
4418 return (uint8_t*) userdata + p->offset;
4419
4420 return SIZE_TO_PTR(p->offset);
4421 }
4422
4423 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) {
4424 size_t m;
4425 int r, done = 0;
4426 bool *found;
4427
4428 if (!json_variant_is_object(v)) {
4429 json_log(v, flags, 0, "JSON variant is not an object.");
4430
4431 if (flags & JSON_PERMISSIVE)
4432 return 0;
4433
4434 return -EINVAL;
4435 }
4436
4437 m = 0;
4438 for (const JsonDispatch *p = table; p->name; p++)
4439 m++;
4440
4441 found = newa0(bool, m);
4442
4443 size_t n = json_variant_elements(v);
4444 for (size_t i = 0; i < n; i += 2) {
4445 JsonVariant *key, *value;
4446 const JsonDispatch *p;
4447
4448 assert_se(key = json_variant_by_index(v, i));
4449 assert_se(value = json_variant_by_index(v, i+1));
4450
4451 for (p = table; p->name; p++)
4452 if (p->name == POINTER_MAX ||
4453 streq_ptr(json_variant_string(key), p->name))
4454 break;
4455
4456 if (p->name) { /* Found a matching entry! :-) */
4457 JsonDispatchFlags merged_flags;
4458
4459 merged_flags = flags | p->flags;
4460
4461 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
4462 !json_variant_has_type(value, p->type)) {
4463
4464 json_log(value, merged_flags, 0,
4465 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
4466 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
4467
4468 if (merged_flags & JSON_PERMISSIVE)
4469 continue;
4470
4471 return -EINVAL;
4472 }
4473
4474 if (found[p-table]) {
4475 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
4476
4477 if (merged_flags & JSON_PERMISSIVE)
4478 continue;
4479
4480 return -ENOTUNIQ;
4481 }
4482
4483 found[p-table] = true;
4484
4485 if (p->callback) {
4486 r = p->callback(json_variant_string(key), value, merged_flags, dispatch_userdata(p, userdata));
4487 if (r < 0) {
4488 if (merged_flags & JSON_PERMISSIVE)
4489 continue;
4490
4491 return r;
4492 }
4493 }
4494
4495 done ++;
4496
4497 } else { /* Didn't find a matching entry! :-( */
4498
4499 if (bad) {
4500 r = bad(json_variant_string(key), value, flags, userdata);
4501 if (r < 0) {
4502 if (flags & JSON_PERMISSIVE)
4503 continue;
4504
4505 return r;
4506 } else
4507 done ++;
4508
4509 } else {
4510 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
4511
4512 if (flags & JSON_PERMISSIVE)
4513 continue;
4514
4515 return -EADDRNOTAVAIL;
4516 }
4517 }
4518 }
4519
4520 for (const JsonDispatch *p = table; p->name; p++) {
4521 JsonDispatchFlags merged_flags = p->flags | flags;
4522
4523 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
4524 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
4525
4526 if ((merged_flags & JSON_PERMISSIVE))
4527 continue;
4528
4529 return -ENXIO;
4530 }
4531 }
4532
4533 return done;
4534 }
4535
4536 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4537 bool *b = ASSERT_PTR(userdata);
4538
4539 assert(variant);
4540
4541 if (!json_variant_is_boolean(variant))
4542 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name));
4543
4544 *b = json_variant_boolean(variant);
4545 return 0;
4546 }
4547
4548 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4549 int *b = ASSERT_PTR(userdata);
4550
4551 assert(variant);
4552
4553 if (json_variant_is_null(variant)) {
4554 *b = -1;
4555 return 0;
4556 }
4557
4558 if (!json_variant_is_boolean(variant))
4559 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name));
4560
4561 *b = json_variant_boolean(variant);
4562 return 0;
4563 }
4564
4565 int json_dispatch_int64(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4566 int64_t *i = ASSERT_PTR(userdata);
4567
4568 assert(variant);
4569
4570 if (!json_variant_is_integer(variant))
4571 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
4572
4573 *i = json_variant_integer(variant);
4574 return 0;
4575 }
4576
4577 int json_dispatch_uint64(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4578 uint64_t *u = ASSERT_PTR(userdata);
4579
4580 assert(variant);
4581
4582 if (!json_variant_is_unsigned(variant))
4583 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer.", strna(name));
4584
4585 *u = json_variant_unsigned(variant);
4586 return 0;
4587 }
4588
4589 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4590 uint32_t *u = ASSERT_PTR(userdata);
4591
4592 assert(variant);
4593
4594 if (!json_variant_is_unsigned(variant))
4595 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer.", strna(name));
4596
4597 if (json_variant_unsigned(variant) > UINT32_MAX)
4598 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4599
4600 *u = (uint32_t) json_variant_unsigned(variant);
4601 return 0;
4602 }
4603
4604 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4605 int32_t *i = ASSERT_PTR(userdata);
4606
4607 assert(variant);
4608
4609 if (!json_variant_is_integer(variant))
4610 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
4611
4612 if (json_variant_integer(variant) < INT32_MIN || json_variant_integer(variant) > INT32_MAX)
4613 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4614
4615 *i = (int32_t) json_variant_integer(variant);
4616 return 0;
4617 }
4618
4619 int json_dispatch_int16(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4620 int16_t *i = ASSERT_PTR(userdata);
4621
4622 assert(variant);
4623
4624 if (!json_variant_is_integer(variant))
4625 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
4626
4627 if (json_variant_integer(variant) < INT16_MIN || json_variant_integer(variant) > INT16_MAX)
4628 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4629
4630 *i = (int16_t) json_variant_integer(variant);
4631 return 0;
4632 }
4633
4634 int json_dispatch_uint16(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4635 uint16_t *i = ASSERT_PTR(userdata);
4636
4637 assert(variant);
4638
4639 if (!json_variant_is_unsigned(variant))
4640 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer.", strna(name));
4641
4642 if (json_variant_unsigned(variant) > UINT16_MAX)
4643 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
4644
4645 *i = (uint16_t) json_variant_unsigned(variant);
4646 return 0;
4647 }
4648
4649 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4650 char **s = ASSERT_PTR(userdata);
4651 int r;
4652
4653 assert(variant);
4654
4655 if (json_variant_is_null(variant)) {
4656 *s = mfree(*s);
4657 return 0;
4658 }
4659
4660 if (!json_variant_is_string(variant))
4661 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4662
4663 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
4664 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4665
4666 r = free_and_strdup(s, json_variant_string(variant));
4667 if (r < 0)
4668 return json_log(variant, flags, r, "Failed to allocate string: %m");
4669
4670 return 0;
4671 }
4672
4673 int json_dispatch_const_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4674 const char **s = ASSERT_PTR(userdata);
4675
4676 assert(variant);
4677
4678 if (json_variant_is_null(variant)) {
4679 *s = NULL;
4680 return 0;
4681 }
4682
4683 if (!json_variant_is_string(variant))
4684 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4685
4686 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
4687 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4688
4689 *s = json_variant_string(variant);
4690 return 0;
4691 }
4692
4693 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4694 _cleanup_strv_free_ char **l = NULL;
4695 char ***s = ASSERT_PTR(userdata);
4696 JsonVariant *e;
4697 int r;
4698
4699 assert(variant);
4700
4701 if (json_variant_is_null(variant)) {
4702 *s = strv_free(*s);
4703 return 0;
4704 }
4705
4706 /* Let's be flexible here: accept a single string in place of a single-item array */
4707 if (json_variant_is_string(variant)) {
4708 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
4709 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4710
4711 l = strv_new(json_variant_string(variant));
4712 if (!l)
4713 return log_oom();
4714
4715 strv_free_and_replace(*s, l);
4716 return 0;
4717 }
4718
4719 if (!json_variant_is_array(variant))
4720 return json_log(variant, SYNTHETIC_ERRNO(EINVAL), flags, "JSON field '%s' is not an array.", strna(name));
4721
4722 JSON_VARIANT_ARRAY_FOREACH(e, variant) {
4723 if (!json_variant_is_string(e))
4724 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON array element is not a string.");
4725
4726 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(e)))
4727 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
4728
4729 r = strv_extend(&l, json_variant_string(e));
4730 if (r < 0)
4731 return json_log(e, flags, r, "Failed to append array element: %m");
4732 }
4733
4734 strv_free_and_replace(*s, l);
4735 return 0;
4736 }
4737
4738 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4739 JsonVariant **p = ASSERT_PTR(userdata);
4740 assert(variant);
4741
4742 /* Takes a reference */
4743 JSON_VARIANT_REPLACE(*p, json_variant_ref(variant));
4744 return 0;
4745 }
4746
4747 int json_dispatch_variant_noref(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4748 JsonVariant **p = ASSERT_PTR(userdata);
4749 assert(variant);
4750
4751 /* Doesn't take a reference */
4752 *p = variant;
4753 return 0;
4754 }
4755
4756 int json_dispatch_uid_gid(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4757 uid_t *uid = userdata;
4758 uint64_t k;
4759
4760 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
4761 assert_cc(sizeof(gid_t) == sizeof(uint32_t));
4762
4763 DISABLE_WARNING_TYPE_LIMITS;
4764 assert_cc((UID_INVALID < (uid_t) 0) == (GID_INVALID < (gid_t) 0));
4765 REENABLE_WARNING;
4766
4767 if (json_variant_is_null(variant)) {
4768 *uid = UID_INVALID;
4769 return 0;
4770 }
4771
4772 if (!json_variant_is_unsigned(variant))
4773 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
4774
4775 k = json_variant_unsigned(variant);
4776 if (k > UINT32_MAX || !uid_is_valid(k))
4777 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid UID/GID.", strna(name));
4778
4779 *uid = k;
4780 return 0;
4781 }
4782
4783 int json_dispatch_user_group_name(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4784 char **s = userdata;
4785 const char *n;
4786 int r;
4787
4788 if (json_variant_is_null(variant)) {
4789 *s = mfree(*s);
4790 return 0;
4791 }
4792
4793 if (!json_variant_is_string(variant))
4794 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4795
4796 n = json_variant_string(variant);
4797 if (!valid_user_group_name(n, FLAGS_SET(flags, JSON_RELAX) ? VALID_USER_RELAX : 0))
4798 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid user/group name.", strna(name));
4799
4800 r = free_and_strdup(s, n);
4801 if (r < 0)
4802 return json_log(variant, flags, r, "Failed to allocate string: %m");
4803
4804 return 0;
4805 }
4806
4807 int json_dispatch_id128(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4808 sd_id128_t *uuid = userdata;
4809 int r;
4810
4811 if (json_variant_is_null(variant)) {
4812 *uuid = SD_ID128_NULL;
4813 return 0;
4814 }
4815
4816 if (!json_variant_is_string(variant))
4817 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
4818
4819 r = sd_id128_from_string(json_variant_string(variant), uuid);
4820 if (r < 0)
4821 return json_log(variant, flags, r, "JSON field '%s' is not a valid UID.", strna(name));
4822
4823 return 0;
4824 }
4825
4826 int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
4827 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not allowed in this object.", strna(name));
4828 }
4829
4830 static int json_cmp_strings(const void *x, const void *y) {
4831 JsonVariant *const *a = x, *const *b = y;
4832
4833 if (!json_variant_is_string(*a) || !json_variant_is_string(*b))
4834 return CMP(*a, *b);
4835
4836 return strcmp(json_variant_string(*a), json_variant_string(*b));
4837 }
4838
4839 int json_variant_sort(JsonVariant **v) {
4840 _cleanup_free_ JsonVariant **a = NULL;
4841 _cleanup_(json_variant_unrefp) JsonVariant *n = NULL;
4842 size_t m;
4843 int r;
4844
4845 assert(v);
4846
4847 if (json_variant_is_sorted(*v))
4848 return 0;
4849
4850 if (!json_variant_is_object(*v))
4851 return -EMEDIUMTYPE;
4852
4853 /* Sorts they key/value pairs in an object variant */
4854
4855 m = json_variant_elements(*v);
4856 a = new(JsonVariant*, m);
4857 if (!a)
4858 return -ENOMEM;
4859
4860 for (size_t i = 0; i < m; i++)
4861 a[i] = json_variant_by_index(*v, i);
4862
4863 qsort(a, m/2, sizeof(JsonVariant*)*2, json_cmp_strings);
4864
4865 r = json_variant_new_object(&n, a, m);
4866 if (r < 0)
4867 return r;
4868
4869 json_variant_propagate_sensitive(*v, n);
4870
4871 if (!n->sorted) /* Check if this worked. This will fail if there are multiple identical keys used. */
4872 return -ENOTUNIQ;
4873
4874 JSON_VARIANT_REPLACE(*v, TAKE_PTR(n));
4875
4876 return 1;
4877 }
4878
4879 int json_variant_normalize(JsonVariant **v) {
4880 _cleanup_free_ JsonVariant **a = NULL;
4881 _cleanup_(json_variant_unrefp) JsonVariant *n = NULL;
4882 size_t i, m;
4883 int r;
4884
4885 assert(v);
4886
4887 if (json_variant_is_normalized(*v))
4888 return 0;
4889
4890 if (!json_variant_is_object(*v) && !json_variant_is_array(*v))
4891 return -EMEDIUMTYPE;
4892
4893 /* Sorts the key/value pairs in an object variant anywhere down the tree in the specified variant */
4894
4895 m = json_variant_elements(*v);
4896 a = new(JsonVariant*, m);
4897 if (!a)
4898 return -ENOMEM;
4899
4900 for (i = 0; i < m; ) {
4901 a[i] = json_variant_ref(json_variant_by_index(*v, i));
4902 i++;
4903
4904 r = json_variant_normalize(&a[i-1]);
4905 if (r < 0)
4906 goto finish;
4907 }
4908
4909 qsort(a, m/2, sizeof(JsonVariant*)*2, json_cmp_strings);
4910
4911 if (json_variant_is_object(*v))
4912 r = json_variant_new_object(&n, a, m);
4913 else {
4914 assert(json_variant_is_array(*v));
4915 r = json_variant_new_array(&n, a, m);
4916 }
4917 if (r < 0)
4918 goto finish;
4919
4920 json_variant_propagate_sensitive(*v, n);
4921
4922 if (!n->normalized) { /* Let's see if normalization worked. It will fail if there are multiple
4923 * identical keys used in the same object anywhere, or if there are floating
4924 * point numbers used (see below) */
4925 r = -ENOTUNIQ;
4926 goto finish;
4927 }
4928
4929 JSON_VARIANT_REPLACE(*v, TAKE_PTR(n));
4930
4931 r = 1;
4932
4933 finish:
4934 for (size_t j = 0; j < i; j++)
4935 json_variant_unref(a[j]);
4936
4937 return r;
4938 }
4939
4940 bool json_variant_is_normalized(JsonVariant *v) {
4941 /* For now, let's consider anything containing numbers not expressible as integers as non-normalized.
4942 * That's because we cannot sensibly compare them due to accuracy issues, nor even store them if they
4943 * are too large. */
4944 if (json_variant_is_real(v) && !json_variant_is_integer(v) && !json_variant_is_unsigned(v))
4945 return false;
4946
4947 /* The concept only applies to variants that include other variants, i.e. objects and arrays. All
4948 * others are normalized anyway. */
4949 if (!json_variant_is_object(v) && !json_variant_is_array(v))
4950 return true;
4951
4952 /* Empty objects/arrays don't include any other variant, hence are always normalized too */
4953 if (json_variant_elements(v) == 0)
4954 return true;
4955
4956 return v->normalized; /* For everything else there's an explicit boolean we maintain */
4957 }
4958
4959 bool json_variant_is_sorted(JsonVariant *v) {
4960
4961 /* Returns true if all key/value pairs of an object are properly sorted. Note that this only applies
4962 * to objects, not arrays. */
4963
4964 if (!json_variant_is_object(v))
4965 return true;
4966 if (json_variant_elements(v) <= 1)
4967 return true;
4968
4969 return v->sorted;
4970 }
4971
4972 int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size) {
4973 if (!json_variant_is_string(v))
4974 return -EINVAL;
4975
4976 return unbase64mem(json_variant_string(v), SIZE_MAX, ret, ret_size);
4977 }
4978
4979 int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size) {
4980 if (!json_variant_is_string(v))
4981 return -EINVAL;
4982
4983 return unhexmem(json_variant_string(v), SIZE_MAX, ret, ret_size);
4984 }
4985
4986 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
4987 [JSON_VARIANT_STRING] = "string",
4988 [JSON_VARIANT_INTEGER] = "integer",
4989 [JSON_VARIANT_UNSIGNED] = "unsigned",
4990 [JSON_VARIANT_REAL] = "real",
4991 [JSON_VARIANT_NUMBER] = "number",
4992 [JSON_VARIANT_BOOLEAN] = "boolean",
4993 [JSON_VARIANT_ARRAY] = "array",
4994 [JSON_VARIANT_OBJECT] = "object",
4995 [JSON_VARIANT_NULL] = "null",
4996 };
4997
4998 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);