]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/json.c
pkgconfig: define variables relative to ${prefix}/${rootprefix}/${sysconfdir}
[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 "string-table.h"
22 #include "string-util.h"
23 #include "strv.h"
24 #include "terminal-util.h"
25 #include "utf8.h"
26
27 /* Refuse putting together variants with a larger depth than 4K by default (as a protection against overflowing stacks
28 * if code processes JSON objects recursively. Note that we store the depth in an uint16_t, hence make sure this
29 * remains under 2^16.
30 * The value was 16k, but it was discovered to be too high on llvm/x86-64. See also the issue #10738. */
31 #define DEPTH_MAX (4U*1024U)
32 assert_cc(DEPTH_MAX <= UINT16_MAX);
33
34 typedef struct JsonSource {
35 /* When we parse from a file or similar, encodes the filename, to indicate the source of a json variant */
36 size_t n_ref;
37 unsigned max_line;
38 unsigned max_column;
39 char name[];
40 } JsonSource;
41
42 /* On x86-64 this whole structure should have a size of 6 * 64 bit = 48 bytes */
43 struct JsonVariant {
44 union {
45 /* We either maintain a reference counter for this variant itself, or we are embedded into an
46 * array/object, in which case only that surrounding object is ref-counted. (If 'embedded' is false,
47 * see below.) */
48 size_t n_ref;
49
50 /* If this JsonVariant is part of an array/object, then this field points to the surrounding
51 * JSON_VARIANT_ARRAY/JSON_VARIANT_OBJECT object. (If 'embedded' is true, see below.) */
52 JsonVariant *parent;
53 };
54
55 /* If this was parsed from some file or buffer, this stores where from, as well as the source line/column */
56 JsonSource *source;
57 unsigned line, column;
58
59 JsonVariantType type:5;
60
61 /* A marker whether this variant is embedded into in array/object or not. If true, the 'parent' pointer above
62 * is valid. If false, the 'n_ref' field above is valid instead. */
63 bool is_embedded:1;
64
65 /* In some conditions (for example, if this object is part of an array of strings or objects), we don't store
66 * any data inline, but instead simply reference an external object and act as surrogate of it. In that case
67 * this bool is set, and the external object is referenced through the .reference field below. */
68 bool is_reference:1;
69
70 /* While comparing two arrays, we use this for marking what we already have seen */
71 bool is_marked:1;
72
73 /* The current 'depth' of the JsonVariant, i.e. how many levels of member variants this has */
74 uint16_t depth;
75
76 union {
77 /* For simple types we store the value in-line. */
78 JsonValue value;
79
80 /* For objects and arrays we store the number of elements immediately following */
81 size_t n_elements;
82
83 /* If is_reference as indicated above is set, this is where the reference object is actually stored. */
84 JsonVariant *reference;
85
86 /* Strings are placed immediately after the structure. Note that when this is a JsonVariant embedded
87 * into an array we might encode strings up to INLINE_STRING_LENGTH characters directly inside the
88 * element, while longer strings are stored as references. When this object is not embedded into an
89 * array, but stand-alone we allocate the right size for the whole structure, i.e. the array might be
90 * much larger than INLINE_STRING_LENGTH.
91 *
92 * Note that because we want to allocate arrays of the JsonVariant structure we specify [0] here,
93 * rather than the prettier []. If we wouldn't, then this char array would have undefined size, and so
94 * would the union and then the struct this is included in. And of structures with undefined size we
95 * can't allocate arrays (at least not easily). */
96 char string[0];
97 };
98 };
99
100 /* Inside string arrays we have a series of JasonVariant structures one after the other. In this case, strings longer
101 * than INLINE_STRING_MAX are stored as references, and all shorter ones inline. (This means — on x86-64 — strings up
102 * to 15 chars are stored within the array elements, and all others in separate allocations) */
103 #define INLINE_STRING_MAX (sizeof(JsonVariant) - offsetof(JsonVariant, string) - 1U)
104
105 /* Let's make sure this structure isn't increased in size accidentally. This check is only for our most relevant arch
106 * (x86-64). */
107 #ifdef __x86_64__
108 assert_cc(sizeof(JsonVariant) == 48U);
109 assert_cc(INLINE_STRING_MAX == 15U);
110 #endif
111
112 static JsonSource* json_source_new(const char *name) {
113 JsonSource *s;
114
115 assert(name);
116
117 s = malloc(offsetof(JsonSource, name) + strlen(name) + 1);
118 if (!s)
119 return NULL;
120
121 *s = (JsonSource) {
122 .n_ref = 1,
123 };
124 strcpy(s->name, name);
125
126 return s;
127 }
128
129 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(JsonSource, json_source, mfree);
130
131 static bool json_source_equal(JsonSource *a, JsonSource *b) {
132 if (a == b)
133 return true;
134
135 if (!a || !b)
136 return false;
137
138 return streq(a->name, b->name);
139 }
140
141 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonSource*, json_source_unref);
142
143 /* There are four kind of JsonVariant* pointers:
144 *
145 * 1. NULL
146 * 2. A 'regular' one, i.e. pointing to malloc() memory
147 * 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.
148 * 4. A 'const string' one, i.e. a pointer to a const string.
149 *
150 * The four kinds of pointers can be discerned like this:
151 *
152 * Detecting #1 is easy, just compare with NULL. Detecting #3 is similarly easy: all magic pointers are below
153 * _JSON_VARIANT_MAGIC_MAX (which is pretty low, within the first memory page, which is special on Linux and other
154 * 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,
155 * otherwise #4. This makes use of the fact that malloc() will return "maximum aligned" memory, which definitely
156 * means the pointer is even. This means we can use the uneven pointers to reference static strings, as long as we
157 * make sure that all static strings used like this are aligned to 2 (or higher), and that we mask the bit on
158 * access. The JSON_VARIANT_STRING_CONST() macro encodes strings as JsonVariant* pointers, with the bit set. */
159
160 static bool json_variant_is_magic(const JsonVariant *v) {
161 if (!v)
162 return false;
163
164 return v < _JSON_VARIANT_MAGIC_MAX;
165 }
166
167 static bool json_variant_is_const_string(const JsonVariant *v) {
168
169 if (v < _JSON_VARIANT_MAGIC_MAX)
170 return false;
171
172 /* A proper JsonVariant is aligned to whatever malloc() aligns things too, which is definitely not uneven. We
173 * hence use all uneven pointers as indicators for const strings. */
174
175 return (((uintptr_t) v) & 1) != 0;
176 }
177
178 static bool json_variant_is_regular(const JsonVariant *v) {
179
180 if (v < _JSON_VARIANT_MAGIC_MAX)
181 return false;
182
183 return (((uintptr_t) v) & 1) == 0;
184 }
185
186 static JsonVariant *json_variant_dereference(JsonVariant *v) {
187
188 /* Recursively dereference variants that are references to other variants */
189
190 if (!v)
191 return NULL;
192
193 if (!json_variant_is_regular(v))
194 return v;
195
196 if (!v->is_reference)
197 return v;
198
199 return json_variant_dereference(v->reference);
200 }
201
202 static uint16_t json_variant_depth(JsonVariant *v) {
203
204 v = json_variant_dereference(v);
205 if (!v)
206 return 0;
207
208 if (!json_variant_is_regular(v))
209 return 0;
210
211 return v->depth;
212 }
213
214 static JsonVariant *json_variant_normalize(JsonVariant *v) {
215
216 /* Converts json variants to their normalized form, i.e. fully dereferenced and wherever possible converted to
217 * the "magic" version if there is one */
218
219 if (!v)
220 return NULL;
221
222 v = json_variant_dereference(v);
223
224 switch (json_variant_type(v)) {
225
226 case JSON_VARIANT_BOOLEAN:
227 return json_variant_boolean(v) ? JSON_VARIANT_MAGIC_TRUE : JSON_VARIANT_MAGIC_FALSE;
228
229 case JSON_VARIANT_NULL:
230 return JSON_VARIANT_MAGIC_NULL;
231
232 case JSON_VARIANT_INTEGER:
233 return json_variant_integer(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_INTEGER : v;
234
235 case JSON_VARIANT_UNSIGNED:
236 return json_variant_unsigned(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED : v;
237
238 case JSON_VARIANT_REAL:
239 #pragma GCC diagnostic push
240 #pragma GCC diagnostic ignored "-Wfloat-equal"
241 return json_variant_real(v) == 0.0 ? JSON_VARIANT_MAGIC_ZERO_REAL : v;
242 #pragma GCC diagnostic pop
243
244 case JSON_VARIANT_STRING:
245 return isempty(json_variant_string(v)) ? JSON_VARIANT_MAGIC_EMPTY_STRING : v;
246
247 case JSON_VARIANT_ARRAY:
248 return json_variant_elements(v) == 0 ? JSON_VARIANT_MAGIC_EMPTY_ARRAY : v;
249
250 case JSON_VARIANT_OBJECT:
251 return json_variant_elements(v) == 0 ? JSON_VARIANT_MAGIC_EMPTY_OBJECT : v;
252
253 default:
254 return v;
255 }
256 }
257
258 static JsonVariant *json_variant_conservative_normalize(JsonVariant *v) {
259
260 /* Much like json_variant_normalize(), but won't simplify if the variant has a source/line location attached to
261 * it, in order not to lose context */
262
263 if (!v)
264 return NULL;
265
266 if (!json_variant_is_regular(v))
267 return v;
268
269 if (v->source || v->line > 0 || v->column > 0)
270 return v;
271
272 return json_variant_normalize(v);
273 }
274
275 static int json_variant_new(JsonVariant **ret, JsonVariantType type, size_t space) {
276 JsonVariant *v;
277
278 assert_return(ret, -EINVAL);
279
280 v = malloc0(offsetof(JsonVariant, value) + space);
281 if (!v)
282 return -ENOMEM;
283
284 v->n_ref = 1;
285 v->type = type;
286
287 *ret = v;
288 return 0;
289 }
290
291 int json_variant_new_integer(JsonVariant **ret, intmax_t i) {
292 JsonVariant *v;
293 int r;
294
295 assert_return(ret, -EINVAL);
296
297 if (i == 0) {
298 *ret = JSON_VARIANT_MAGIC_ZERO_INTEGER;
299 return 0;
300 }
301
302 r = json_variant_new(&v, JSON_VARIANT_INTEGER, sizeof(i));
303 if (r < 0)
304 return r;
305
306 v->value.integer = i;
307 *ret = v;
308
309 return 0;
310 }
311
312 int json_variant_new_unsigned(JsonVariant **ret, uintmax_t u) {
313 JsonVariant *v;
314 int r;
315
316 assert_return(ret, -EINVAL);
317 if (u == 0) {
318 *ret = JSON_VARIANT_MAGIC_ZERO_UNSIGNED;
319 return 0;
320 }
321
322 r = json_variant_new(&v, JSON_VARIANT_UNSIGNED, sizeof(u));
323 if (r < 0)
324 return r;
325
326 v->value.unsig = u;
327 *ret = v;
328
329 return 0;
330 }
331
332 int json_variant_new_real(JsonVariant **ret, long double d) {
333 JsonVariant *v;
334 int r;
335
336 assert_return(ret, -EINVAL);
337
338 #pragma GCC diagnostic push
339 #pragma GCC diagnostic ignored "-Wfloat-equal"
340 if (d == 0.0) {
341 #pragma GCC diagnostic pop
342 *ret = JSON_VARIANT_MAGIC_ZERO_REAL;
343 return 0;
344 }
345
346 r = json_variant_new(&v, JSON_VARIANT_REAL, sizeof(d));
347 if (r < 0)
348 return r;
349
350 v->value.real = d;
351 *ret = v;
352
353 return 0;
354 }
355
356 int json_variant_new_boolean(JsonVariant **ret, bool b) {
357 assert_return(ret, -EINVAL);
358
359 if (b)
360 *ret = JSON_VARIANT_MAGIC_TRUE;
361 else
362 *ret = JSON_VARIANT_MAGIC_FALSE;
363
364 return 0;
365 }
366
367 int json_variant_new_null(JsonVariant **ret) {
368 assert_return(ret, -EINVAL);
369
370 *ret = JSON_VARIANT_MAGIC_NULL;
371 return 0;
372 }
373
374 int json_variant_new_stringn(JsonVariant **ret, const char *s, size_t n) {
375 JsonVariant *v;
376 int r;
377
378 assert_return(ret, -EINVAL);
379 if (!s) {
380 assert_return(n == 0, -EINVAL);
381 return json_variant_new_null(ret);
382 }
383 if (n == 0) {
384 *ret = JSON_VARIANT_MAGIC_EMPTY_STRING;
385 return 0;
386 }
387
388 r = json_variant_new(&v, JSON_VARIANT_STRING, n + 1);
389 if (r < 0)
390 return r;
391
392 memcpy(v->string, s, n);
393 v->string[n] = 0;
394
395 *ret = v;
396 return 0;
397 }
398
399 static void json_variant_set(JsonVariant *a, JsonVariant *b) {
400 assert(a);
401
402 b = json_variant_dereference(b);
403 if (!b) {
404 a->type = JSON_VARIANT_NULL;
405 return;
406 }
407
408 a->type = json_variant_type(b);
409 switch (a->type) {
410
411 case JSON_VARIANT_INTEGER:
412 a->value.integer = json_variant_integer(b);
413 break;
414
415 case JSON_VARIANT_UNSIGNED:
416 a->value.unsig = json_variant_unsigned(b);
417 break;
418
419 case JSON_VARIANT_REAL:
420 a->value.real = json_variant_real(b);
421 break;
422
423 case JSON_VARIANT_BOOLEAN:
424 a->value.boolean = json_variant_boolean(b);
425 break;
426
427 case JSON_VARIANT_STRING: {
428 const char *s;
429
430 assert_se(s = json_variant_string(b));
431
432 /* Short strings we can store inline */
433 if (strnlen(s, INLINE_STRING_MAX+1) <= INLINE_STRING_MAX) {
434 strcpy(a->string, s);
435 break;
436 }
437
438 /* For longer strings, use a reference… */
439 _fallthrough_;
440 }
441
442 case JSON_VARIANT_ARRAY:
443 case JSON_VARIANT_OBJECT:
444 a->is_reference = true;
445 a->reference = json_variant_ref(json_variant_conservative_normalize(b));
446 break;
447
448 case JSON_VARIANT_NULL:
449 break;
450
451 default:
452 assert_not_reached("Unexpected variant type");
453 }
454 }
455
456 static void json_variant_copy_source(JsonVariant *v, JsonVariant *from) {
457 assert(v);
458 assert(from);
459
460 if (!json_variant_is_regular(from))
461 return;
462
463 v->line = from->line;
464 v->column = from->column;
465 v->source = json_source_ref(from->source);
466 }
467
468 int json_variant_new_array(JsonVariant **ret, JsonVariant **array, size_t n) {
469 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
470
471 assert_return(ret, -EINVAL);
472 if (n == 0) {
473 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
474 return 0;
475 }
476 assert_return(array, -EINVAL);
477
478 v = new(JsonVariant, n + 1);
479 if (!v)
480 return -ENOMEM;
481
482 *v = (JsonVariant) {
483 .n_ref = 1,
484 .type = JSON_VARIANT_ARRAY,
485 };
486
487 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
488 JsonVariant *w = v + 1 + v->n_elements,
489 *c = array[v->n_elements];
490 uint16_t d;
491
492 d = json_variant_depth(c);
493 if (d >= DEPTH_MAX) /* Refuse too deep nesting */
494 return -ELNRNG;
495 if (d >= v->depth)
496 v->depth = d + 1;
497
498 *w = (JsonVariant) {
499 .is_embedded = true,
500 .parent = v,
501 };
502
503 json_variant_set(w, c);
504 json_variant_copy_source(w, c);
505 }
506
507 *ret = TAKE_PTR(v);
508 return 0;
509 }
510
511 int json_variant_new_array_bytes(JsonVariant **ret, const void *p, size_t n) {
512 JsonVariant *v;
513 size_t i;
514
515 assert_return(ret, -EINVAL);
516 if (n == 0) {
517 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
518 return 0;
519 }
520 assert_return(p, -EINVAL);
521
522 v = new(JsonVariant, n + 1);
523 if (!v)
524 return -ENOMEM;
525
526 *v = (JsonVariant) {
527 .n_ref = 1,
528 .type = JSON_VARIANT_ARRAY,
529 .n_elements = n,
530 .depth = 1,
531 };
532
533 for (i = 0; i < n; i++) {
534 JsonVariant *w = v + 1 + i;
535
536 *w = (JsonVariant) {
537 .is_embedded = true,
538 .parent = v,
539 .type = JSON_VARIANT_UNSIGNED,
540 .value.unsig = ((const uint8_t*) p)[i],
541 };
542 }
543
544 *ret = v;
545 return 0;
546 }
547
548 int json_variant_new_array_strv(JsonVariant **ret, char **l) {
549 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
550 size_t n;
551 int r;
552
553 assert(ret);
554
555 n = strv_length(l);
556 if (n == 0) {
557 *ret = JSON_VARIANT_MAGIC_EMPTY_ARRAY;
558 return 0;
559 }
560
561 v = new(JsonVariant, n + 1);
562 if (!v)
563 return -ENOMEM;
564
565 *v = (JsonVariant) {
566 .n_ref = 1,
567 .type = JSON_VARIANT_ARRAY,
568 .depth = 1,
569 };
570
571 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
572 JsonVariant *w = v + 1 + v->n_elements;
573 size_t k;
574
575 *w = (JsonVariant) {
576 .is_embedded = true,
577 .parent = v,
578 .type = JSON_VARIANT_STRING,
579 };
580
581 k = strlen(l[v->n_elements]);
582
583 if (k > INLINE_STRING_MAX) {
584 /* If string is too long, store it as reference. */
585
586 r = json_variant_new_stringn(&w->reference, l[v->n_elements], k);
587 if (r < 0)
588 return r;
589
590 w->is_reference = true;
591 } else
592 memcpy(w->string, l[v->n_elements], k+1);
593 }
594
595 *ret = TAKE_PTR(v);
596 return 0;
597 }
598
599 int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n) {
600 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
601
602 assert_return(ret, -EINVAL);
603 if (n == 0) {
604 *ret = JSON_VARIANT_MAGIC_EMPTY_OBJECT;
605 return 0;
606 }
607 assert_return(array, -EINVAL);
608 assert_return(n % 2 == 0, -EINVAL);
609
610 v = new(JsonVariant, n + 1);
611 if (!v)
612 return -ENOMEM;
613
614 *v = (JsonVariant) {
615 .n_ref = 1,
616 .type = JSON_VARIANT_OBJECT,
617 };
618
619 for (v->n_elements = 0; v->n_elements < n; v->n_elements++) {
620 JsonVariant *w = v + 1 + v->n_elements,
621 *c = array[v->n_elements];
622 uint16_t d;
623
624 if ((v->n_elements & 1) == 0 &&
625 !json_variant_is_string(c))
626 return -EINVAL; /* Every second one needs to be a string, as it is the key name */
627
628 d = json_variant_depth(c);
629 if (d >= DEPTH_MAX) /* Refuse too deep nesting */
630 return -ELNRNG;
631 if (d >= v->depth)
632 v->depth = d + 1;
633
634 *w = (JsonVariant) {
635 .is_embedded = true,
636 .parent = v,
637 };
638
639 json_variant_set(w, c);
640 json_variant_copy_source(w, c);
641 }
642
643 *ret = TAKE_PTR(v);
644 return 0;
645 }
646
647 static void json_variant_free_inner(JsonVariant *v) {
648 assert(v);
649
650 if (!json_variant_is_regular(v))
651 return;
652
653 json_source_unref(v->source);
654
655 if (v->is_reference) {
656 json_variant_unref(v->reference);
657 return;
658 }
659
660 if (IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT)) {
661 size_t i;
662
663 for (i = 0; i < v->n_elements; i++)
664 json_variant_free_inner(v + 1 + i);
665 }
666 }
667
668 JsonVariant *json_variant_ref(JsonVariant *v) {
669 if (!v)
670 return NULL;
671 if (!json_variant_is_regular(v))
672 return v;
673
674 if (v->is_embedded)
675 json_variant_ref(v->parent); /* ref the compounding variant instead */
676 else {
677 assert(v->n_ref > 0);
678 v->n_ref++;
679 }
680
681 return v;
682 }
683
684 JsonVariant *json_variant_unref(JsonVariant *v) {
685 if (!v)
686 return NULL;
687 if (!json_variant_is_regular(v))
688 return NULL;
689
690 if (v->is_embedded)
691 json_variant_unref(v->parent);
692 else {
693 assert(v->n_ref > 0);
694 v->n_ref--;
695
696 if (v->n_ref == 0) {
697 json_variant_free_inner(v);
698 free(v);
699 }
700 }
701
702 return NULL;
703 }
704
705 void json_variant_unref_many(JsonVariant **array, size_t n) {
706 size_t i;
707
708 assert(array || n == 0);
709
710 for (i = 0; i < n; i++)
711 json_variant_unref(array[i]);
712 }
713
714 const char *json_variant_string(JsonVariant *v) {
715 if (!v)
716 return NULL;
717 if (v == JSON_VARIANT_MAGIC_EMPTY_STRING)
718 return "";
719 if (json_variant_is_magic(v))
720 goto mismatch;
721 if (json_variant_is_const_string(v)) {
722 uintptr_t p = (uintptr_t) v;
723
724 assert((p & 1) != 0);
725 return (const char*) (p ^ 1U);
726 }
727
728 if (v->is_reference)
729 return json_variant_string(v->reference);
730 if (v->type != JSON_VARIANT_STRING)
731 goto mismatch;
732
733 return v->string;
734
735 mismatch:
736 log_debug("Non-string JSON variant requested as string, returning NULL.");
737 return NULL;
738 }
739
740 bool json_variant_boolean(JsonVariant *v) {
741 if (!v)
742 goto mismatch;
743 if (v == JSON_VARIANT_MAGIC_TRUE)
744 return true;
745 if (v == JSON_VARIANT_MAGIC_FALSE)
746 return false;
747 if (!json_variant_is_regular(v))
748 goto mismatch;
749 if (v->type != JSON_VARIANT_BOOLEAN)
750 goto mismatch;
751 if (v->is_reference)
752 return json_variant_boolean(v->reference);
753
754 return v->value.boolean;
755
756 mismatch:
757 log_debug("Non-boolean JSON variant requested as boolean, returning false.");
758 return false;
759 }
760
761 intmax_t json_variant_integer(JsonVariant *v) {
762 if (!v)
763 goto mismatch;
764 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
765 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
766 v == JSON_VARIANT_MAGIC_ZERO_REAL)
767 return 0;
768 if (!json_variant_is_regular(v))
769 goto mismatch;
770 if (v->is_reference)
771 return json_variant_integer(v->reference);
772
773 switch (v->type) {
774
775 case JSON_VARIANT_INTEGER:
776 return v->value.integer;
777
778 case JSON_VARIANT_UNSIGNED:
779 if (v->value.unsig <= INTMAX_MAX)
780 return (intmax_t) v->value.unsig;
781
782 log_debug("Unsigned integer %ju requested as signed integer and out of range, returning 0.", v->value.unsig);
783 return 0;
784
785 case JSON_VARIANT_REAL: {
786 intmax_t converted;
787
788 converted = (intmax_t) v->value.real;
789
790 #pragma GCC diagnostic push
791 #pragma GCC diagnostic ignored "-Wfloat-equal"
792 if ((long double) converted == v->value.real)
793 #pragma GCC diagnostic pop
794 return converted;
795
796 log_debug("Real %Lg requested as integer, and cannot be converted losslessly, returning 0.", v->value.real);
797 return 0;
798 }
799
800 default:
801 break;
802 }
803
804 mismatch:
805 log_debug("Non-integer JSON variant requested as integer, returning 0.");
806 return 0;
807 }
808
809 uintmax_t json_variant_unsigned(JsonVariant *v) {
810 if (!v)
811 goto mismatch;
812 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
813 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
814 v == JSON_VARIANT_MAGIC_ZERO_REAL)
815 return 0;
816 if (!json_variant_is_regular(v))
817 goto mismatch;
818 if (v->is_reference)
819 return json_variant_integer(v->reference);
820
821 switch (v->type) {
822
823 case JSON_VARIANT_INTEGER:
824 if (v->value.integer >= 0)
825 return (uintmax_t) v->value.integer;
826
827 log_debug("Signed integer %ju requested as unsigned integer and out of range, returning 0.", v->value.integer);
828 return 0;
829
830 case JSON_VARIANT_UNSIGNED:
831 return v->value.unsig;
832
833 case JSON_VARIANT_REAL: {
834 uintmax_t converted;
835
836 converted = (uintmax_t) v->value.real;
837
838 #pragma GCC diagnostic push
839 #pragma GCC diagnostic ignored "-Wfloat-equal"
840 if ((long double) converted == v->value.real)
841 #pragma GCC diagnostic pop
842 return converted;
843
844 log_debug("Real %Lg requested as unsigned integer, and cannot be converted losslessly, returning 0.", v->value.real);
845 return 0;
846 }
847
848 default:
849 break;
850 }
851
852 mismatch:
853 log_debug("Non-integer JSON variant requested as unsigned, returning 0.");
854 return 0;
855 }
856
857 long double json_variant_real(JsonVariant *v) {
858 if (!v)
859 return 0.0;
860 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
861 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
862 v == JSON_VARIANT_MAGIC_ZERO_REAL)
863 return 0.0;
864 if (!json_variant_is_regular(v))
865 goto mismatch;
866 if (v->is_reference)
867 return json_variant_real(v->reference);
868
869 switch (v->type) {
870
871 case JSON_VARIANT_REAL:
872 return v->value.real;
873
874 case JSON_VARIANT_INTEGER: {
875 long double converted;
876
877 converted = (long double) v->value.integer;
878
879 if ((intmax_t) converted == v->value.integer)
880 return converted;
881
882 log_debug("Signed integer %ji requested as real, and cannot be converted losslessly, returning 0.", v->value.integer);
883 return 0.0;
884 }
885
886 case JSON_VARIANT_UNSIGNED: {
887 long double converted;
888
889 converted = (long double) v->value.unsig;
890
891 if ((uintmax_t) converted == v->value.unsig)
892 return converted;
893
894 log_debug("Unsigned integer %ju requested as real, and cannot be converted losslessly, returning 0.", v->value.unsig);
895 return 0.0;
896 }
897
898 default:
899 break;
900 }
901
902 mismatch:
903 log_debug("Non-integer JSON variant requested as integer, returning 0.");
904 return 0.0;
905 }
906
907 bool json_variant_is_negative(JsonVariant *v) {
908 if (!v)
909 goto mismatch;
910 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER ||
911 v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED ||
912 v == JSON_VARIANT_MAGIC_ZERO_REAL)
913 return false;
914 if (!json_variant_is_regular(v))
915 goto mismatch;
916 if (v->is_reference)
917 return json_variant_is_negative(v->reference);
918
919 /* This function is useful as checking whether numbers are negative is pretty complex since we have three types
920 * of numbers. And some JSON code (OCI for example) uses negative numbers to mark "not defined" numeric
921 * values. */
922
923 switch (v->type) {
924
925 case JSON_VARIANT_REAL:
926 return v->value.real < 0;
927
928 case JSON_VARIANT_INTEGER:
929 return v->value.integer < 0;
930
931 case JSON_VARIANT_UNSIGNED:
932 return false;
933
934 default:
935 break;
936 }
937
938 mismatch:
939 log_debug("Non-integer JSON variant tested for negativity, returning false.");
940 return false;
941 }
942
943 JsonVariantType json_variant_type(JsonVariant *v) {
944
945 if (!v)
946 return _JSON_VARIANT_TYPE_INVALID;
947
948 if (json_variant_is_const_string(v))
949 return JSON_VARIANT_STRING;
950
951 if (v == JSON_VARIANT_MAGIC_TRUE || v == JSON_VARIANT_MAGIC_FALSE)
952 return JSON_VARIANT_BOOLEAN;
953
954 if (v == JSON_VARIANT_MAGIC_NULL)
955 return JSON_VARIANT_NULL;
956
957 if (v == JSON_VARIANT_MAGIC_ZERO_INTEGER)
958 return JSON_VARIANT_INTEGER;
959
960 if (v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED)
961 return JSON_VARIANT_UNSIGNED;
962
963 if (v == JSON_VARIANT_MAGIC_ZERO_REAL)
964 return JSON_VARIANT_REAL;
965
966 if (v == JSON_VARIANT_MAGIC_EMPTY_STRING)
967 return JSON_VARIANT_STRING;
968
969 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY)
970 return JSON_VARIANT_ARRAY;
971
972 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
973 return JSON_VARIANT_OBJECT;
974
975 return v->type;
976 }
977
978 bool json_variant_has_type(JsonVariant *v, JsonVariantType type) {
979 JsonVariantType rt;
980
981 v = json_variant_dereference(v);
982 if (!v)
983 return false;
984
985 rt = json_variant_type(v);
986 if (rt == type)
987 return true;
988
989 /* If it's a const string, then it only can be a string, and if it is not, it's not */
990 if (json_variant_is_const_string(v))
991 return false;
992
993 /* All three magic zeroes qualify as integer, unsigned and as real */
994 if ((v == JSON_VARIANT_MAGIC_ZERO_INTEGER || v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED || v == JSON_VARIANT_MAGIC_ZERO_REAL) &&
995 IN_SET(type, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL, JSON_VARIANT_NUMBER))
996 return true;
997
998 /* All other magic variant types are only equal to themselves */
999 if (json_variant_is_magic(v))
1000 return false;
1001
1002 /* Handle the "number" pseudo type */
1003 if (type == JSON_VARIANT_NUMBER)
1004 return IN_SET(rt, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL);
1005
1006 /* Integer conversions are OK in many cases */
1007 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_UNSIGNED)
1008 return v->value.integer >= 0;
1009 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_INTEGER)
1010 return v->value.unsig <= INTMAX_MAX;
1011
1012 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1013 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_REAL)
1014 return (intmax_t) (long double) v->value.integer == v->value.integer;
1015 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_REAL)
1016 return (uintmax_t) (long double) v->value.unsig == v->value.unsig;
1017
1018 #pragma GCC diagnostic push
1019 #pragma GCC diagnostic ignored "-Wfloat-equal"
1020 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1021 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_INTEGER)
1022 return (long double) (intmax_t) v->value.real == v->value.real;
1023 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_UNSIGNED)
1024 return (long double) (uintmax_t) v->value.real == v->value.real;
1025 #pragma GCC diagnostic pop
1026
1027 return false;
1028 }
1029
1030 size_t json_variant_elements(JsonVariant *v) {
1031 if (!v)
1032 return 0;
1033 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1034 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1035 return 0;
1036 if (!json_variant_is_regular(v))
1037 goto mismatch;
1038 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1039 goto mismatch;
1040 if (v->is_reference)
1041 return json_variant_elements(v->reference);
1042
1043 return v->n_elements;
1044
1045 mismatch:
1046 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1047 return 0;
1048 }
1049
1050 JsonVariant *json_variant_by_index(JsonVariant *v, size_t idx) {
1051 if (!v)
1052 return NULL;
1053 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1054 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1055 return NULL;
1056 if (!json_variant_is_regular(v))
1057 goto mismatch;
1058 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1059 goto mismatch;
1060 if (v->is_reference)
1061 return json_variant_by_index(v->reference, idx);
1062 if (idx >= v->n_elements)
1063 return NULL;
1064
1065 return json_variant_conservative_normalize(v + 1 + idx);
1066
1067 mismatch:
1068 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1069 return NULL;
1070 }
1071
1072 JsonVariant *json_variant_by_key_full(JsonVariant *v, const char *key, JsonVariant **ret_key) {
1073 size_t i;
1074
1075 if (!v)
1076 goto not_found;
1077 if (!key)
1078 goto not_found;
1079 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1080 goto not_found;
1081 if (!json_variant_is_regular(v))
1082 goto mismatch;
1083 if (v->type != JSON_VARIANT_OBJECT)
1084 goto mismatch;
1085 if (v->is_reference)
1086 return json_variant_by_key(v->reference, key);
1087
1088 for (i = 0; i < v->n_elements; i += 2) {
1089 JsonVariant *p;
1090
1091 p = json_variant_dereference(v + 1 + i);
1092
1093 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1094 continue;
1095
1096 if (streq(json_variant_string(p), key)) {
1097
1098 if (ret_key)
1099 *ret_key = json_variant_conservative_normalize(v + 1 + i);
1100
1101 return json_variant_conservative_normalize(v + 1 + i + 1);
1102 }
1103 }
1104
1105 not_found:
1106 if (ret_key)
1107 *ret_key = NULL;
1108
1109 return NULL;
1110
1111 mismatch:
1112 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1113 if (ret_key)
1114 *ret_key = NULL;
1115
1116 return NULL;
1117 }
1118
1119 JsonVariant *json_variant_by_key(JsonVariant *v, const char *key) {
1120 return json_variant_by_key_full(v, key, NULL);
1121 }
1122
1123 bool json_variant_equal(JsonVariant *a, JsonVariant *b) {
1124 JsonVariantType t;
1125
1126 a = json_variant_normalize(a);
1127 b = json_variant_normalize(b);
1128
1129 if (a == b)
1130 return true;
1131
1132 t = json_variant_type(a);
1133 if (!json_variant_has_type(b, t))
1134 return false;
1135
1136 switch (t) {
1137
1138 case JSON_VARIANT_STRING:
1139 return streq(json_variant_string(a), json_variant_string(b));
1140
1141 case JSON_VARIANT_INTEGER:
1142 return json_variant_integer(a) == json_variant_integer(b);
1143
1144 case JSON_VARIANT_UNSIGNED:
1145 return json_variant_unsigned(a) == json_variant_unsigned(b);
1146
1147 case JSON_VARIANT_REAL:
1148 #pragma GCC diagnostic push
1149 #pragma GCC diagnostic ignored "-Wfloat-equal"
1150 return json_variant_real(a) == json_variant_real(b);
1151 #pragma GCC diagnostic pop
1152
1153 case JSON_VARIANT_BOOLEAN:
1154 return json_variant_boolean(a) == json_variant_boolean(b);
1155
1156 case JSON_VARIANT_NULL:
1157 return true;
1158
1159 case JSON_VARIANT_ARRAY: {
1160 size_t i, n;
1161
1162 n = json_variant_elements(a);
1163 if (n != json_variant_elements(b))
1164 return false;
1165
1166 for (i = 0; i < n; i++) {
1167 if (!json_variant_equal(json_variant_by_index(a, i), json_variant_by_index(b, i)))
1168 return false;
1169 }
1170
1171 return true;
1172 }
1173
1174 case JSON_VARIANT_OBJECT: {
1175 size_t i, n;
1176
1177 n = json_variant_elements(a);
1178 if (n != json_variant_elements(b))
1179 return false;
1180
1181 /* Iterate through all keys in 'a' */
1182 for (i = 0; i < n; i += 2) {
1183 bool found = false;
1184 size_t j;
1185
1186 /* Match them against all keys in 'b' */
1187 for (j = 0; j < n; j += 2) {
1188 JsonVariant *key_b;
1189
1190 key_b = json_variant_by_index(b, j);
1191
1192 /* During the first iteration unmark everything */
1193 if (i == 0)
1194 key_b->is_marked = false;
1195 else if (key_b->is_marked) /* In later iterations if we already marked something, don't bother with it again */
1196 continue;
1197
1198 if (found)
1199 continue;
1200
1201 if (json_variant_equal(json_variant_by_index(a, i), key_b) &&
1202 json_variant_equal(json_variant_by_index(a, i+1), json_variant_by_index(b, j+1))) {
1203 /* Key and values match! */
1204 key_b->is_marked = found = true;
1205
1206 /* In the first iteration we continue the inner loop since we want to mark
1207 * everything, otherwise exit the loop quickly after we found what we were
1208 * looking for. */
1209 if (i != 0)
1210 break;
1211 }
1212 }
1213
1214 if (!found)
1215 return false;
1216 }
1217
1218 return true;
1219 }
1220
1221 default:
1222 assert_not_reached("Unknown variant type.");
1223 }
1224 }
1225
1226 int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column) {
1227 assert_return(v, -EINVAL);
1228
1229 if (ret_source)
1230 *ret_source = json_variant_is_regular(v) && v->source ? v->source->name : NULL;
1231
1232 if (ret_line)
1233 *ret_line = json_variant_is_regular(v) ? v->line : 0;
1234
1235 if (ret_column)
1236 *ret_column = json_variant_is_regular(v) ? v->column : 0;
1237
1238 return 0;
1239 }
1240
1241 static int print_source(FILE *f, JsonVariant *v, JsonFormatFlags flags, bool whitespace) {
1242 size_t w, k;
1243
1244 if (!FLAGS_SET(flags, JSON_FORMAT_SOURCE|JSON_FORMAT_PRETTY))
1245 return 0;
1246
1247 if (!json_variant_is_regular(v))
1248 return 0;
1249
1250 if (!v->source && v->line == 0 && v->column == 0)
1251 return 0;
1252
1253 /* The max width we need to format the line numbers for this source file */
1254 w = (v->source && v->source->max_line > 0) ?
1255 DECIMAL_STR_WIDTH(v->source->max_line) :
1256 DECIMAL_STR_MAX(unsigned)-1;
1257 k = (v->source && v->source->max_column > 0) ?
1258 DECIMAL_STR_WIDTH(v->source->max_column) :
1259 DECIMAL_STR_MAX(unsigned) -1;
1260
1261 if (whitespace) {
1262 size_t i, n;
1263
1264 n = 1 + (v->source ? strlen(v->source->name) : 0) +
1265 ((v->source && (v->line > 0 || v->column > 0)) ? 1 : 0) +
1266 (v->line > 0 ? w : 0) +
1267 (((v->source || v->line > 0) && v->column > 0) ? 1 : 0) +
1268 (v->column > 0 ? k : 0) +
1269 2;
1270
1271 for (i = 0; i < n; i++)
1272 fputc(' ', f);
1273 } else {
1274 fputc('[', f);
1275
1276 if (v->source)
1277 fputs(v->source->name, f);
1278 if (v->source && (v->line > 0 || v->column > 0))
1279 fputc(':', f);
1280 if (v->line > 0)
1281 fprintf(f, "%*u", (int) w, v->line);
1282 if ((v->source || v->line > 0) || v->column > 0)
1283 fputc(':', f);
1284 if (v->column > 0)
1285 fprintf(f, "%*u", (int) k, v->column);
1286
1287 fputc(']', f);
1288 fputc(' ', f);
1289 }
1290
1291 return 0;
1292 }
1293
1294 static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const char *prefix) {
1295 int r;
1296
1297 assert(f);
1298 assert(v);
1299
1300 switch (json_variant_type(v)) {
1301
1302 case JSON_VARIANT_REAL: {
1303 locale_t loc;
1304
1305 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
1306 if (loc == (locale_t) 0)
1307 return -errno;
1308
1309 if (flags & JSON_FORMAT_COLOR)
1310 fputs(ANSI_HIGHLIGHT_BLUE, f);
1311
1312 fprintf(f, "%.*Le", DECIMAL_DIG, json_variant_real(v));
1313
1314 if (flags & JSON_FORMAT_COLOR)
1315 fputs(ANSI_NORMAL, f);
1316
1317 freelocale(loc);
1318 break;
1319 }
1320
1321 case JSON_VARIANT_INTEGER:
1322 if (flags & JSON_FORMAT_COLOR)
1323 fputs(ANSI_HIGHLIGHT_BLUE, f);
1324
1325 fprintf(f, "%" PRIdMAX, json_variant_integer(v));
1326
1327 if (flags & JSON_FORMAT_COLOR)
1328 fputs(ANSI_NORMAL, f);
1329 break;
1330
1331 case JSON_VARIANT_UNSIGNED:
1332 if (flags & JSON_FORMAT_COLOR)
1333 fputs(ANSI_HIGHLIGHT_BLUE, f);
1334
1335 fprintf(f, "%" PRIuMAX, json_variant_unsigned(v));
1336
1337 if (flags & JSON_FORMAT_COLOR)
1338 fputs(ANSI_NORMAL, f);
1339 break;
1340
1341 case JSON_VARIANT_BOOLEAN:
1342
1343 if (flags & JSON_FORMAT_COLOR)
1344 fputs(ANSI_HIGHLIGHT, f);
1345
1346 if (json_variant_boolean(v))
1347 fputs("true", f);
1348 else
1349 fputs("false", f);
1350
1351 if (flags & JSON_FORMAT_COLOR)
1352 fputs(ANSI_NORMAL, f);
1353
1354 break;
1355
1356 case JSON_VARIANT_NULL:
1357 if (flags & JSON_FORMAT_COLOR)
1358 fputs(ANSI_HIGHLIGHT, f);
1359
1360 fputs("null", f);
1361
1362 if (flags & JSON_FORMAT_COLOR)
1363 fputs(ANSI_NORMAL, f);
1364 break;
1365
1366 case JSON_VARIANT_STRING: {
1367 const char *q;
1368
1369 fputc('"', f);
1370
1371 if (flags & JSON_FORMAT_COLOR)
1372 fputs(ANSI_GREEN, f);
1373
1374 for (q = json_variant_string(v); *q; q++) {
1375
1376 switch (*q) {
1377
1378 case '"':
1379 fputs("\\\"", f);
1380 break;
1381
1382 case '\\':
1383 fputs("\\\\", f);
1384 break;
1385
1386 case '\b':
1387 fputs("\\b", f);
1388 break;
1389
1390 case '\f':
1391 fputs("\\f", f);
1392 break;
1393
1394 case '\n':
1395 fputs("\\n", f);
1396 break;
1397
1398 case '\r':
1399 fputs("\\r", f);
1400 break;
1401
1402 case '\t':
1403 fputs("\\t", f);
1404 break;
1405
1406 default:
1407 if ((signed char) *q >= 0 && *q < ' ')
1408 fprintf(f, "\\u%04x", *q);
1409 else
1410 fputc(*q, f);
1411 break;
1412 }
1413 }
1414
1415 if (flags & JSON_FORMAT_COLOR)
1416 fputs(ANSI_NORMAL, f);
1417
1418 fputc('"', f);
1419 break;
1420 }
1421
1422 case JSON_VARIANT_ARRAY: {
1423 size_t i, n;
1424
1425 n = json_variant_elements(v);
1426
1427 if (n == 0)
1428 fputs("[]", f);
1429 else {
1430 _cleanup_free_ char *joined = NULL;
1431 const char *prefix2;
1432
1433 if (flags & JSON_FORMAT_PRETTY) {
1434 joined = strjoin(strempty(prefix), "\t");
1435 if (!joined)
1436 return -ENOMEM;
1437
1438 prefix2 = joined;
1439 fputs("[\n", f);
1440 } else {
1441 prefix2 = strempty(prefix);
1442 fputc('[', f);
1443 }
1444
1445 for (i = 0; i < n; i++) {
1446 JsonVariant *e;
1447
1448 assert_se(e = json_variant_by_index(v, i));
1449
1450 if (i > 0) {
1451 if (flags & JSON_FORMAT_PRETTY)
1452 fputs(",\n", f);
1453 else
1454 fputc(',', f);
1455 }
1456
1457 if (flags & JSON_FORMAT_PRETTY) {
1458 print_source(f, e, flags, false);
1459 fputs(prefix2, f);
1460 }
1461
1462 r = json_format(f, e, flags, prefix2);
1463 if (r < 0)
1464 return r;
1465 }
1466
1467 if (flags & JSON_FORMAT_PRETTY) {
1468 fputc('\n', f);
1469 print_source(f, v, flags, true);
1470 fputs(strempty(prefix), f);
1471 }
1472
1473 fputc(']', f);
1474 }
1475 break;
1476 }
1477
1478 case JSON_VARIANT_OBJECT: {
1479 size_t i, n;
1480
1481 n = json_variant_elements(v);
1482
1483 if (n == 0)
1484 fputs("{}", f);
1485 else {
1486 _cleanup_free_ char *joined = NULL;
1487 const char *prefix2;
1488
1489 if (flags & JSON_FORMAT_PRETTY) {
1490 joined = strjoin(strempty(prefix), "\t");
1491 if (!joined)
1492 return -ENOMEM;
1493
1494 prefix2 = joined;
1495 fputs("{\n", f);
1496 } else {
1497 prefix2 = strempty(prefix);
1498 fputc('{', f);
1499 }
1500
1501 for (i = 0; i < n; i += 2) {
1502 JsonVariant *e;
1503
1504 e = json_variant_by_index(v, i);
1505
1506 if (i > 0) {
1507 if (flags & JSON_FORMAT_PRETTY)
1508 fputs(",\n", f);
1509 else
1510 fputc(',', f);
1511 }
1512
1513 if (flags & JSON_FORMAT_PRETTY) {
1514 print_source(f, e, flags, false);
1515 fputs(prefix2, f);
1516 }
1517
1518 r = json_format(f, e, flags, prefix2);
1519 if (r < 0)
1520 return r;
1521
1522 fputs(flags & JSON_FORMAT_PRETTY ? " : " : ":", f);
1523
1524 r = json_format(f, json_variant_by_index(v, i+1), flags, prefix2);
1525 if (r < 0)
1526 return r;
1527 }
1528
1529 if (flags & JSON_FORMAT_PRETTY) {
1530 fputc('\n', f);
1531 print_source(f, v, flags, true);
1532 fputs(strempty(prefix), f);
1533 }
1534
1535 fputc('}', f);
1536 }
1537 break;
1538 }
1539
1540 default:
1541 assert_not_reached("Unexpected variant type.");
1542 }
1543
1544 return 0;
1545 }
1546
1547 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
1548 _cleanup_free_ char *s = NULL;
1549 size_t sz = 0;
1550 int r;
1551
1552 assert_return(v, -EINVAL);
1553 assert_return(ret, -EINVAL);
1554
1555 {
1556 _cleanup_fclose_ FILE *f = NULL;
1557
1558 f = open_memstream(&s, &sz);
1559 if (!f)
1560 return -ENOMEM;
1561
1562 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
1563
1564 json_variant_dump(v, flags, f, NULL);
1565
1566 r = fflush_and_check(f);
1567 }
1568 if (r < 0)
1569 return r;
1570
1571 assert(s);
1572 *ret = TAKE_PTR(s);
1573
1574 return (int) sz;
1575 }
1576
1577 void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) {
1578 if (!v)
1579 return;
1580
1581 if (!f)
1582 f = stdout;
1583
1584 print_source(f, v, flags, false);
1585
1586 if (((flags & (JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_COLOR)) == JSON_FORMAT_COLOR_AUTO) && colors_enabled())
1587 flags |= JSON_FORMAT_COLOR;
1588
1589 if (flags & JSON_FORMAT_SSE)
1590 fputs("data: ", f);
1591 if (flags & JSON_FORMAT_SEQ)
1592 fputc('\x1e', f); /* ASCII Record Separator */
1593
1594 json_format(f, v, flags, prefix);
1595
1596 if (flags & (JSON_FORMAT_PRETTY|JSON_FORMAT_SEQ|JSON_FORMAT_SSE|JSON_FORMAT_NEWLINE))
1597 fputc('\n', f);
1598 if (flags & JSON_FORMAT_SSE)
1599 fputc('\n', f); /* In case of SSE add a second newline */
1600 }
1601
1602 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
1603 JsonVariantType t;
1604 JsonVariant *c;
1605 JsonValue value;
1606 const void *source;
1607 size_t k;
1608
1609 assert(nv);
1610 assert(v);
1611
1612 /* Let's copy the simple types literally, and the larger types by references */
1613 t = json_variant_type(v);
1614 switch (t) {
1615 case JSON_VARIANT_INTEGER:
1616 k = sizeof(intmax_t);
1617 value.integer = json_variant_integer(v);
1618 source = &value;
1619 break;
1620
1621 case JSON_VARIANT_UNSIGNED:
1622 k = sizeof(uintmax_t);
1623 value.unsig = json_variant_unsigned(v);
1624 source = &value;
1625 break;
1626
1627 case JSON_VARIANT_REAL:
1628 k = sizeof(long double);
1629 value.real = json_variant_real(v);
1630 source = &value;
1631 break;
1632
1633 case JSON_VARIANT_BOOLEAN:
1634 k = sizeof(bool);
1635 value.boolean = json_variant_boolean(v);
1636 source = &value;
1637 break;
1638
1639 case JSON_VARIANT_NULL:
1640 k = 0;
1641 source = NULL;
1642 break;
1643
1644 case JSON_VARIANT_STRING:
1645 source = json_variant_string(v);
1646 k = strnlen(source, INLINE_STRING_MAX + 1);
1647 if (k <= INLINE_STRING_MAX) {
1648 k ++;
1649 break;
1650 }
1651
1652 _fallthrough_;
1653
1654 default:
1655 /* Everything else copy by reference */
1656
1657 c = malloc0(offsetof(JsonVariant, reference) + sizeof(JsonVariant*));
1658 if (!c)
1659 return -ENOMEM;
1660
1661 c->n_ref = 1;
1662 c->type = t;
1663 c->is_reference = true;
1664 c->reference = json_variant_ref(json_variant_normalize(v));
1665
1666 *nv = c;
1667 return 0;
1668 }
1669
1670 c = malloc0(offsetof(JsonVariant, value) + k);
1671 if (!c)
1672 return -ENOMEM;
1673
1674 c->n_ref = 1;
1675 c->type = t;
1676
1677 memcpy_safe(&c->value, source, k);
1678
1679 *nv = c;
1680 return 0;
1681 }
1682
1683 static bool json_single_ref(JsonVariant *v) {
1684
1685 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
1686
1687 if (!json_variant_is_regular(v))
1688 return false;
1689
1690 if (v->is_embedded)
1691 return json_single_ref(v->parent);
1692
1693 assert(v->n_ref > 0);
1694 return v->n_ref == 1;
1695 }
1696
1697 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
1698 JsonVariant *w;
1699 int r;
1700
1701 assert(v);
1702
1703 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole referencer of
1704 * the object. If not, allocates a new object, possibly a surrogate for the original one */
1705
1706 if (!*v)
1707 return 0;
1708
1709 if (source && line > source->max_line)
1710 source->max_line = line;
1711 if (source && column > source->max_column)
1712 source->max_column = column;
1713
1714 if (!json_variant_is_regular(*v)) {
1715
1716 if (!source && line == 0 && column == 0)
1717 return 0;
1718
1719 } else {
1720 if (json_source_equal((*v)->source, source) &&
1721 (*v)->line == line &&
1722 (*v)->column == column)
1723 return 0;
1724
1725 if (json_single_ref(*v)) { /* Sole reference? */
1726 json_source_unref((*v)->source);
1727 (*v)->source = json_source_ref(source);
1728 (*v)->line = line;
1729 (*v)->column = column;
1730 return 1;
1731 }
1732 }
1733
1734 r = json_variant_copy(&w, *v);
1735 if (r < 0)
1736 return r;
1737
1738 assert(json_variant_is_regular(w));
1739 assert(!w->is_embedded);
1740 assert(w->n_ref == 1);
1741 assert(!w->source);
1742
1743 w->source = json_source_ref(source);
1744 w->line = line;
1745 w->column = column;
1746
1747 json_variant_unref(*v);
1748 *v = w;
1749
1750 return 1;
1751 }
1752
1753 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
1754 assert(line);
1755 assert(column);
1756 assert(s || n == 0);
1757
1758 while (n > 0) {
1759
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);
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);
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 va_end(ap);
3113
3114 return r;
3115 }
3116
3117 int json_build(JsonVariant **ret, ...) {
3118 va_list ap;
3119 int r;
3120
3121 va_start(ap, ret);
3122 r = json_buildv(ret, ap);
3123 va_end(ap);
3124
3125 return r;
3126 }
3127
3128 int json_log_internal(
3129 JsonVariant *variant,
3130 int level,
3131 int error,
3132 const char *file,
3133 int line,
3134 const char *func,
3135 const char *format, ...) {
3136
3137 PROTECT_ERRNO;
3138
3139 unsigned source_line, source_column;
3140 char buffer[LINE_MAX];
3141 const char *source;
3142 va_list ap;
3143 int r;
3144
3145 errno = ERRNO_VALUE(error);
3146
3147 va_start(ap, format);
3148 (void) vsnprintf(buffer, sizeof buffer, format, ap);
3149 va_end(ap);
3150
3151 if (variant) {
3152 r = json_variant_get_source(variant, &source, &source_line, &source_column);
3153 if (r < 0)
3154 return r;
3155 } else {
3156 source = NULL;
3157 source_line = 0;
3158 source_column = 0;
3159 }
3160
3161 if (source && source_line > 0 && source_column > 0)
3162 return log_struct_internal(
3163 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3164 error,
3165 file, line, func,
3166 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3167 "CONFIG_FILE=%s", source,
3168 "CONFIG_LINE=%u", source_line,
3169 "CONFIG_COLUMN=%u", source_column,
3170 LOG_MESSAGE("%s:%u: %s", source, line, buffer),
3171 NULL);
3172 else
3173 return log_struct_internal(
3174 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3175 error,
3176 file, line, func,
3177 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3178 LOG_MESSAGE("%s", buffer),
3179 NULL);
3180 }
3181
3182 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) {
3183 const JsonDispatch *p;
3184 size_t i, n, m;
3185 int r, done = 0;
3186 bool *found;
3187
3188 if (!json_variant_is_object(v)) {
3189 json_log(v, flags, 0, "JSON variant is not an object.");
3190
3191 if (flags & JSON_PERMISSIVE)
3192 return 0;
3193
3194 return -EINVAL;
3195 }
3196
3197 for (p = table, m = 0; p->name; p++)
3198 m++;
3199
3200 found = newa0(bool, m);
3201
3202 n = json_variant_elements(v);
3203 for (i = 0; i < n; i += 2) {
3204 JsonVariant *key, *value;
3205
3206 assert_se(key = json_variant_by_index(v, i));
3207 assert_se(value = json_variant_by_index(v, i+1));
3208
3209 for (p = table; p->name; p++)
3210 if (p->name == (const char*) -1 ||
3211 streq_ptr(json_variant_string(key), p->name))
3212 break;
3213
3214 if (p->name) { /* Found a matching entry! :-) */
3215 JsonDispatchFlags merged_flags;
3216
3217 merged_flags = flags | p->flags;
3218
3219 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
3220 !json_variant_has_type(value, p->type)) {
3221
3222 json_log(value, merged_flags, 0,
3223 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
3224 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
3225
3226 if (merged_flags & JSON_PERMISSIVE)
3227 continue;
3228
3229 return -EINVAL;
3230 }
3231
3232 if (found[p-table]) {
3233 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
3234
3235 if (merged_flags & JSON_PERMISSIVE)
3236 continue;
3237
3238 return -ENOTUNIQ;
3239 }
3240
3241 found[p-table] = true;
3242
3243 if (p->callback) {
3244 r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset);
3245 if (r < 0) {
3246 if (merged_flags & JSON_PERMISSIVE)
3247 continue;
3248
3249 return r;
3250 }
3251 }
3252
3253 done ++;
3254
3255 } else { /* Didn't find a matching entry! :-( */
3256
3257 if (bad) {
3258 r = bad(json_variant_string(key), value, flags, userdata);
3259 if (r < 0) {
3260 if (flags & JSON_PERMISSIVE)
3261 continue;
3262
3263 return r;
3264 } else
3265 done ++;
3266
3267 } else {
3268 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
3269
3270 if (flags & JSON_PERMISSIVE)
3271 continue;
3272
3273 return -EADDRNOTAVAIL;
3274 }
3275 }
3276 }
3277
3278 for (p = table; p->name; p++) {
3279 JsonDispatchFlags merged_flags = p->flags | flags;
3280
3281 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
3282 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
3283
3284 if ((merged_flags & JSON_PERMISSIVE))
3285 continue;
3286
3287 return -ENXIO;
3288 }
3289 }
3290
3291 return done;
3292 }
3293
3294 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3295 bool *b = userdata;
3296
3297 assert(variant);
3298 assert(b);
3299
3300 if (!json_variant_is_boolean(variant)) {
3301 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3302 return -EINVAL;
3303 }
3304
3305 *b = json_variant_boolean(variant);
3306 return 0;
3307 }
3308
3309 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3310 int *b = userdata;
3311
3312 assert(variant);
3313 assert(b);
3314
3315 if (!json_variant_is_boolean(variant)) {
3316 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3317 return -EINVAL;
3318 }
3319
3320 *b = json_variant_boolean(variant);
3321 return 0;
3322 }
3323
3324 int json_dispatch_integer(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3325 intmax_t *i = userdata;
3326
3327 assert(variant);
3328 assert(i);
3329
3330 if (!json_variant_is_integer(variant)) {
3331 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3332 return -EINVAL;
3333 }
3334
3335 *i = json_variant_integer(variant);
3336 return 0;
3337 }
3338
3339 int json_dispatch_unsigned(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3340 uintmax_t *u = userdata;
3341
3342 assert(variant);
3343 assert(u);
3344
3345 if (!json_variant_is_unsigned(variant)) {
3346 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3347 return -EINVAL;
3348 }
3349
3350 *u = json_variant_unsigned(variant);
3351 return 0;
3352 }
3353
3354 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3355 uint32_t *u = userdata;
3356
3357 assert(variant);
3358 assert(u);
3359
3360 if (!json_variant_is_unsigned(variant)) {
3361 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3362 return -EINVAL;
3363 }
3364
3365 if (json_variant_unsigned(variant) > UINT32_MAX) {
3366 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3367 return -ERANGE;
3368 }
3369
3370 *u = (uint32_t) json_variant_unsigned(variant);
3371 return 0;
3372 }
3373
3374 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3375 int32_t *i = userdata;
3376
3377 assert(variant);
3378 assert(i);
3379
3380 if (!json_variant_is_integer(variant)) {
3381 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3382 return -EINVAL;
3383 }
3384
3385 if (json_variant_integer(variant) < INT32_MIN || json_variant_integer(variant) > INT32_MAX) {
3386 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3387 return -ERANGE;
3388 }
3389
3390 *i = (int32_t) json_variant_integer(variant);
3391 return 0;
3392 }
3393
3394 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3395 char **s = userdata;
3396 int r;
3397
3398 assert(variant);
3399 assert(s);
3400
3401 if (json_variant_is_null(variant)) {
3402 *s = mfree(*s);
3403 return 0;
3404 }
3405
3406 if (!json_variant_is_string(variant)) {
3407 json_log(variant, flags, 0, "JSON field '%s' is not a string.", strna(name));
3408 return -EINVAL;
3409 }
3410
3411 r = free_and_strdup(s, json_variant_string(variant));
3412 if (r < 0)
3413 return json_log(variant, flags, r, "Failed to allocate string: %m");
3414
3415 return 0;
3416 }
3417
3418 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3419 _cleanup_strv_free_ char **l = NULL;
3420 char ***s = userdata;
3421 size_t i;
3422 int r;
3423
3424 assert(variant);
3425 assert(s);
3426
3427 if (json_variant_is_null(variant)) {
3428 *s = strv_free(*s);
3429 return 0;
3430 }
3431
3432 if (!json_variant_is_array(variant)) {
3433 json_log(variant, 0, flags, "JSON field '%s' is not an array.", strna(name));
3434 return -EINVAL;
3435 }
3436
3437 for (i = 0; i < json_variant_elements(variant); i++) {
3438 JsonVariant *e;
3439
3440 assert_se(e = json_variant_by_index(variant, i));
3441
3442 if (!json_variant_is_string(e)) {
3443 json_log(e, 0, flags, "JSON array element is not a string.");
3444 return -EINVAL;
3445 }
3446
3447 r = strv_extend(&l, json_variant_string(e));
3448 if (r < 0)
3449 return json_log(variant, flags, r, "Failed to append array element: %m");
3450 }
3451
3452 strv_free_and_replace(*s, l);
3453 return 0;
3454 }
3455
3456 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3457 JsonVariant **p = userdata;
3458
3459 assert(variant);
3460 assert(p);
3461
3462 json_variant_unref(*p);
3463 *p = json_variant_ref(variant);
3464
3465 return 0;
3466 }
3467
3468 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
3469 [JSON_VARIANT_STRING] = "string",
3470 [JSON_VARIANT_INTEGER] = "integer",
3471 [JSON_VARIANT_UNSIGNED] = "unsigned",
3472 [JSON_VARIANT_REAL] = "real",
3473 [JSON_VARIANT_NUMBER] = "number",
3474 [JSON_VARIANT_BOOLEAN] = "boolean",
3475 [JSON_VARIANT_ARRAY] = "array",
3476 [JSON_VARIANT_OBJECT] = "object",
3477 [JSON_VARIANT_NULL] = "null",
3478 };
3479
3480 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);