]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/json.c
util: split out memcmp()/memset() related calls into memory-util.[ch]
[thirdparty/systemd.git] / src / shared / json.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <math.h>
5 #include <stdarg.h>
6 #include <stdio_ext.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10
11 #include "sd-messages.h"
12
13 #include "alloc-util.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 "memory-util.h"
22 #include "string-table.h"
23 #include "string-util.h"
24 #include "strv.h"
25 #include "terminal-util.h"
26 #include "utf8.h"
27
28 /* Refuse putting together variants with a larger depth than 4K by default (as a protection against overflowing stacks
29 * if code processes JSON objects recursively. Note that we store the depth in an uint16_t, hence make sure this
30 * remains under 2^16.
31 * The value was 16k, but it was discovered to be too high on llvm/x86-64. See also the issue #10738. */
32 #define DEPTH_MAX (4U*1024U)
33 assert_cc(DEPTH_MAX <= UINT16_MAX);
34
35 typedef struct JsonSource {
36 /* When we parse from a file or similar, encodes the filename, to indicate the source of a json variant */
37 size_t n_ref;
38 unsigned max_line;
39 unsigned max_column;
40 char name[];
41 } JsonSource;
42
43 /* On x86-64 this whole structure should have a size of 6 * 64 bit = 48 bytes */
44 struct JsonVariant {
45 union {
46 /* We either maintain a reference counter for this variant itself, or we are embedded into an
47 * array/object, in which case only that surrounding object is ref-counted. (If 'embedded' is false,
48 * see below.) */
49 size_t n_ref;
50
51 /* If this JsonVariant is part of an array/object, then this field points to the surrounding
52 * JSON_VARIANT_ARRAY/JSON_VARIANT_OBJECT object. (If 'embedded' is true, see below.) */
53 JsonVariant *parent;
54 };
55
56 /* If this was parsed from some file or buffer, this stores where from, as well as the source line/column */
57 JsonSource *source;
58 unsigned line, column;
59
60 JsonVariantType type:5;
61
62 /* A marker whether this variant is embedded into in array/object or not. If true, the 'parent' pointer above
63 * is valid. If false, the 'n_ref' field above is valid instead. */
64 bool is_embedded:1;
65
66 /* In some conditions (for example, if this object is part of an array of strings or objects), we don't store
67 * any data inline, but instead simply reference an external object and act as surrogate of it. In that case
68 * this bool is set, and the external object is referenced through the .reference field below. */
69 bool is_reference:1;
70
71 /* While comparing two arrays, we use this for marking what we already have seen */
72 bool is_marked:1;
73
74 /* The current 'depth' of the JsonVariant, i.e. how many levels of member variants this has */
75 uint16_t depth;
76
77 union {
78 /* For simple types we store the value in-line. */
79 JsonValue value;
80
81 /* For objects and arrays we store the number of elements immediately following */
82 size_t n_elements;
83
84 /* If is_reference as indicated above is set, this is where the reference object is actually stored. */
85 JsonVariant *reference;
86
87 /* Strings are placed immediately after the structure. Note that when this is a JsonVariant embedded
88 * into an array we might encode strings up to INLINE_STRING_LENGTH characters directly inside the
89 * element, while longer strings are stored as references. When this object is not embedded into an
90 * array, but stand-alone we allocate the right size for the whole structure, i.e. the array might be
91 * much larger than INLINE_STRING_LENGTH.
92 *
93 * Note that because we want to allocate arrays of the JsonVariant structure we specify [0] here,
94 * rather than the prettier []. If we wouldn't, then this char array would have undefined size, and so
95 * would the union and then the struct this is included in. And of structures with undefined size we
96 * can't allocate arrays (at least not easily). */
97 char string[0];
98 };
99 };
100
101 /* Inside string arrays we have a series of JasonVariant structures one after the other. In this case, strings longer
102 * than INLINE_STRING_MAX are stored as references, and all shorter ones inline. (This means — on x86-64 — strings up
103 * to 15 chars are stored within the array elements, and all others in separate allocations) */
104 #define INLINE_STRING_MAX (sizeof(JsonVariant) - offsetof(JsonVariant, string) - 1U)
105
106 /* Let's make sure this structure isn't increased in size accidentally. This check is only for our most relevant arch
107 * (x86-64). */
108 #ifdef __x86_64__
109 assert_cc(sizeof(JsonVariant) == 48U);
110 assert_cc(INLINE_STRING_MAX == 15U);
111 #endif
112
113 static JsonSource* json_source_new(const char *name) {
114 JsonSource *s;
115
116 assert(name);
117
118 s = malloc(offsetof(JsonSource, name) + strlen(name) + 1);
119 if (!s)
120 return NULL;
121
122 *s = (JsonSource) {
123 .n_ref = 1,
124 };
125 strcpy(s->name, name);
126
127 return s;
128 }
129
130 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(JsonSource, json_source, mfree);
131
132 static bool json_source_equal(JsonSource *a, JsonSource *b) {
133 if (a == b)
134 return true;
135
136 if (!a || !b)
137 return false;
138
139 return streq(a->name, b->name);
140 }
141
142 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonSource*, json_source_unref);
143
144 /* There are four kind of JsonVariant* pointers:
145 *
146 * 1. NULL
147 * 2. A 'regular' one, i.e. pointing to malloc() memory
148 * 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.
149 * 4. A 'const string' one, i.e. a pointer to a const string.
150 *
151 * The four kinds of pointers can be discerned like this:
152 *
153 * Detecting #1 is easy, just compare with NULL. Detecting #3 is similarly easy: all magic pointers are below
154 * _JSON_VARIANT_MAGIC_MAX (which is pretty low, within the first memory page, which is special on Linux and other
155 * 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,
156 * otherwise #4. This makes use of the fact that malloc() will return "maximum aligned" memory, which definitely
157 * means the pointer is even. This means we can use the uneven pointers to reference static strings, as long as we
158 * make sure that all static strings used like this are aligned to 2 (or higher), and that we mask the bit on
159 * access. The JSON_VARIANT_STRING_CONST() macro encodes strings as JsonVariant* pointers, with the bit set. */
160
161 static bool json_variant_is_magic(const JsonVariant *v) {
162 if (!v)
163 return false;
164
165 return v < _JSON_VARIANT_MAGIC_MAX;
166 }
167
168 static bool json_variant_is_const_string(const JsonVariant *v) {
169
170 if (v < _JSON_VARIANT_MAGIC_MAX)
171 return false;
172
173 /* A proper JsonVariant is aligned to whatever malloc() aligns things too, which is definitely not uneven. We
174 * hence use all uneven pointers as indicators for const strings. */
175
176 return (((uintptr_t) v) & 1) != 0;
177 }
178
179 static bool json_variant_is_regular(const JsonVariant *v) {
180
181 if (v < _JSON_VARIANT_MAGIC_MAX)
182 return false;
183
184 return (((uintptr_t) v) & 1) == 0;
185 }
186
187 static JsonVariant *json_variant_dereference(JsonVariant *v) {
188
189 /* Recursively dereference variants that are references to other variants */
190
191 if (!v)
192 return NULL;
193
194 if (!json_variant_is_regular(v))
195 return v;
196
197 if (!v->is_reference)
198 return v;
199
200 return json_variant_dereference(v->reference);
201 }
202
203 static uint16_t json_variant_depth(JsonVariant *v) {
204
205 v = json_variant_dereference(v);
206 if (!v)
207 return 0;
208
209 if (!json_variant_is_regular(v))
210 return 0;
211
212 return v->depth;
213 }
214
215 static JsonVariant *json_variant_normalize(JsonVariant *v) {
216
217 /* Converts json variants to their normalized form, i.e. fully dereferenced and wherever possible converted to
218 * the "magic" version if there is one */
219
220 if (!v)
221 return NULL;
222
223 v = json_variant_dereference(v);
224
225 switch (json_variant_type(v)) {
226
227 case JSON_VARIANT_BOOLEAN:
228 return json_variant_boolean(v) ? JSON_VARIANT_MAGIC_TRUE : JSON_VARIANT_MAGIC_FALSE;
229
230 case JSON_VARIANT_NULL:
231 return JSON_VARIANT_MAGIC_NULL;
232
233 case JSON_VARIANT_INTEGER:
234 return json_variant_integer(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_INTEGER : v;
235
236 case JSON_VARIANT_UNSIGNED:
237 return json_variant_unsigned(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED : v;
238
239 case JSON_VARIANT_REAL:
240 #pragma GCC diagnostic push
241 #pragma GCC diagnostic ignored "-Wfloat-equal"
242 return json_variant_real(v) == 0.0 ? JSON_VARIANT_MAGIC_ZERO_REAL : v;
243 #pragma GCC diagnostic pop
244
245 case JSON_VARIANT_STRING:
246 return isempty(json_variant_string(v)) ? JSON_VARIANT_MAGIC_EMPTY_STRING : v;
247
248 case JSON_VARIANT_ARRAY:
249 return json_variant_elements(v) == 0 ? JSON_VARIANT_MAGIC_EMPTY_ARRAY : v;
250
251 case JSON_VARIANT_OBJECT:
252 return json_variant_elements(v) == 0 ? JSON_VARIANT_MAGIC_EMPTY_OBJECT : v;
253
254 default:
255 return v;
256 }
257 }
258
259 static JsonVariant *json_variant_conservative_normalize(JsonVariant *v) {
260
261 /* Much like json_variant_normalize(), but won't simplify if the variant has a source/line location attached to
262 * it, in order not to lose context */
263
264 if (!v)
265 return NULL;
266
267 if (!json_variant_is_regular(v))
268 return v;
269
270 if (v->source || v->line > 0 || v->column > 0)
271 return v;
272
273 return json_variant_normalize(v);
274 }
275
276 static int json_variant_new(JsonVariant **ret, JsonVariantType type, size_t space) {
277 JsonVariant *v;
278
279 assert_return(ret, -EINVAL);
280
281 v = malloc0(offsetof(JsonVariant, value) + space);
282 if (!v)
283 return -ENOMEM;
284
285 v->n_ref = 1;
286 v->type = type;
287
288 *ret = v;
289 return 0;
290 }
291
292 int json_variant_new_integer(JsonVariant **ret, intmax_t i) {
293 JsonVariant *v;
294 int r;
295
296 assert_return(ret, -EINVAL);
297
298 if (i == 0) {
299 *ret = JSON_VARIANT_MAGIC_ZERO_INTEGER;
300 return 0;
301 }
302
303 r = json_variant_new(&v, JSON_VARIANT_INTEGER, sizeof(i));
304 if (r < 0)
305 return r;
306
307 v->value.integer = i;
308 *ret = v;
309
310 return 0;
311 }
312
313 int json_variant_new_unsigned(JsonVariant **ret, uintmax_t u) {
314 JsonVariant *v;
315 int r;
316
317 assert_return(ret, -EINVAL);
318 if (u == 0) {
319 *ret = JSON_VARIANT_MAGIC_ZERO_UNSIGNED;
320 return 0;
321 }
322
323 r = json_variant_new(&v, JSON_VARIANT_UNSIGNED, sizeof(u));
324 if (r < 0)
325 return r;
326
327 v->value.unsig = u;
328 *ret = v;
329
330 return 0;
331 }
332
333 int json_variant_new_real(JsonVariant **ret, long double d) {
334 JsonVariant *v;
335 int r;
336
337 assert_return(ret, -EINVAL);
338
339 #pragma GCC diagnostic push
340 #pragma GCC diagnostic ignored "-Wfloat-equal"
341 if (d == 0.0) {
342 #pragma GCC diagnostic pop
343 *ret = JSON_VARIANT_MAGIC_ZERO_REAL;
344 return 0;
345 }
346
347 r = json_variant_new(&v, JSON_VARIANT_REAL, sizeof(d));
348 if (r < 0)
349 return r;
350
351 v->value.real = d;
352 *ret = v;
353
354 return 0;
355 }
356
357 int json_variant_new_boolean(JsonVariant **ret, bool b) {
358 assert_return(ret, -EINVAL);
359
360 if (b)
361 *ret = JSON_VARIANT_MAGIC_TRUE;
362 else
363 *ret = JSON_VARIANT_MAGIC_FALSE;
364
365 return 0;
366 }
367
368 int json_variant_new_null(JsonVariant **ret) {
369 assert_return(ret, -EINVAL);
370
371 *ret = JSON_VARIANT_MAGIC_NULL;
372 return 0;
373 }
374
375 int json_variant_new_stringn(JsonVariant **ret, const char *s, size_t n) {
376 JsonVariant *v;
377 int r;
378
379 assert_return(ret, -EINVAL);
380 if (!s) {
381 assert_return(n == 0, -EINVAL);
382 return json_variant_new_null(ret);
383 }
384 if (n == 0) {
385 *ret = JSON_VARIANT_MAGIC_EMPTY_STRING;
386 return 0;
387 }
388
389 r = json_variant_new(&v, JSON_VARIANT_STRING, n + 1);
390 if (r < 0)
391 return r;
392
393 memcpy(v->string, s, n);
394 v->string[n] = 0;
395
396 *ret = v;
397 return 0;
398 }
399
400 static void json_variant_set(JsonVariant *a, JsonVariant *b) {
401 assert(a);
402
403 b = json_variant_dereference(b);
404 if (!b) {
405 a->type = JSON_VARIANT_NULL;
406 return;
407 }
408
409 a->type = json_variant_type(b);
410 switch (a->type) {
411
412 case JSON_VARIANT_INTEGER:
413 a->value.integer = json_variant_integer(b);
414 break;
415
416 case JSON_VARIANT_UNSIGNED:
417 a->value.unsig = json_variant_unsigned(b);
418 break;
419
420 case JSON_VARIANT_REAL:
421 a->value.real = json_variant_real(b);
422 break;
423
424 case JSON_VARIANT_BOOLEAN:
425 a->value.boolean = json_variant_boolean(b);
426 break;
427
428 case JSON_VARIANT_STRING: {
429 const char *s;
430
431 assert_se(s = json_variant_string(b));
432
433 /* Short strings we can store inline */
434 if (strnlen(s, INLINE_STRING_MAX+1) <= INLINE_STRING_MAX) {
435 strcpy(a->string, s);
436 break;
437 }
438
439 /* For longer strings, use a reference… */
440 _fallthrough_;
441 }
442
443 case JSON_VARIANT_ARRAY:
444 case JSON_VARIANT_OBJECT:
445 a->is_reference = true;
446 a->reference = json_variant_ref(json_variant_conservative_normalize(b));
447 break;
448
449 case JSON_VARIANT_NULL:
450 break;
451
452 default:
453 assert_not_reached("Unexpected variant type");
454 }
455 }
456
457 static void json_variant_copy_source(JsonVariant *v, JsonVariant *from) {
458 assert(v);
459 assert(from);
460
461 if (!json_variant_is_regular(from))
462 return;
463
464 v->line = from->line;
465 v->column = from->column;
466 v->source = json_source_ref(from->source);
467 }
468
469 int json_variant_new_array(JsonVariant **ret, JsonVariant **array, size_t n) {
470 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
471
472 assert_return(ret, -EINVAL);
473 if (n == 0) {
474 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
475 return 0;
476 }
477 assert_return(array, -EINVAL);
478
479 v = new(JsonVariant, n + 1);
480 if (!v)
481 return -ENOMEM;
482
483 *v = (JsonVariant) {
484 .n_ref = 1,
485 .type = JSON_VARIANT_ARRAY,
486 };
487
488 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
489 JsonVariant *w = v + 1 + v->n_elements,
490 *c = array[v->n_elements];
491 uint16_t d;
492
493 d = json_variant_depth(c);
494 if (d >= DEPTH_MAX) /* Refuse too deep nesting */
495 return -ELNRNG;
496 if (d >= v->depth)
497 v->depth = d + 1;
498
499 *w = (JsonVariant) {
500 .is_embedded = true,
501 .parent = v,
502 };
503
504 json_variant_set(w, c);
505 json_variant_copy_source(w, c);
506 }
507
508 *ret = TAKE_PTR(v);
509 return 0;
510 }
511
512 int json_variant_new_array_bytes(JsonVariant **ret, const void *p, size_t n) {
513 JsonVariant *v;
514 size_t i;
515
516 assert_return(ret, -EINVAL);
517 if (n == 0) {
518 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
519 return 0;
520 }
521 assert_return(p, -EINVAL);
522
523 v = new(JsonVariant, n + 1);
524 if (!v)
525 return -ENOMEM;
526
527 *v = (JsonVariant) {
528 .n_ref = 1,
529 .type = JSON_VARIANT_ARRAY,
530 .n_elements = n,
531 .depth = 1,
532 };
533
534 for (i = 0; i < n; i++) {
535 JsonVariant *w = v + 1 + i;
536
537 *w = (JsonVariant) {
538 .is_embedded = true,
539 .parent = v,
540 .type = JSON_VARIANT_UNSIGNED,
541 .value.unsig = ((const uint8_t*) p)[i],
542 };
543 }
544
545 *ret = v;
546 return 0;
547 }
548
549 int json_variant_new_array_strv(JsonVariant **ret, char **l) {
550 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
551 size_t n;
552 int r;
553
554 assert(ret);
555
556 n = strv_length(l);
557 if (n == 0) {
558 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
559 return 0;
560 }
561
562 v = new(JsonVariant, n + 1);
563 if (!v)
564 return -ENOMEM;
565
566 *v = (JsonVariant) {
567 .n_ref = 1,
568 .type = JSON_VARIANT_ARRAY,
569 .depth = 1,
570 };
571
572 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
573 JsonVariant *w = v + 1 + v->n_elements;
574 size_t k;
575
576 *w = (JsonVariant) {
577 .is_embedded = true,
578 .parent = v,
579 .type = JSON_VARIANT_STRING,
580 };
581
582 k = strlen(l[v->n_elements]);
583
584 if (k > INLINE_STRING_MAX) {
585 /* If string is too long, store it as reference. */
586
587 r = json_variant_new_stringn(&w->reference, l[v->n_elements], k);
588 if (r < 0)
589 return r;
590
591 w->is_reference = true;
592 } else
593 memcpy(w->string, l[v->n_elements], k+1);
594 }
595
596 *ret = TAKE_PTR(v);
597 return 0;
598 }
599
600 int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n) {
601 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
602
603 assert_return(ret, -EINVAL);
604 if (n == 0) {
605 *ret = JSON_VARIANT_MAGIC_EMPTY_OBJECT;
606 return 0;
607 }
608 assert_return(array, -EINVAL);
609 assert_return(n % 2 == 0, -EINVAL);
610
611 v = new(JsonVariant, n + 1);
612 if (!v)
613 return -ENOMEM;
614
615 *v = (JsonVariant) {
616 .n_ref = 1,
617 .type = JSON_VARIANT_OBJECT,
618 };
619
620 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
621 JsonVariant *w = v + 1 + v->n_elements,
622 *c = array[v->n_elements];
623 uint16_t d;
624
625 if ((v->n_elements & 1) == 0 &&
626 !json_variant_is_string(c))
627 return -EINVAL; /* Every second one needs to be a string, as it is the key name */
628
629 d = json_variant_depth(c);
630 if (d >= DEPTH_MAX) /* Refuse too deep nesting */
631 return -ELNRNG;
632 if (d >= v->depth)
633 v->depth = d + 1;
634
635 *w = (JsonVariant) {
636 .is_embedded = true,
637 .parent = v,
638 };
639
640 json_variant_set(w, c);
641 json_variant_copy_source(w, c);
642 }
643
644 *ret = TAKE_PTR(v);
645 return 0;
646 }
647
648 static void json_variant_free_inner(JsonVariant *v) {
649 assert(v);
650
651 if (!json_variant_is_regular(v))
652 return;
653
654 json_source_unref(v->source);
655
656 if (v->is_reference) {
657 json_variant_unref(v->reference);
658 return;
659 }
660
661 if (IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT)) {
662 size_t i;
663
664 for (i = 0; i < v->n_elements; i++)
665 json_variant_free_inner(v + 1 + i);
666 }
667 }
668
669 JsonVariant *json_variant_ref(JsonVariant *v) {
670 if (!v)
671 return NULL;
672 if (!json_variant_is_regular(v))
673 return v;
674
675 if (v->is_embedded)
676 json_variant_ref(v->parent); /* ref the compounding variant instead */
677 else {
678 assert(v->n_ref > 0);
679 v->n_ref++;
680 }
681
682 return v;
683 }
684
685 JsonVariant *json_variant_unref(JsonVariant *v) {
686 if (!v)
687 return NULL;
688 if (!json_variant_is_regular(v))
689 return NULL;
690
691 if (v->is_embedded)
692 json_variant_unref(v->parent);
693 else {
694 assert(v->n_ref > 0);
695 v->n_ref--;
696
697 if (v->n_ref == 0) {
698 json_variant_free_inner(v);
699 free(v);
700 }
701 }
702
703 return NULL;
704 }
705
706 void json_variant_unref_many(JsonVariant **array, size_t n) {
707 size_t i;
708
709 assert(array || n == 0);
710
711 for (i = 0; i < n; i++)
712 json_variant_unref(array[i]);
713 }
714
715 const char *json_variant_string(JsonVariant *v) {
716 if (!v)
717 return NULL;
718 if (v == JSON_VARIANT_MAGIC_EMPTY_STRING)
719 return "";
720 if (json_variant_is_magic(v))
721 goto mismatch;
722 if (json_variant_is_const_string(v)) {
723 uintptr_t p = (uintptr_t) v;
724
725 assert((p & 1) != 0);
726 return (const char*) (p ^ 1U);
727 }
728
729 if (v->is_reference)
730 return json_variant_string(v->reference);
731 if (v->type != JSON_VARIANT_STRING)
732 goto mismatch;
733
734 return v->string;
735
736 mismatch:
737 log_debug("Non-string JSON variant requested as string, returning NULL.");
738 return NULL;
739 }
740
741 bool json_variant_boolean(JsonVariant *v) {
742 if (!v)
743 goto mismatch;
744 if (v == JSON_VARIANT_MAGIC_TRUE)
745 return true;
746 if (v == JSON_VARIANT_MAGIC_FALSE)
747 return false;
748 if (!json_variant_is_regular(v))
749 goto mismatch;
750 if (v->type != JSON_VARIANT_BOOLEAN)
751 goto mismatch;
752 if (v->is_reference)
753 return json_variant_boolean(v->reference);
754
755 return v->value.boolean;
756
757 mismatch:
758 log_debug("Non-boolean JSON variant requested as boolean, returning false.");
759 return false;
760 }
761
762 intmax_t json_variant_integer(JsonVariant *v) {
763 if (!v)
764 goto mismatch;
765 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
766 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
767 v == JSON_VARIANT_MAGIC_ZERO_REAL)
768 return 0;
769 if (!json_variant_is_regular(v))
770 goto mismatch;
771 if (v->is_reference)
772 return json_variant_integer(v->reference);
773
774 switch (v->type) {
775
776 case JSON_VARIANT_INTEGER:
777 return v->value.integer;
778
779 case JSON_VARIANT_UNSIGNED:
780 if (v->value.unsig <= INTMAX_MAX)
781 return (intmax_t) v->value.unsig;
782
783 log_debug("Unsigned integer %ju requested as signed integer and out of range, returning 0.", v->value.unsig);
784 return 0;
785
786 case JSON_VARIANT_REAL: {
787 intmax_t converted;
788
789 converted = (intmax_t) v->value.real;
790
791 #pragma GCC diagnostic push
792 #pragma GCC diagnostic ignored "-Wfloat-equal"
793 if ((long double) converted == v->value.real)
794 #pragma GCC diagnostic pop
795 return converted;
796
797 log_debug("Real %Lg requested as integer, and cannot be converted losslessly, returning 0.", v->value.real);
798 return 0;
799 }
800
801 default:
802 break;
803 }
804
805 mismatch:
806 log_debug("Non-integer JSON variant requested as integer, returning 0.");
807 return 0;
808 }
809
810 uintmax_t json_variant_unsigned(JsonVariant *v) {
811 if (!v)
812 goto mismatch;
813 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
814 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
815 v == JSON_VARIANT_MAGIC_ZERO_REAL)
816 return 0;
817 if (!json_variant_is_regular(v))
818 goto mismatch;
819 if (v->is_reference)
820 return json_variant_integer(v->reference);
821
822 switch (v->type) {
823
824 case JSON_VARIANT_INTEGER:
825 if (v->value.integer >= 0)
826 return (uintmax_t) v->value.integer;
827
828 log_debug("Signed integer %ju requested as unsigned integer and out of range, returning 0.", v->value.integer);
829 return 0;
830
831 case JSON_VARIANT_UNSIGNED:
832 return v->value.unsig;
833
834 case JSON_VARIANT_REAL: {
835 uintmax_t converted;
836
837 converted = (uintmax_t) v->value.real;
838
839 #pragma GCC diagnostic push
840 #pragma GCC diagnostic ignored "-Wfloat-equal"
841 if ((long double) converted == v->value.real)
842 #pragma GCC diagnostic pop
843 return converted;
844
845 log_debug("Real %Lg requested as unsigned integer, and cannot be converted losslessly, returning 0.", v->value.real);
846 return 0;
847 }
848
849 default:
850 break;
851 }
852
853 mismatch:
854 log_debug("Non-integer JSON variant requested as unsigned, returning 0.");
855 return 0;
856 }
857
858 long double json_variant_real(JsonVariant *v) {
859 if (!v)
860 return 0.0;
861 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
862 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
863 v == JSON_VARIANT_MAGIC_ZERO_REAL)
864 return 0.0;
865 if (!json_variant_is_regular(v))
866 goto mismatch;
867 if (v->is_reference)
868 return json_variant_real(v->reference);
869
870 switch (v->type) {
871
872 case JSON_VARIANT_REAL:
873 return v->value.real;
874
875 case JSON_VARIANT_INTEGER: {
876 long double converted;
877
878 converted = (long double) v->value.integer;
879
880 if ((intmax_t) converted == v->value.integer)
881 return converted;
882
883 log_debug("Signed integer %ji requested as real, and cannot be converted losslessly, returning 0.", v->value.integer);
884 return 0.0;
885 }
886
887 case JSON_VARIANT_UNSIGNED: {
888 long double converted;
889
890 converted = (long double) v->value.unsig;
891
892 if ((uintmax_t) converted == v->value.unsig)
893 return converted;
894
895 log_debug("Unsigned integer %ju requested as real, and cannot be converted losslessly, returning 0.", v->value.unsig);
896 return 0.0;
897 }
898
899 default:
900 break;
901 }
902
903 mismatch:
904 log_debug("Non-integer JSON variant requested as integer, returning 0.");
905 return 0.0;
906 }
907
908 bool json_variant_is_negative(JsonVariant *v) {
909 if (!v)
910 goto mismatch;
911 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
912 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
913 v == JSON_VARIANT_MAGIC_ZERO_REAL)
914 return false;
915 if (!json_variant_is_regular(v))
916 goto mismatch;
917 if (v->is_reference)
918 return json_variant_is_negative(v->reference);
919
920 /* This function is useful as checking whether numbers are negative is pretty complex since we have three types
921 * of numbers. And some JSON code (OCI for example) uses negative numbers to mark "not defined" numeric
922 * values. */
923
924 switch (v->type) {
925
926 case JSON_VARIANT_REAL:
927 return v->value.real < 0;
928
929 case JSON_VARIANT_INTEGER:
930 return v->value.integer < 0;
931
932 case JSON_VARIANT_UNSIGNED:
933 return false;
934
935 default:
936 break;
937 }
938
939 mismatch:
940 log_debug("Non-integer JSON variant tested for negativity, returning false.");
941 return false;
942 }
943
944 JsonVariantType json_variant_type(JsonVariant *v) {
945
946 if (!v)
947 return _JSON_VARIANT_TYPE_INVALID;
948
949 if (json_variant_is_const_string(v))
950 return JSON_VARIANT_STRING;
951
952 if (v == JSON_VARIANT_MAGIC_TRUE || v == JSON_VARIANT_MAGIC_FALSE)
953 return JSON_VARIANT_BOOLEAN;
954
955 if (v == JSON_VARIANT_MAGIC_NULL)
956 return JSON_VARIANT_NULL;
957
958 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER)
959 return JSON_VARIANT_INTEGER;
960
961 if (v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED)
962 return JSON_VARIANT_UNSIGNED;
963
964 if (v == JSON_VARIANT_MAGIC_ZERO_REAL)
965 return JSON_VARIANT_REAL;
966
967 if (v == JSON_VARIANT_MAGIC_EMPTY_STRING)
968 return JSON_VARIANT_STRING;
969
970 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY)
971 return JSON_VARIANT_ARRAY;
972
973 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
974 return JSON_VARIANT_OBJECT;
975
976 return v->type;
977 }
978
979 bool json_variant_has_type(JsonVariant *v, JsonVariantType type) {
980 JsonVariantType rt;
981
982 v = json_variant_dereference(v);
983 if (!v)
984 return false;
985
986 rt = json_variant_type(v);
987 if (rt == type)
988 return true;
989
990 /* If it's a const string, then it only can be a string, and if it is not, it's not */
991 if (json_variant_is_const_string(v))
992 return false;
993
994 /* All three magic zeroes qualify as integer, unsigned and as real */
995 if ((v == JSON_VARIANT_MAGIC_ZERO_INTEGER || v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED || v == JSON_VARIANT_MAGIC_ZERO_REAL) &&
996 IN_SET(type, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL, JSON_VARIANT_NUMBER))
997 return true;
998
999 /* All other magic variant types are only equal to themselves */
1000 if (json_variant_is_magic(v))
1001 return false;
1002
1003 /* Handle the "number" pseudo type */
1004 if (type == JSON_VARIANT_NUMBER)
1005 return IN_SET(rt, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL);
1006
1007 /* Integer conversions are OK in many cases */
1008 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_UNSIGNED)
1009 return v->value.integer >= 0;
1010 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_INTEGER)
1011 return v->value.unsig <= INTMAX_MAX;
1012
1013 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1014 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_REAL)
1015 return (intmax_t) (long double) v->value.integer == v->value.integer;
1016 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_REAL)
1017 return (uintmax_t) (long double) v->value.unsig == v->value.unsig;
1018
1019 #pragma GCC diagnostic push
1020 #pragma GCC diagnostic ignored "-Wfloat-equal"
1021 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1022 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_INTEGER)
1023 return (long double) (intmax_t) v->value.real == v->value.real;
1024 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_UNSIGNED)
1025 return (long double) (uintmax_t) v->value.real == v->value.real;
1026 #pragma GCC diagnostic pop
1027
1028 return false;
1029 }
1030
1031 size_t json_variant_elements(JsonVariant *v) {
1032 if (!v)
1033 return 0;
1034 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1035 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1036 return 0;
1037 if (!json_variant_is_regular(v))
1038 goto mismatch;
1039 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1040 goto mismatch;
1041 if (v->is_reference)
1042 return json_variant_elements(v->reference);
1043
1044 return v->n_elements;
1045
1046 mismatch:
1047 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1048 return 0;
1049 }
1050
1051 JsonVariant *json_variant_by_index(JsonVariant *v, size_t idx) {
1052 if (!v)
1053 return NULL;
1054 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1055 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1056 return NULL;
1057 if (!json_variant_is_regular(v))
1058 goto mismatch;
1059 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1060 goto mismatch;
1061 if (v->is_reference)
1062 return json_variant_by_index(v->reference, idx);
1063 if (idx >= v->n_elements)
1064 return NULL;
1065
1066 return json_variant_conservative_normalize(v + 1 + idx);
1067
1068 mismatch:
1069 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1070 return NULL;
1071 }
1072
1073 JsonVariant *json_variant_by_key_full(JsonVariant *v, const char *key, JsonVariant **ret_key) {
1074 size_t i;
1075
1076 if (!v)
1077 goto not_found;
1078 if (!key)
1079 goto not_found;
1080 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1081 goto not_found;
1082 if (!json_variant_is_regular(v))
1083 goto mismatch;
1084 if (v->type != JSON_VARIANT_OBJECT)
1085 goto mismatch;
1086 if (v->is_reference)
1087 return json_variant_by_key(v->reference, key);
1088
1089 for (i = 0; i < v->n_elements; i += 2) {
1090 JsonVariant *p;
1091
1092 p = json_variant_dereference(v + 1 + i);
1093
1094 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1095 continue;
1096
1097 if (streq(json_variant_string(p), key)) {
1098
1099 if (ret_key)
1100 *ret_key = json_variant_conservative_normalize(v + 1 + i);
1101
1102 return json_variant_conservative_normalize(v + 1 + i + 1);
1103 }
1104 }
1105
1106 not_found:
1107 if (ret_key)
1108 *ret_key = NULL;
1109
1110 return NULL;
1111
1112 mismatch:
1113 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1114 if (ret_key)
1115 *ret_key = NULL;
1116
1117 return NULL;
1118 }
1119
1120 JsonVariant *json_variant_by_key(JsonVariant *v, const char *key) {
1121 return json_variant_by_key_full(v, key, NULL);
1122 }
1123
1124 bool json_variant_equal(JsonVariant *a, JsonVariant *b) {
1125 JsonVariantType t;
1126
1127 a = json_variant_normalize(a);
1128 b = json_variant_normalize(b);
1129
1130 if (a == b)
1131 return true;
1132
1133 t = json_variant_type(a);
1134 if (!json_variant_has_type(b, t))
1135 return false;
1136
1137 switch (t) {
1138
1139 case JSON_VARIANT_STRING:
1140 return streq(json_variant_string(a), json_variant_string(b));
1141
1142 case JSON_VARIANT_INTEGER:
1143 return json_variant_integer(a) == json_variant_integer(b);
1144
1145 case JSON_VARIANT_UNSIGNED:
1146 return json_variant_unsigned(a) == json_variant_unsigned(b);
1147
1148 case JSON_VARIANT_REAL:
1149 #pragma GCC diagnostic push
1150 #pragma GCC diagnostic ignored "-Wfloat-equal"
1151 return json_variant_real(a) == json_variant_real(b);
1152 #pragma GCC diagnostic pop
1153
1154 case JSON_VARIANT_BOOLEAN:
1155 return json_variant_boolean(a) == json_variant_boolean(b);
1156
1157 case JSON_VARIANT_NULL:
1158 return true;
1159
1160 case JSON_VARIANT_ARRAY: {
1161 size_t i, n;
1162
1163 n = json_variant_elements(a);
1164 if (n != json_variant_elements(b))
1165 return false;
1166
1167 for (i = 0; i < n; i++) {
1168 if (!json_variant_equal(json_variant_by_index(a, i), json_variant_by_index(b, i)))
1169 return false;
1170 }
1171
1172 return true;
1173 }
1174
1175 case JSON_VARIANT_OBJECT: {
1176 size_t i, n;
1177
1178 n = json_variant_elements(a);
1179 if (n != json_variant_elements(b))
1180 return false;
1181
1182 /* Iterate through all keys in 'a' */
1183 for (i = 0; i < n; i += 2) {
1184 bool found = false;
1185 size_t j;
1186
1187 /* Match them against all keys in 'b' */
1188 for (j = 0; j < n; j += 2) {
1189 JsonVariant *key_b;
1190
1191 key_b = json_variant_by_index(b, j);
1192
1193 /* During the first iteration unmark everything */
1194 if (i == 0)
1195 key_b->is_marked = false;
1196 else if (key_b->is_marked) /* In later iterations if we already marked something, don't bother with it again */
1197 continue;
1198
1199 if (found)
1200 continue;
1201
1202 if (json_variant_equal(json_variant_by_index(a, i), key_b) &&
1203 json_variant_equal(json_variant_by_index(a, i+1), json_variant_by_index(b, j+1))) {
1204 /* Key and values match! */
1205 key_b->is_marked = found = true;
1206
1207 /* In the first iteration we continue the inner loop since we want to mark
1208 * everything, otherwise exit the loop quickly after we found what we were
1209 * looking for. */
1210 if (i != 0)
1211 break;
1212 }
1213 }
1214
1215 if (!found)
1216 return false;
1217 }
1218
1219 return true;
1220 }
1221
1222 default:
1223 assert_not_reached("Unknown variant type.");
1224 }
1225 }
1226
1227 int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column) {
1228 assert_return(v, -EINVAL);
1229
1230 if (ret_source)
1231 *ret_source = json_variant_is_regular(v) && v->source ? v->source->name : NULL;
1232
1233 if (ret_line)
1234 *ret_line = json_variant_is_regular(v) ? v->line : 0;
1235
1236 if (ret_column)
1237 *ret_column = json_variant_is_regular(v) ? v->column : 0;
1238
1239 return 0;
1240 }
1241
1242 static int print_source(FILE *f, JsonVariant *v, JsonFormatFlags flags, bool whitespace) {
1243 size_t w, k;
1244
1245 if (!FLAGS_SET(flags, JSON_FORMAT_SOURCE|JSON_FORMAT_PRETTY))
1246 return 0;
1247
1248 if (!json_variant_is_regular(v))
1249 return 0;
1250
1251 if (!v->source && v->line == 0 && v->column == 0)
1252 return 0;
1253
1254 /* The max width we need to format the line numbers for this source file */
1255 w = (v->source && v->source->max_line > 0) ?
1256 DECIMAL_STR_WIDTH(v->source->max_line) :
1257 DECIMAL_STR_MAX(unsigned)-1;
1258 k = (v->source && v->source->max_column > 0) ?
1259 DECIMAL_STR_WIDTH(v->source->max_column) :
1260 DECIMAL_STR_MAX(unsigned) -1;
1261
1262 if (whitespace) {
1263 size_t i, n;
1264
1265 n = 1 + (v->source ? strlen(v->source->name) : 0) +
1266 ((v->source && (v->line > 0 || v->column > 0)) ? 1 : 0) +
1267 (v->line > 0 ? w : 0) +
1268 (((v->source || v->line > 0) && v->column > 0) ? 1 : 0) +
1269 (v->column > 0 ? k : 0) +
1270 2;
1271
1272 for (i = 0; i < n; i++)
1273 fputc(' ', f);
1274 } else {
1275 fputc('[', f);
1276
1277 if (v->source)
1278 fputs(v->source->name, f);
1279 if (v->source && (v->line > 0 || v->column > 0))
1280 fputc(':', f);
1281 if (v->line > 0)
1282 fprintf(f, "%*u", (int) w, v->line);
1283 if ((v->source || v->line > 0) || v->column > 0)
1284 fputc(':', f);
1285 if (v->column > 0)
1286 fprintf(f, "%*u", (int) k, v->column);
1287
1288 fputc(']', f);
1289 fputc(' ', f);
1290 }
1291
1292 return 0;
1293 }
1294
1295 static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const char *prefix) {
1296 int r;
1297
1298 assert(f);
1299 assert(v);
1300
1301 switch (json_variant_type(v)) {
1302
1303 case JSON_VARIANT_REAL: {
1304 locale_t loc;
1305
1306 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
1307 if (loc == (locale_t) 0)
1308 return -errno;
1309
1310 if (flags & JSON_FORMAT_COLOR)
1311 fputs(ANSI_HIGHLIGHT_BLUE, f);
1312
1313 fprintf(f, "%.*Le", DECIMAL_DIG, json_variant_real(v));
1314
1315 if (flags & JSON_FORMAT_COLOR)
1316 fputs(ANSI_NORMAL, f);
1317
1318 freelocale(loc);
1319 break;
1320 }
1321
1322 case JSON_VARIANT_INTEGER:
1323 if (flags & JSON_FORMAT_COLOR)
1324 fputs(ANSI_HIGHLIGHT_BLUE, f);
1325
1326 fprintf(f, "%" PRIdMAX, json_variant_integer(v));
1327
1328 if (flags & JSON_FORMAT_COLOR)
1329 fputs(ANSI_NORMAL, f);
1330 break;
1331
1332 case JSON_VARIANT_UNSIGNED:
1333 if (flags & JSON_FORMAT_COLOR)
1334 fputs(ANSI_HIGHLIGHT_BLUE, f);
1335
1336 fprintf(f, "%" PRIuMAX, json_variant_unsigned(v));
1337
1338 if (flags & JSON_FORMAT_COLOR)
1339 fputs(ANSI_NORMAL, f);
1340 break;
1341
1342 case JSON_VARIANT_BOOLEAN:
1343
1344 if (flags & JSON_FORMAT_COLOR)
1345 fputs(ANSI_HIGHLIGHT, f);
1346
1347 if (json_variant_boolean(v))
1348 fputs("true", f);
1349 else
1350 fputs("false", f);
1351
1352 if (flags & JSON_FORMAT_COLOR)
1353 fputs(ANSI_NORMAL, f);
1354
1355 break;
1356
1357 case JSON_VARIANT_NULL:
1358 if (flags & JSON_FORMAT_COLOR)
1359 fputs(ANSI_HIGHLIGHT, f);
1360
1361 fputs("null", f);
1362
1363 if (flags & JSON_FORMAT_COLOR)
1364 fputs(ANSI_NORMAL, f);
1365 break;
1366
1367 case JSON_VARIANT_STRING: {
1368 const char *q;
1369
1370 fputc('"', f);
1371
1372 if (flags & JSON_FORMAT_COLOR)
1373 fputs(ANSI_GREEN, f);
1374
1375 for (q = json_variant_string(v); *q; q++) {
1376
1377 switch (*q) {
1378
1379 case '"':
1380 fputs("\\\"", f);
1381 break;
1382
1383 case '\\':
1384 fputs("\\\\", f);
1385 break;
1386
1387 case '\b':
1388 fputs("\\b", f);
1389 break;
1390
1391 case '\f':
1392 fputs("\\f", f);
1393 break;
1394
1395 case '\n':
1396 fputs("\\n", f);
1397 break;
1398
1399 case '\r':
1400 fputs("\\r", f);
1401 break;
1402
1403 case '\t':
1404 fputs("\\t", f);
1405 break;
1406
1407 default:
1408 if ((signed char) *q >= 0 && *q < ' ')
1409 fprintf(f, "\\u%04x", *q);
1410 else
1411 fputc(*q, f);
1412 break;
1413 }
1414 }
1415
1416 if (flags & JSON_FORMAT_COLOR)
1417 fputs(ANSI_NORMAL, f);
1418
1419 fputc('"', f);
1420 break;
1421 }
1422
1423 case JSON_VARIANT_ARRAY: {
1424 size_t i, n;
1425
1426 n = json_variant_elements(v);
1427
1428 if (n == 0)
1429 fputs("[]", f);
1430 else {
1431 _cleanup_free_ char *joined = NULL;
1432 const char *prefix2;
1433
1434 if (flags & JSON_FORMAT_PRETTY) {
1435 joined = strjoin(strempty(prefix), "\t");
1436 if (!joined)
1437 return -ENOMEM;
1438
1439 prefix2 = joined;
1440 fputs("[\n", f);
1441 } else {
1442 prefix2 = strempty(prefix);
1443 fputc('[', f);
1444 }
1445
1446 for (i = 0; i < n; i++) {
1447 JsonVariant *e;
1448
1449 assert_se(e = json_variant_by_index(v, i));
1450
1451 if (i > 0) {
1452 if (flags & JSON_FORMAT_PRETTY)
1453 fputs(",\n", f);
1454 else
1455 fputc(',', f);
1456 }
1457
1458 if (flags & JSON_FORMAT_PRETTY) {
1459 print_source(f, e, flags, false);
1460 fputs(prefix2, f);
1461 }
1462
1463 r = json_format(f, e, flags, prefix2);
1464 if (r < 0)
1465 return r;
1466 }
1467
1468 if (flags & JSON_FORMAT_PRETTY) {
1469 fputc('\n', f);
1470 print_source(f, v, flags, true);
1471 fputs(strempty(prefix), f);
1472 }
1473
1474 fputc(']', f);
1475 }
1476 break;
1477 }
1478
1479 case JSON_VARIANT_OBJECT: {
1480 size_t i, n;
1481
1482 n = json_variant_elements(v);
1483
1484 if (n == 0)
1485 fputs("{}", f);
1486 else {
1487 _cleanup_free_ char *joined = NULL;
1488 const char *prefix2;
1489
1490 if (flags & JSON_FORMAT_PRETTY) {
1491 joined = strjoin(strempty(prefix), "\t");
1492 if (!joined)
1493 return -ENOMEM;
1494
1495 prefix2 = joined;
1496 fputs("{\n", f);
1497 } else {
1498 prefix2 = strempty(prefix);
1499 fputc('{', f);
1500 }
1501
1502 for (i = 0; i < n; i += 2) {
1503 JsonVariant *e;
1504
1505 e = json_variant_by_index(v, i);
1506
1507 if (i > 0) {
1508 if (flags & JSON_FORMAT_PRETTY)
1509 fputs(",\n", f);
1510 else
1511 fputc(',', f);
1512 }
1513
1514 if (flags & JSON_FORMAT_PRETTY) {
1515 print_source(f, e, flags, false);
1516 fputs(prefix2, f);
1517 }
1518
1519 r = json_format(f, e, flags, prefix2);
1520 if (r < 0)
1521 return r;
1522
1523 fputs(flags & JSON_FORMAT_PRETTY ? " : " : ":", f);
1524
1525 r = json_format(f, json_variant_by_index(v, i+1), flags, prefix2);
1526 if (r < 0)
1527 return r;
1528 }
1529
1530 if (flags & JSON_FORMAT_PRETTY) {
1531 fputc('\n', f);
1532 print_source(f, v, flags, true);
1533 fputs(strempty(prefix), f);
1534 }
1535
1536 fputc('}', f);
1537 }
1538 break;
1539 }
1540
1541 default:
1542 assert_not_reached("Unexpected variant type.");
1543 }
1544
1545 return 0;
1546 }
1547
1548 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
1549 _cleanup_free_ char *s = NULL;
1550 size_t sz = 0;
1551 int r;
1552
1553 assert_return(v, -EINVAL);
1554 assert_return(ret, -EINVAL);
1555
1556 {
1557 _cleanup_fclose_ FILE *f = NULL;
1558
1559 f = open_memstream(&s, &sz);
1560 if (!f)
1561 return -ENOMEM;
1562
1563 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
1564
1565 json_variant_dump(v, flags, f, NULL);
1566
1567 r = fflush_and_check(f);
1568 }
1569 if (r < 0)
1570 return r;
1571
1572 assert(s);
1573 *ret = TAKE_PTR(s);
1574
1575 return (int) sz;
1576 }
1577
1578 void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) {
1579 if (!v)
1580 return;
1581
1582 if (!f)
1583 f = stdout;
1584
1585 print_source(f, v, flags, false);
1586
1587 if (((flags & (JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_COLOR)) == JSON_FORMAT_COLOR_AUTO) && colors_enabled())
1588 flags |= JSON_FORMAT_COLOR;
1589
1590 if (flags & JSON_FORMAT_SSE)
1591 fputs("data: ", f);
1592 if (flags & JSON_FORMAT_SEQ)
1593 fputc('\x1e', f); /* ASCII Record Separator */
1594
1595 json_format(f, v, flags, prefix);
1596
1597 if (flags & (JSON_FORMAT_PRETTY|JSON_FORMAT_SEQ|JSON_FORMAT_SSE|JSON_FORMAT_NEWLINE))
1598 fputc('\n', f);
1599 if (flags & JSON_FORMAT_SSE)
1600 fputc('\n', f); /* In case of SSE add a second newline */
1601 }
1602
1603 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
1604 JsonVariantType t;
1605 JsonVariant *c;
1606 JsonValue value;
1607 const void *source;
1608 size_t k;
1609
1610 assert(nv);
1611 assert(v);
1612
1613 /* Let's copy the simple types literally, and the larger types by references */
1614 t = json_variant_type(v);
1615 switch (t) {
1616 case JSON_VARIANT_INTEGER:
1617 k = sizeof(intmax_t);
1618 value.integer = json_variant_integer(v);
1619 source = &value;
1620 break;
1621
1622 case JSON_VARIANT_UNSIGNED:
1623 k = sizeof(uintmax_t);
1624 value.unsig = json_variant_unsigned(v);
1625 source = &value;
1626 break;
1627
1628 case JSON_VARIANT_REAL:
1629 k = sizeof(long double);
1630 value.real = json_variant_real(v);
1631 source = &value;
1632 break;
1633
1634 case JSON_VARIANT_BOOLEAN:
1635 k = sizeof(bool);
1636 value.boolean = json_variant_boolean(v);
1637 source = &value;
1638 break;
1639
1640 case JSON_VARIANT_NULL:
1641 k = 0;
1642 source = NULL;
1643 break;
1644
1645 case JSON_VARIANT_STRING:
1646 source = json_variant_string(v);
1647 k = strnlen(source, INLINE_STRING_MAX + 1);
1648 if (k <= INLINE_STRING_MAX) {
1649 k ++;
1650 break;
1651 }
1652
1653 _fallthrough_;
1654
1655 default:
1656 /* Everything else copy by reference */
1657
1658 c = malloc0(offsetof(JsonVariant, reference) + sizeof(JsonVariant*));
1659 if (!c)
1660 return -ENOMEM;
1661
1662 c->n_ref = 1;
1663 c->type = t;
1664 c->is_reference = true;
1665 c->reference = json_variant_ref(json_variant_normalize(v));
1666
1667 *nv = c;
1668 return 0;
1669 }
1670
1671 c = malloc0(offsetof(JsonVariant, value) + k);
1672 if (!c)
1673 return -ENOMEM;
1674
1675 c->n_ref = 1;
1676 c->type = t;
1677
1678 memcpy_safe(&c->value, source, k);
1679
1680 *nv = c;
1681 return 0;
1682 }
1683
1684 static bool json_single_ref(JsonVariant *v) {
1685
1686 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
1687
1688 if (!json_variant_is_regular(v))
1689 return false;
1690
1691 if (v->is_embedded)
1692 return json_single_ref(v->parent);
1693
1694 assert(v->n_ref > 0);
1695 return v->n_ref == 1;
1696 }
1697
1698 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
1699 JsonVariant *w;
1700 int r;
1701
1702 assert(v);
1703
1704 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole referencer of
1705 * the object. If not, allocates a new object, possibly a surrogate for the original one */
1706
1707 if (!*v)
1708 return 0;
1709
1710 if (source && line > source->max_line)
1711 source->max_line = line;
1712 if (source && column > source->max_column)
1713 source->max_column = column;
1714
1715 if (!json_variant_is_regular(*v)) {
1716
1717 if (!source && line == 0 && column == 0)
1718 return 0;
1719
1720 } else {
1721 if (json_source_equal((*v)->source, source) &&
1722 (*v)->line == line &&
1723 (*v)->column == column)
1724 return 0;
1725
1726 if (json_single_ref(*v)) { /* Sole reference? */
1727 json_source_unref((*v)->source);
1728 (*v)->source = json_source_ref(source);
1729 (*v)->line = line;
1730 (*v)->column = column;
1731 return 1;
1732 }
1733 }
1734
1735 r = json_variant_copy(&w, *v);
1736 if (r < 0)
1737 return r;
1738
1739 assert(json_variant_is_regular(w));
1740 assert(!w->is_embedded);
1741 assert(w->n_ref == 1);
1742 assert(!w->source);
1743
1744 w->source = json_source_ref(source);
1745 w->line = line;
1746 w->column = column;
1747
1748 json_variant_unref(*v);
1749 *v = w;
1750
1751 return 1;
1752 }
1753
1754 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
1755 assert(line);
1756 assert(column);
1757 assert(s || n == 0);
1758
1759 while (n > 0) {
1760 if (*s == '\n') {
1761 (*line)++;
1762 *column = 1;
1763 } else if ((signed char) *s >= 0 && *s < 127) /* Process ASCII chars quickly */
1764 (*column)++;
1765 else {
1766 int w;
1767
1768 w = utf8_encoded_valid_unichar(s, n);
1769 if (w < 0) /* count invalid unichars as normal characters */
1770 w = 1;
1771 else if ((size_t) w > n) /* never read more than the specified number of characters */
1772 w = (int) n;
1773
1774 (*column)++;
1775
1776 s += w;
1777 n -= w;
1778 continue;
1779 }
1780
1781 s++;
1782 n--;
1783 }
1784 }
1785
1786 static int unhex_ucs2(const char *c, uint16_t *ret) {
1787 int aa, bb, cc, dd;
1788 uint16_t x;
1789
1790 assert(c);
1791 assert(ret);
1792
1793 aa = unhexchar(c[0]);
1794 if (aa < 0)
1795 return -EINVAL;
1796
1797 bb = unhexchar(c[1]);
1798 if (bb < 0)
1799 return -EINVAL;
1800
1801 cc = unhexchar(c[2]);
1802 if (cc < 0)
1803 return -EINVAL;
1804
1805 dd = unhexchar(c[3]);
1806 if (dd < 0)
1807 return -EINVAL;
1808
1809 x = ((uint16_t) aa << 12) |
1810 ((uint16_t) bb << 8) |
1811 ((uint16_t) cc << 4) |
1812 ((uint16_t) dd);
1813
1814 if (x <= 0)
1815 return -EINVAL;
1816
1817 *ret = x;
1818
1819 return 0;
1820 }
1821
1822 static int json_parse_string(const char **p, char **ret) {
1823 _cleanup_free_ char *s = NULL;
1824 size_t n = 0, allocated = 0;
1825 const char *c;
1826
1827 assert(p);
1828 assert(*p);
1829 assert(ret);
1830
1831 c = *p;
1832
1833 if (*c != '"')
1834 return -EINVAL;
1835
1836 c++;
1837
1838 for (;;) {
1839 int len;
1840
1841 /* Check for EOF */
1842 if (*c == 0)
1843 return -EINVAL;
1844
1845 /* Check for control characters 0x00..0x1f */
1846 if (*c > 0 && *c < ' ')
1847 return -EINVAL;
1848
1849 /* Check for control character 0x7f */
1850 if (*c == 0x7f)
1851 return -EINVAL;
1852
1853 if (*c == '"') {
1854 if (!s) {
1855 s = strdup("");
1856 if (!s)
1857 return -ENOMEM;
1858 } else
1859 s[n] = 0;
1860
1861 *p = c + 1;
1862
1863 *ret = TAKE_PTR(s);
1864 return JSON_TOKEN_STRING;
1865 }
1866
1867 if (*c == '\\') {
1868 char ch = 0;
1869 c++;
1870
1871 if (*c == 0)
1872 return -EINVAL;
1873
1874 if (IN_SET(*c, '"', '\\', '/'))
1875 ch = *c;
1876 else if (*c == 'b')
1877 ch = '\b';
1878 else if (*c == 'f')
1879 ch = '\f';
1880 else if (*c == 'n')
1881 ch = '\n';
1882 else if (*c == 'r')
1883 ch = '\r';
1884 else if (*c == 't')
1885 ch = '\t';
1886 else if (*c == 'u') {
1887 char16_t x;
1888 int r;
1889
1890 r = unhex_ucs2(c + 1, &x);
1891 if (r < 0)
1892 return r;
1893
1894 c += 5;
1895
1896 if (!GREEDY_REALLOC(s, allocated, n + 5))
1897 return -ENOMEM;
1898
1899 if (!utf16_is_surrogate(x))
1900 n += utf8_encode_unichar(s + n, (char32_t) x);
1901 else if (utf16_is_trailing_surrogate(x))
1902 return -EINVAL;
1903 else {
1904 char16_t y;
1905
1906 if (c[0] != '\\' || c[1] != 'u')
1907 return -EINVAL;
1908
1909 r = unhex_ucs2(c + 2, &y);
1910 if (r < 0)
1911 return r;
1912
1913 c += 6;
1914
1915 if (!utf16_is_trailing_surrogate(y))
1916 return -EINVAL;
1917
1918 n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
1919 }
1920
1921 continue;
1922 } else
1923 return -EINVAL;
1924
1925 if (!GREEDY_REALLOC(s, allocated, n + 2))
1926 return -ENOMEM;
1927
1928 s[n++] = ch;
1929 c ++;
1930 continue;
1931 }
1932
1933 len = utf8_encoded_valid_unichar(c, (size_t) -1);
1934 if (len < 0)
1935 return len;
1936
1937 if (!GREEDY_REALLOC(s, allocated, n + len + 1))
1938 return -ENOMEM;
1939
1940 memcpy(s + n, c, len);
1941 n += len;
1942 c += len;
1943 }
1944 }
1945
1946 static int json_parse_number(const char **p, JsonValue *ret) {
1947 bool negative = false, exponent_negative = false, is_real = false;
1948 long double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
1949 intmax_t i = 0;
1950 uintmax_t u = 0;
1951 const char *c;
1952
1953 assert(p);
1954 assert(*p);
1955 assert(ret);
1956
1957 c = *p;
1958
1959 if (*c == '-') {
1960 negative = true;
1961 c++;
1962 }
1963
1964 if (*c == '0')
1965 c++;
1966 else {
1967 if (!strchr("123456789", *c) || *c == 0)
1968 return -EINVAL;
1969
1970 do {
1971 if (!is_real) {
1972 if (negative) {
1973
1974 if (i < INTMAX_MIN / 10) /* overflow */
1975 is_real = true;
1976 else {
1977 intmax_t t = 10 * i;
1978
1979 if (t < INTMAX_MIN + (*c - '0')) /* overflow */
1980 is_real = true;
1981 else
1982 i = t - (*c - '0');
1983 }
1984 } else {
1985 if (u > UINTMAX_MAX / 10) /* overflow */
1986 is_real = true;
1987 else {
1988 uintmax_t t = 10 * u;
1989
1990 if (t > UINTMAX_MAX - (*c - '0')) /* overflow */
1991 is_real = true;
1992 else
1993 u = t + (*c - '0');
1994 }
1995 }
1996 }
1997
1998 x = 10.0 * x + (*c - '0');
1999
2000 c++;
2001 } while (strchr("0123456789", *c) && *c != 0);
2002 }
2003
2004 if (*c == '.') {
2005 is_real = true;
2006 c++;
2007
2008 if (!strchr("0123456789", *c) || *c == 0)
2009 return -EINVAL;
2010
2011 do {
2012 y = 10.0 * y + (*c - '0');
2013 shift = 10.0 * shift;
2014 c++;
2015 } while (strchr("0123456789", *c) && *c != 0);
2016 }
2017
2018 if (IN_SET(*c, 'e', 'E')) {
2019 is_real = true;
2020 c++;
2021
2022 if (*c == '-') {
2023 exponent_negative = true;
2024 c++;
2025 } else if (*c == '+')
2026 c++;
2027
2028 if (!strchr("0123456789", *c) || *c == 0)
2029 return -EINVAL;
2030
2031 do {
2032 exponent = 10.0 * exponent + (*c - '0');
2033 c++;
2034 } while (strchr("0123456789", *c) && *c != 0);
2035 }
2036
2037 *p = c;
2038
2039 if (is_real) {
2040 ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10l((exponent_negative ? -1.0 : 1.0) * exponent);
2041 return JSON_TOKEN_REAL;
2042 } else if (negative) {
2043 ret->integer = i;
2044 return JSON_TOKEN_INTEGER;
2045 } else {
2046 ret->unsig = u;
2047 return JSON_TOKEN_UNSIGNED;
2048 }
2049 }
2050
2051 int json_tokenize(
2052 const char **p,
2053 char **ret_string,
2054 JsonValue *ret_value,
2055 unsigned *ret_line, /* 'ret_line' returns the line at the beginning of this token */
2056 unsigned *ret_column,
2057 void **state,
2058 unsigned *line, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2059 unsigned *column) {
2060
2061 unsigned start_line, start_column;
2062 const char *start, *c;
2063 size_t n;
2064 int t, r;
2065
2066 enum {
2067 STATE_NULL,
2068 STATE_VALUE,
2069 STATE_VALUE_POST,
2070 };
2071
2072 assert(p);
2073 assert(*p);
2074 assert(ret_string);
2075 assert(ret_value);
2076 assert(ret_line);
2077 assert(ret_column);
2078 assert(line);
2079 assert(column);
2080 assert(state);
2081
2082 t = PTR_TO_INT(*state);
2083 if (t == STATE_NULL) {
2084 *line = 1;
2085 *column = 1;
2086 t = STATE_VALUE;
2087 }
2088
2089 /* Skip over the whitespace */
2090 n = strspn(*p, WHITESPACE);
2091 inc_lines_columns(line, column, *p, n);
2092 c = *p + n;
2093
2094 /* Remember where we started processing this token */
2095 start = c;
2096 start_line = *line;
2097 start_column = *column;
2098
2099 if (*c == 0) {
2100 *ret_string = NULL;
2101 *ret_value = JSON_VALUE_NULL;
2102 r = JSON_TOKEN_END;
2103 goto finish;
2104 }
2105
2106 switch (t) {
2107
2108 case STATE_VALUE:
2109
2110 if (*c == '{') {
2111 c++;
2112 *state = INT_TO_PTR(STATE_VALUE);
2113 r = JSON_TOKEN_OBJECT_OPEN;
2114 goto null_return;
2115
2116 } else if (*c == '}') {
2117 c++;
2118 *state = INT_TO_PTR(STATE_VALUE_POST);
2119 r = JSON_TOKEN_OBJECT_CLOSE;
2120 goto null_return;
2121
2122 } else if (*c == '[') {
2123 c++;
2124 *state = INT_TO_PTR(STATE_VALUE);
2125 r = JSON_TOKEN_ARRAY_OPEN;
2126 goto null_return;
2127
2128 } else if (*c == ']') {
2129 c++;
2130 *state = INT_TO_PTR(STATE_VALUE_POST);
2131 r = JSON_TOKEN_ARRAY_CLOSE;
2132 goto null_return;
2133
2134 } else if (*c == '"') {
2135
2136 r = json_parse_string(&c, ret_string);
2137 if (r < 0)
2138 return r;
2139
2140 *ret_value = JSON_VALUE_NULL;
2141 *state = INT_TO_PTR(STATE_VALUE_POST);
2142 goto finish;
2143
2144 } else if (strchr("-0123456789", *c)) {
2145
2146 r = json_parse_number(&c, ret_value);
2147 if (r < 0)
2148 return r;
2149
2150 *ret_string = NULL;
2151 *state = INT_TO_PTR(STATE_VALUE_POST);
2152 goto finish;
2153
2154 } else if (startswith(c, "true")) {
2155 *ret_string = NULL;
2156 ret_value->boolean = true;
2157 c += 4;
2158 *state = INT_TO_PTR(STATE_VALUE_POST);
2159 r = JSON_TOKEN_BOOLEAN;
2160 goto finish;
2161
2162 } else if (startswith(c, "false")) {
2163 *ret_string = NULL;
2164 ret_value->boolean = false;
2165 c += 5;
2166 *state = INT_TO_PTR(STATE_VALUE_POST);
2167 r = JSON_TOKEN_BOOLEAN;
2168 goto finish;
2169
2170 } else if (startswith(c, "null")) {
2171 *ret_string = NULL;
2172 *ret_value = JSON_VALUE_NULL;
2173 c += 4;
2174 *state = INT_TO_PTR(STATE_VALUE_POST);
2175 r = JSON_TOKEN_NULL;
2176 goto finish;
2177
2178 }
2179
2180 return -EINVAL;
2181
2182 case STATE_VALUE_POST:
2183
2184 if (*c == ':') {
2185 c++;
2186 *state = INT_TO_PTR(STATE_VALUE);
2187 r = JSON_TOKEN_COLON;
2188 goto null_return;
2189
2190 } else if (*c == ',') {
2191 c++;
2192 *state = INT_TO_PTR(STATE_VALUE);
2193 r = JSON_TOKEN_COMMA;
2194 goto null_return;
2195
2196 } else if (*c == '}') {
2197 c++;
2198 *state = INT_TO_PTR(STATE_VALUE_POST);
2199 r = JSON_TOKEN_OBJECT_CLOSE;
2200 goto null_return;
2201
2202 } else if (*c == ']') {
2203 c++;
2204 *state = INT_TO_PTR(STATE_VALUE_POST);
2205 r = JSON_TOKEN_ARRAY_CLOSE;
2206 goto null_return;
2207 }
2208
2209 return -EINVAL;
2210
2211 default:
2212 assert_not_reached("Unexpected tokenizer state");
2213 }
2214
2215 null_return:
2216 *ret_string = NULL;
2217 *ret_value = JSON_VALUE_NULL;
2218
2219 finish:
2220 inc_lines_columns(line, column, start, c - start);
2221 *p = c;
2222
2223 *ret_line = start_line;
2224 *ret_column = start_column;
2225
2226 return r;
2227 }
2228
2229 typedef enum JsonExpect {
2230 /* The following values are used by json_parse() */
2231 EXPECT_TOPLEVEL,
2232 EXPECT_END,
2233 EXPECT_OBJECT_FIRST_KEY,
2234 EXPECT_OBJECT_NEXT_KEY,
2235 EXPECT_OBJECT_COLON,
2236 EXPECT_OBJECT_VALUE,
2237 EXPECT_OBJECT_COMMA,
2238 EXPECT_ARRAY_FIRST_ELEMENT,
2239 EXPECT_ARRAY_NEXT_ELEMENT,
2240 EXPECT_ARRAY_COMMA,
2241
2242 /* And these are used by json_build() */
2243 EXPECT_ARRAY_ELEMENT,
2244 EXPECT_OBJECT_KEY,
2245 } JsonExpect;
2246
2247 typedef struct JsonStack {
2248 JsonExpect expect;
2249 JsonVariant **elements;
2250 size_t n_elements, n_elements_allocated;
2251 unsigned line_before;
2252 unsigned column_before;
2253 size_t n_suppress; /* When building: if > 0, suppress this many subsequent elements. If == (size_t) -1, suppress all subsequent elements */
2254 } JsonStack;
2255
2256 static void json_stack_release(JsonStack *s) {
2257 assert(s);
2258
2259 json_variant_unref_many(s->elements, s->n_elements);
2260 s->elements = mfree(s->elements);
2261 }
2262
2263 static int json_parse_internal(
2264 const char **input,
2265 JsonSource *source,
2266 JsonVariant **ret,
2267 unsigned *line,
2268 unsigned *column,
2269 bool continue_end) {
2270
2271 size_t n_stack = 1, n_stack_allocated = 0, i;
2272 unsigned line_buffer = 0, column_buffer = 0;
2273 void *tokenizer_state = NULL;
2274 JsonStack *stack = NULL;
2275 const char *p;
2276 int r;
2277
2278 assert_return(input, -EINVAL);
2279 assert_return(ret, -EINVAL);
2280
2281 p = *input;
2282
2283 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack))
2284 return -ENOMEM;
2285
2286 stack[0] = (JsonStack) {
2287 .expect = EXPECT_TOPLEVEL,
2288 };
2289
2290 if (!line)
2291 line = &line_buffer;
2292 if (!column)
2293 column = &column_buffer;
2294
2295 for (;;) {
2296 _cleanup_free_ char *string = NULL;
2297 unsigned line_token, column_token;
2298 JsonVariant *add = NULL;
2299 JsonStack *current;
2300 JsonValue value;
2301 int token;
2302
2303 assert(n_stack > 0);
2304 current = stack + n_stack - 1;
2305
2306 if (continue_end && current->expect == EXPECT_END)
2307 goto done;
2308
2309 token = json_tokenize(&p, &string, &value, &line_token, &column_token, &tokenizer_state, line, column);
2310 if (token < 0) {
2311 r = token;
2312 goto finish;
2313 }
2314
2315 switch (token) {
2316
2317 case JSON_TOKEN_END:
2318 if (current->expect != EXPECT_END) {
2319 r = -EINVAL;
2320 goto finish;
2321 }
2322
2323 assert(current->n_elements == 1);
2324 assert(n_stack == 1);
2325 goto done;
2326
2327 case JSON_TOKEN_COLON:
2328
2329 if (current->expect != EXPECT_OBJECT_COLON) {
2330 r = -EINVAL;
2331 goto finish;
2332 }
2333
2334 current->expect = EXPECT_OBJECT_VALUE;
2335 break;
2336
2337 case JSON_TOKEN_COMMA:
2338
2339 if (current->expect == EXPECT_OBJECT_COMMA)
2340 current->expect = EXPECT_OBJECT_NEXT_KEY;
2341 else if (current->expect == EXPECT_ARRAY_COMMA)
2342 current->expect = EXPECT_ARRAY_NEXT_ELEMENT;
2343 else {
2344 r = -EINVAL;
2345 goto finish;
2346 }
2347
2348 break;
2349
2350 case JSON_TOKEN_OBJECT_OPEN:
2351
2352 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2353 r = -EINVAL;
2354 goto finish;
2355 }
2356
2357 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2358 r = -ENOMEM;
2359 goto finish;
2360 }
2361 current = stack + n_stack - 1;
2362
2363 /* Prepare the expect for when we return from the child */
2364 if (current->expect == EXPECT_TOPLEVEL)
2365 current->expect = EXPECT_END;
2366 else if (current->expect == EXPECT_OBJECT_VALUE)
2367 current->expect = EXPECT_OBJECT_COMMA;
2368 else {
2369 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2370 current->expect = EXPECT_ARRAY_COMMA;
2371 }
2372
2373 stack[n_stack++] = (JsonStack) {
2374 .expect = EXPECT_OBJECT_FIRST_KEY,
2375 .line_before = line_token,
2376 .column_before = column_token,
2377 };
2378
2379 current = stack + n_stack - 1;
2380 break;
2381
2382 case JSON_TOKEN_OBJECT_CLOSE:
2383 if (!IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_COMMA)) {
2384 r = -EINVAL;
2385 goto finish;
2386 }
2387
2388 assert(n_stack > 1);
2389
2390 r = json_variant_new_object(&add, current->elements, current->n_elements);
2391 if (r < 0)
2392 goto finish;
2393
2394 line_token = current->line_before;
2395 column_token = current->column_before;
2396
2397 json_stack_release(current);
2398 n_stack--, current--;
2399
2400 break;
2401
2402 case JSON_TOKEN_ARRAY_OPEN:
2403 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2404 r = -EINVAL;
2405 goto finish;
2406 }
2407
2408 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2409 r = -ENOMEM;
2410 goto finish;
2411 }
2412 current = stack + n_stack - 1;
2413
2414 /* Prepare the expect for when we return from the child */
2415 if (current->expect == EXPECT_TOPLEVEL)
2416 current->expect = EXPECT_END;
2417 else if (current->expect == EXPECT_OBJECT_VALUE)
2418 current->expect = EXPECT_OBJECT_COMMA;
2419 else {
2420 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2421 current->expect = EXPECT_ARRAY_COMMA;
2422 }
2423
2424 stack[n_stack++] = (JsonStack) {
2425 .expect = EXPECT_ARRAY_FIRST_ELEMENT,
2426 .line_before = line_token,
2427 .column_before = column_token,
2428 };
2429
2430 break;
2431
2432 case JSON_TOKEN_ARRAY_CLOSE:
2433 if (!IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_COMMA)) {
2434 r = -EINVAL;
2435 goto finish;
2436 }
2437
2438 assert(n_stack > 1);
2439
2440 r = json_variant_new_array(&add, current->elements, current->n_elements);
2441 if (r < 0)
2442 goto finish;
2443
2444 line_token = current->line_before;
2445 column_token = current->column_before;
2446
2447 json_stack_release(current);
2448 n_stack--, current--;
2449 break;
2450
2451 case JSON_TOKEN_STRING:
2452 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)) {
2453 r = -EINVAL;
2454 goto finish;
2455 }
2456
2457 r = json_variant_new_string(&add, string);
2458 if (r < 0)
2459 goto finish;
2460
2461 if (current->expect == EXPECT_TOPLEVEL)
2462 current->expect = EXPECT_END;
2463 else if (IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_NEXT_KEY))
2464 current->expect = EXPECT_OBJECT_COLON;
2465 else if (current->expect == EXPECT_OBJECT_VALUE)
2466 current->expect = EXPECT_OBJECT_COMMA;
2467 else {
2468 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2469 current->expect = EXPECT_ARRAY_COMMA;
2470 }
2471
2472 break;
2473
2474 case JSON_TOKEN_REAL:
2475 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2476 r = -EINVAL;
2477 goto finish;
2478 }
2479
2480 r = json_variant_new_real(&add, value.real);
2481 if (r < 0)
2482 goto finish;
2483
2484 if (current->expect == EXPECT_TOPLEVEL)
2485 current->expect = EXPECT_END;
2486 else if (current->expect == EXPECT_OBJECT_VALUE)
2487 current->expect = EXPECT_OBJECT_COMMA;
2488 else {
2489 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2490 current->expect = EXPECT_ARRAY_COMMA;
2491 }
2492
2493 break;
2494
2495 case JSON_TOKEN_INTEGER:
2496 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2497 r = -EINVAL;
2498 goto finish;
2499 }
2500
2501 r = json_variant_new_integer(&add, value.integer);
2502 if (r < 0)
2503 goto finish;
2504
2505 if (current->expect == EXPECT_TOPLEVEL)
2506 current->expect = EXPECT_END;
2507 else if (current->expect == EXPECT_OBJECT_VALUE)
2508 current->expect = EXPECT_OBJECT_COMMA;
2509 else {
2510 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2511 current->expect = EXPECT_ARRAY_COMMA;
2512 }
2513
2514 break;
2515
2516 case JSON_TOKEN_UNSIGNED:
2517 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2518 r = -EINVAL;
2519 goto finish;
2520 }
2521
2522 r = json_variant_new_unsigned(&add, value.unsig);
2523 if (r < 0)
2524 goto finish;
2525
2526 if (current->expect == EXPECT_TOPLEVEL)
2527 current->expect = EXPECT_END;
2528 else if (current->expect == EXPECT_OBJECT_VALUE)
2529 current->expect = EXPECT_OBJECT_COMMA;
2530 else {
2531 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2532 current->expect = EXPECT_ARRAY_COMMA;
2533 }
2534
2535 break;
2536
2537 case JSON_TOKEN_BOOLEAN:
2538 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2539 r = -EINVAL;
2540 goto finish;
2541 }
2542
2543 r = json_variant_new_boolean(&add, value.boolean);
2544 if (r < 0)
2545 goto finish;
2546
2547 if (current->expect == EXPECT_TOPLEVEL)
2548 current->expect = EXPECT_END;
2549 else if (current->expect == EXPECT_OBJECT_VALUE)
2550 current->expect = EXPECT_OBJECT_COMMA;
2551 else {
2552 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2553 current->expect = EXPECT_ARRAY_COMMA;
2554 }
2555
2556 break;
2557
2558 case JSON_TOKEN_NULL:
2559 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2560 r = -EINVAL;
2561 goto finish;
2562 }
2563
2564 r = json_variant_new_null(&add);
2565 if (r < 0)
2566 goto finish;
2567
2568 if (current->expect == EXPECT_TOPLEVEL)
2569 current->expect = EXPECT_END;
2570 else if (current->expect == EXPECT_OBJECT_VALUE)
2571 current->expect = EXPECT_OBJECT_COMMA;
2572 else {
2573 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2574 current->expect = EXPECT_ARRAY_COMMA;
2575 }
2576
2577 break;
2578
2579 default:
2580 assert_not_reached("Unexpected token");
2581 }
2582
2583 if (add) {
2584 (void) json_variant_set_source(&add, source, line_token, column_token);
2585
2586 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
2587 r = -ENOMEM;
2588 goto finish;
2589 }
2590
2591 current->elements[current->n_elements++] = add;
2592 }
2593 }
2594
2595 done:
2596 assert(n_stack == 1);
2597 assert(stack[0].n_elements == 1);
2598
2599 *ret = json_variant_ref(stack[0].elements[0]);
2600 *input = p;
2601 r = 0;
2602
2603 finish:
2604 for (i = 0; i < n_stack; i++)
2605 json_stack_release(stack + i);
2606
2607 free(stack);
2608
2609 return r;
2610 }
2611
2612 int json_parse(const char *input, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
2613 return json_parse_internal(&input, NULL, ret, ret_line, ret_column, false);
2614 }
2615
2616 int json_parse_continue(const char **p, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
2617 return json_parse_internal(p, NULL, ret, ret_line, ret_column, true);
2618 }
2619
2620 int json_parse_file(FILE *f, const char *path, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
2621 _cleanup_(json_source_unrefp) JsonSource *source = NULL;
2622 _cleanup_free_ char *text = NULL;
2623 const char *p;
2624 int r;
2625
2626 if (f)
2627 r = read_full_stream(f, &text, NULL);
2628 else if (path)
2629 r = read_full_file(path, &text, NULL);
2630 else
2631 return -EINVAL;
2632 if (r < 0)
2633 return r;
2634
2635 if (path) {
2636 source = json_source_new(path);
2637 if (!source)
2638 return -ENOMEM;
2639 }
2640
2641 p = text;
2642 return json_parse_internal(&p, source, ret, ret_line, ret_column, false);
2643 }
2644
2645 int json_buildv(JsonVariant **ret, va_list ap) {
2646 JsonStack *stack = NULL;
2647 size_t n_stack = 1, n_stack_allocated = 0, i;
2648 int r;
2649
2650 assert_return(ret, -EINVAL);
2651
2652 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack))
2653 return -ENOMEM;
2654
2655 stack[0] = (JsonStack) {
2656 .expect = EXPECT_TOPLEVEL,
2657 };
2658
2659 for (;;) {
2660 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL;
2661 size_t n_subtract = 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
2662 * have been added to the current variant */
2663 JsonStack *current;
2664 int command;
2665
2666 assert(n_stack > 0);
2667 current = stack + n_stack - 1;
2668
2669 if (current->expect == EXPECT_END)
2670 goto done;
2671
2672 command = va_arg(ap, int);
2673
2674 switch (command) {
2675
2676 case _JSON_BUILD_STRING: {
2677 const char *p;
2678
2679 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2680 r = -EINVAL;
2681 goto finish;
2682 }
2683
2684 p = va_arg(ap, const char *);
2685
2686 if (current->n_suppress == 0) {
2687 r = json_variant_new_string(&add, p);
2688 if (r < 0)
2689 goto finish;
2690 }
2691
2692 n_subtract = 1;
2693
2694 if (current->expect == EXPECT_TOPLEVEL)
2695 current->expect = EXPECT_END;
2696 else if (current->expect == EXPECT_OBJECT_VALUE)
2697 current->expect = EXPECT_OBJECT_KEY;
2698 else
2699 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2700
2701 break;
2702 }
2703
2704 case _JSON_BUILD_INTEGER: {
2705 intmax_t j;
2706
2707 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2708 r = -EINVAL;
2709 goto finish;
2710 }
2711
2712 j = va_arg(ap, intmax_t);
2713
2714 if (current->n_suppress == 0) {
2715 r = json_variant_new_integer(&add, j);
2716 if (r < 0)
2717 goto finish;
2718 }
2719
2720 n_subtract = 1;
2721
2722 if (current->expect == EXPECT_TOPLEVEL)
2723 current->expect = EXPECT_END;
2724 else if (current->expect == EXPECT_OBJECT_VALUE)
2725 current->expect = EXPECT_OBJECT_KEY;
2726 else
2727 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2728
2729 break;
2730 }
2731
2732 case _JSON_BUILD_UNSIGNED: {
2733 uintmax_t j;
2734
2735 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2736 r = -EINVAL;
2737 goto finish;
2738 }
2739
2740 j = va_arg(ap, uintmax_t);
2741
2742 if (current->n_suppress == 0) {
2743 r = json_variant_new_unsigned(&add, j);
2744 if (r < 0)
2745 goto finish;
2746 }
2747
2748 n_subtract = 1;
2749
2750 if (current->expect == EXPECT_TOPLEVEL)
2751 current->expect = EXPECT_END;
2752 else if (current->expect == EXPECT_OBJECT_VALUE)
2753 current->expect = EXPECT_OBJECT_KEY;
2754 else
2755 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2756
2757 break;
2758 }
2759
2760 case _JSON_BUILD_REAL: {
2761 long double d;
2762
2763 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2764 r = -EINVAL;
2765 goto finish;
2766 }
2767
2768 d = va_arg(ap, long double);
2769
2770 if (current->n_suppress == 0) {
2771 r = json_variant_new_real(&add, d);
2772 if (r < 0)
2773 goto finish;
2774 }
2775
2776 n_subtract = 1;
2777
2778 if (current->expect == EXPECT_TOPLEVEL)
2779 current->expect = EXPECT_END;
2780 else if (current->expect == EXPECT_OBJECT_VALUE)
2781 current->expect = EXPECT_OBJECT_KEY;
2782 else
2783 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2784
2785 break;
2786 }
2787
2788 case _JSON_BUILD_BOOLEAN: {
2789 bool b;
2790
2791 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2792 r = -EINVAL;
2793 goto finish;
2794 }
2795
2796 b = va_arg(ap, int);
2797
2798 if (current->n_suppress == 0) {
2799 r = json_variant_new_boolean(&add, b);
2800 if (r < 0)
2801 goto finish;
2802 }
2803
2804 n_subtract = 1;
2805
2806 if (current->expect == EXPECT_TOPLEVEL)
2807 current->expect = EXPECT_END;
2808 else if (current->expect == EXPECT_OBJECT_VALUE)
2809 current->expect = EXPECT_OBJECT_KEY;
2810 else
2811 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2812
2813 break;
2814 }
2815
2816 case _JSON_BUILD_NULL:
2817
2818 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2819 r = -EINVAL;
2820 goto finish;
2821 }
2822
2823 if (current->n_suppress == 0) {
2824 r = json_variant_new_null(&add);
2825 if (r < 0)
2826 goto finish;
2827 }
2828
2829 n_subtract = 1;
2830
2831 if (current->expect == EXPECT_TOPLEVEL)
2832 current->expect = EXPECT_END;
2833 else if (current->expect == EXPECT_OBJECT_VALUE)
2834 current->expect = EXPECT_OBJECT_KEY;
2835 else
2836 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2837
2838 break;
2839
2840 case _JSON_BUILD_VARIANT:
2841
2842 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2843 r = -EINVAL;
2844 goto finish;
2845 }
2846
2847 /* Note that we don't care for current->n_suppress here, after all the variant is already
2848 * allocated anyway... */
2849 add = va_arg(ap, JsonVariant*);
2850 if (!add)
2851 add = JSON_VARIANT_MAGIC_NULL;
2852 else
2853 json_variant_ref(add);
2854
2855 n_subtract = 1;
2856
2857 if (current->expect == EXPECT_TOPLEVEL)
2858 current->expect = EXPECT_END;
2859 else if (current->expect == EXPECT_OBJECT_VALUE)
2860 current->expect = EXPECT_OBJECT_KEY;
2861 else
2862 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2863
2864 break;
2865
2866 case _JSON_BUILD_LITERAL: {
2867 const char *l;
2868
2869 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2870 r = -EINVAL;
2871 goto finish;
2872 }
2873
2874 l = va_arg(ap, const char *);
2875
2876 if (l) {
2877 /* Note that we don't care for current->n_suppress here, we should generate parsing
2878 * errors even in suppressed object properties */
2879
2880 r = json_parse(l, &add, NULL, NULL);
2881 if (r < 0)
2882 goto finish;
2883 } else
2884 add = JSON_VARIANT_MAGIC_NULL;
2885
2886 n_subtract = 1;
2887
2888 if (current->expect == EXPECT_TOPLEVEL)
2889 current->expect = EXPECT_END;
2890 else if (current->expect == EXPECT_OBJECT_VALUE)
2891 current->expect = EXPECT_OBJECT_KEY;
2892 else
2893 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2894
2895 break;
2896 }
2897
2898 case _JSON_BUILD_ARRAY_BEGIN:
2899
2900 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2901 r = -EINVAL;
2902 goto finish;
2903 }
2904
2905 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2906 r = -ENOMEM;
2907 goto finish;
2908 }
2909 current = stack + n_stack - 1;
2910
2911 if (current->expect == EXPECT_TOPLEVEL)
2912 current->expect = EXPECT_END;
2913 else if (current->expect == EXPECT_OBJECT_VALUE)
2914 current->expect = EXPECT_OBJECT_KEY;
2915 else
2916 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2917
2918 stack[n_stack++] = (JsonStack) {
2919 .expect = EXPECT_ARRAY_ELEMENT,
2920 .n_suppress = current->n_suppress != 0 ? (size_t) -1 : 0, /* if we shall suppress the
2921 * new array, then we should
2922 * also suppress all array
2923 * members */
2924 };
2925
2926 break;
2927
2928 case _JSON_BUILD_ARRAY_END:
2929 if (current->expect != EXPECT_ARRAY_ELEMENT) {
2930 r = -EINVAL;
2931 goto finish;
2932 }
2933
2934 assert(n_stack > 1);
2935
2936 if (current->n_suppress == 0) {
2937 r = json_variant_new_array(&add, current->elements, current->n_elements);
2938 if (r < 0)
2939 goto finish;
2940 }
2941
2942 n_subtract = 1;
2943
2944 json_stack_release(current);
2945 n_stack--, current--;
2946
2947 break;
2948
2949 case _JSON_BUILD_STRV: {
2950 char **l;
2951
2952 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2953 r = -EINVAL;
2954 goto finish;
2955 }
2956
2957 l = va_arg(ap, char **);
2958
2959 if (current->n_suppress == 0) {
2960 r = json_variant_new_array_strv(&add, l);
2961 if (r < 0)
2962 goto finish;
2963 }
2964
2965 n_subtract = 1;
2966
2967 if (current->expect == EXPECT_TOPLEVEL)
2968 current->expect = EXPECT_END;
2969 else if (current->expect == EXPECT_OBJECT_VALUE)
2970 current->expect = EXPECT_OBJECT_KEY;
2971 else
2972 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2973
2974 break;
2975 }
2976
2977 case _JSON_BUILD_OBJECT_BEGIN:
2978
2979 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2980 r = -EINVAL;
2981 goto finish;
2982 }
2983
2984 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2985 r = -ENOMEM;
2986 goto finish;
2987 }
2988 current = stack + n_stack - 1;
2989
2990 if (current->expect == EXPECT_TOPLEVEL)
2991 current->expect = EXPECT_END;
2992 else if (current->expect == EXPECT_OBJECT_VALUE)
2993 current->expect = EXPECT_OBJECT_KEY;
2994 else
2995 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2996
2997 stack[n_stack++] = (JsonStack) {
2998 .expect = EXPECT_OBJECT_KEY,
2999 .n_suppress = current->n_suppress != 0 ? (size_t) -1 : 0, /* if we shall suppress the
3000 * new object, then we should
3001 * also suppress all object
3002 * members */
3003 };
3004
3005 break;
3006
3007 case _JSON_BUILD_OBJECT_END:
3008
3009 if (current->expect != EXPECT_OBJECT_KEY) {
3010 r = -EINVAL;
3011 goto finish;
3012 }
3013
3014 assert(n_stack > 1);
3015
3016 if (current->n_suppress == 0) {
3017 r = json_variant_new_object(&add, current->elements, current->n_elements);
3018 if (r < 0)
3019 goto finish;
3020 }
3021
3022 n_subtract = 1;
3023
3024 json_stack_release(current);
3025 n_stack--, current--;
3026
3027 break;
3028
3029 case _JSON_BUILD_PAIR: {
3030 const char *n;
3031
3032 if (current->expect != EXPECT_OBJECT_KEY) {
3033 r = -EINVAL;
3034 goto finish;
3035 }
3036
3037 n = va_arg(ap, const char *);
3038
3039 if (current->n_suppress == 0) {
3040 r = json_variant_new_string(&add, n);
3041 if (r < 0)
3042 goto finish;
3043 }
3044
3045 n_subtract = 1;
3046
3047 current->expect = EXPECT_OBJECT_VALUE;
3048 break;
3049 }
3050
3051 case _JSON_BUILD_PAIR_CONDITION: {
3052 const char *n;
3053 bool b;
3054
3055 if (current->expect != EXPECT_OBJECT_KEY) {
3056 r = -EINVAL;
3057 goto finish;
3058 }
3059
3060 b = va_arg(ap, int);
3061 n = va_arg(ap, const char *);
3062
3063 if (b && current->n_suppress == 0) {
3064 r = json_variant_new_string(&add, n);
3065 if (r < 0)
3066 goto finish;
3067 }
3068
3069 n_subtract = 1; /* we generated one item */
3070
3071 if (!b && current->n_suppress != (size_t) -1)
3072 current->n_suppress += 2; /* Suppress this one and the next item */
3073
3074 current->expect = EXPECT_OBJECT_VALUE;
3075 break;
3076 }}
3077
3078 /* If a variant was generated, add it to our current variant, but only if we are not supposed to suppress additions */
3079 if (add && current->n_suppress == 0) {
3080 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
3081 r = -ENOMEM;
3082 goto finish;
3083 }
3084
3085 current->elements[current->n_elements++] = TAKE_PTR(add);
3086 }
3087
3088 /* If we are supposed to suppress items, let's subtract how many items where generated from that
3089 * counter. Except if the counter is (size_t) -1, i.e. we shall suppress an infinite number of elements
3090 * on this stack level */
3091 if (current->n_suppress != (size_t) -1) {
3092 if (current->n_suppress <= n_subtract) /* Saturated */
3093 current->n_suppress = 0;
3094 else
3095 current->n_suppress -= n_subtract;
3096 }
3097 }
3098
3099 done:
3100 assert(n_stack == 1);
3101 assert(stack[0].n_elements == 1);
3102
3103 *ret = json_variant_ref(stack[0].elements[0]);
3104 r = 0;
3105
3106 finish:
3107 for (i = 0; i < n_stack; i++)
3108 json_stack_release(stack + i);
3109
3110 free(stack);
3111
3112 return r;
3113 }
3114
3115 int json_build(JsonVariant **ret, ...) {
3116 va_list ap;
3117 int r;
3118
3119 va_start(ap, ret);
3120 r = json_buildv(ret, ap);
3121 va_end(ap);
3122
3123 return r;
3124 }
3125
3126 int json_log_internal(
3127 JsonVariant *variant,
3128 int level,
3129 int error,
3130 const char *file,
3131 int line,
3132 const char *func,
3133 const char *format, ...) {
3134
3135 PROTECT_ERRNO;
3136
3137 unsigned source_line, source_column;
3138 char buffer[LINE_MAX];
3139 const char *source;
3140 va_list ap;
3141 int r;
3142
3143 errno = ERRNO_VALUE(error);
3144
3145 va_start(ap, format);
3146 (void) vsnprintf(buffer, sizeof buffer, format, ap);
3147 va_end(ap);
3148
3149 if (variant) {
3150 r = json_variant_get_source(variant, &source, &source_line, &source_column);
3151 if (r < 0)
3152 return r;
3153 } else {
3154 source = NULL;
3155 source_line = 0;
3156 source_column = 0;
3157 }
3158
3159 if (source && source_line > 0 && source_column > 0)
3160 return log_struct_internal(
3161 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3162 error,
3163 file, line, func,
3164 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3165 "CONFIG_FILE=%s", source,
3166 "CONFIG_LINE=%u", source_line,
3167 "CONFIG_COLUMN=%u", source_column,
3168 LOG_MESSAGE("%s:%u:%u: %s", source, source_line, source_column, buffer),
3169 NULL);
3170 else
3171 return log_struct_internal(
3172 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3173 error,
3174 file, line, func,
3175 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3176 LOG_MESSAGE("%s", buffer),
3177 NULL);
3178 }
3179
3180 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) {
3181 const JsonDispatch *p;
3182 size_t i, n, m;
3183 int r, done = 0;
3184 bool *found;
3185
3186 if (!json_variant_is_object(v)) {
3187 json_log(v, flags, 0, "JSON variant is not an object.");
3188
3189 if (flags & JSON_PERMISSIVE)
3190 return 0;
3191
3192 return -EINVAL;
3193 }
3194
3195 for (p = table, m = 0; p->name; p++)
3196 m++;
3197
3198 found = newa0(bool, m);
3199
3200 n = json_variant_elements(v);
3201 for (i = 0; i < n; i += 2) {
3202 JsonVariant *key, *value;
3203
3204 assert_se(key = json_variant_by_index(v, i));
3205 assert_se(value = json_variant_by_index(v, i+1));
3206
3207 for (p = table; p->name; p++)
3208 if (p->name == (const char*) -1 ||
3209 streq_ptr(json_variant_string(key), p->name))
3210 break;
3211
3212 if (p->name) { /* Found a matching entry! :-) */
3213 JsonDispatchFlags merged_flags;
3214
3215 merged_flags = flags | p->flags;
3216
3217 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
3218 !json_variant_has_type(value, p->type)) {
3219
3220 json_log(value, merged_flags, 0,
3221 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
3222 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
3223
3224 if (merged_flags & JSON_PERMISSIVE)
3225 continue;
3226
3227 return -EINVAL;
3228 }
3229
3230 if (found[p-table]) {
3231 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
3232
3233 if (merged_flags & JSON_PERMISSIVE)
3234 continue;
3235
3236 return -ENOTUNIQ;
3237 }
3238
3239 found[p-table] = true;
3240
3241 if (p->callback) {
3242 r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset);
3243 if (r < 0) {
3244 if (merged_flags & JSON_PERMISSIVE)
3245 continue;
3246
3247 return r;
3248 }
3249 }
3250
3251 done ++;
3252
3253 } else { /* Didn't find a matching entry! :-( */
3254
3255 if (bad) {
3256 r = bad(json_variant_string(key), value, flags, userdata);
3257 if (r < 0) {
3258 if (flags & JSON_PERMISSIVE)
3259 continue;
3260
3261 return r;
3262 } else
3263 done ++;
3264
3265 } else {
3266 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
3267
3268 if (flags & JSON_PERMISSIVE)
3269 continue;
3270
3271 return -EADDRNOTAVAIL;
3272 }
3273 }
3274 }
3275
3276 for (p = table; p->name; p++) {
3277 JsonDispatchFlags merged_flags = p->flags | flags;
3278
3279 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
3280 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
3281
3282 if ((merged_flags & JSON_PERMISSIVE))
3283 continue;
3284
3285 return -ENXIO;
3286 }
3287 }
3288
3289 return done;
3290 }
3291
3292 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3293 bool *b = userdata;
3294
3295 assert(variant);
3296 assert(b);
3297
3298 if (!json_variant_is_boolean(variant)) {
3299 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3300 return -EINVAL;
3301 }
3302
3303 *b = json_variant_boolean(variant);
3304 return 0;
3305 }
3306
3307 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3308 int *b = userdata;
3309
3310 assert(variant);
3311 assert(b);
3312
3313 if (!json_variant_is_boolean(variant)) {
3314 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3315 return -EINVAL;
3316 }
3317
3318 *b = json_variant_boolean(variant);
3319 return 0;
3320 }
3321
3322 int json_dispatch_integer(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3323 intmax_t *i = userdata;
3324
3325 assert(variant);
3326 assert(i);
3327
3328 if (!json_variant_is_integer(variant)) {
3329 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3330 return -EINVAL;
3331 }
3332
3333 *i = json_variant_integer(variant);
3334 return 0;
3335 }
3336
3337 int json_dispatch_unsigned(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3338 uintmax_t *u = userdata;
3339
3340 assert(variant);
3341 assert(u);
3342
3343 if (!json_variant_is_unsigned(variant)) {
3344 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3345 return -EINVAL;
3346 }
3347
3348 *u = json_variant_unsigned(variant);
3349 return 0;
3350 }
3351
3352 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3353 uint32_t *u = userdata;
3354
3355 assert(variant);
3356 assert(u);
3357
3358 if (!json_variant_is_unsigned(variant)) {
3359 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3360 return -EINVAL;
3361 }
3362
3363 if (json_variant_unsigned(variant) > UINT32_MAX) {
3364 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3365 return -ERANGE;
3366 }
3367
3368 *u = (uint32_t) json_variant_unsigned(variant);
3369 return 0;
3370 }
3371
3372 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3373 int32_t *i = userdata;
3374
3375 assert(variant);
3376 assert(i);
3377
3378 if (!json_variant_is_integer(variant)) {
3379 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3380 return -EINVAL;
3381 }
3382
3383 if (json_variant_integer(variant) < INT32_MIN || json_variant_integer(variant) > INT32_MAX) {
3384 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3385 return -ERANGE;
3386 }
3387
3388 *i = (int32_t) json_variant_integer(variant);
3389 return 0;
3390 }
3391
3392 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3393 char **s = userdata;
3394 int r;
3395
3396 assert(variant);
3397 assert(s);
3398
3399 if (json_variant_is_null(variant)) {
3400 *s = mfree(*s);
3401 return 0;
3402 }
3403
3404 if (!json_variant_is_string(variant)) {
3405 json_log(variant, flags, 0, "JSON field '%s' is not a string.", strna(name));
3406 return -EINVAL;
3407 }
3408
3409 r = free_and_strdup(s, json_variant_string(variant));
3410 if (r < 0)
3411 return json_log(variant, flags, r, "Failed to allocate string: %m");
3412
3413 return 0;
3414 }
3415
3416 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3417 _cleanup_strv_free_ char **l = NULL;
3418 char ***s = userdata;
3419 size_t i;
3420 int r;
3421
3422 assert(variant);
3423 assert(s);
3424
3425 if (json_variant_is_null(variant)) {
3426 *s = strv_free(*s);
3427 return 0;
3428 }
3429
3430 if (!json_variant_is_array(variant)) {
3431 json_log(variant, 0, flags, "JSON field '%s' is not an array.", strna(name));
3432 return -EINVAL;
3433 }
3434
3435 for (i = 0; i < json_variant_elements(variant); i++) {
3436 JsonVariant *e;
3437
3438 assert_se(e = json_variant_by_index(variant, i));
3439
3440 if (!json_variant_is_string(e)) {
3441 json_log(e, 0, flags, "JSON array element is not a string.");
3442 return -EINVAL;
3443 }
3444
3445 r = strv_extend(&l, json_variant_string(e));
3446 if (r < 0)
3447 return json_log(variant, flags, r, "Failed to append array element: %m");
3448 }
3449
3450 strv_free_and_replace(*s, l);
3451 return 0;
3452 }
3453
3454 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3455 JsonVariant **p = userdata;
3456
3457 assert(variant);
3458 assert(p);
3459
3460 json_variant_unref(*p);
3461 *p = json_variant_ref(variant);
3462
3463 return 0;
3464 }
3465
3466 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
3467 [JSON_VARIANT_STRING] = "string",
3468 [JSON_VARIANT_INTEGER] = "integer",
3469 [JSON_VARIANT_UNSIGNED] = "unsigned",
3470 [JSON_VARIANT_REAL] = "real",
3471 [JSON_VARIANT_NUMBER] = "number",
3472 [JSON_VARIANT_BOOLEAN] = "boolean",
3473 [JSON_VARIANT_ARRAY] = "array",
3474 [JSON_VARIANT_OBJECT] = "object",
3475 [JSON_VARIANT_NULL] = "null",
3476 };
3477
3478 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);