]> git.proxmox.com Git - systemd.git/blob - src/shared/json.c
New upstream version 240
[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
983 rt = json_variant_type(v);
984 if (rt == type)
985 return true;
986
987 /* If it's a const string, then it only can be a string, and if it is not, it's not */
988 if (json_variant_is_const_string(v))
989 return false;
990
991 /* All three magic zeroes qualify as integer, unsigned and as real */
992 if ((v == JSON_VARIANT_MAGIC_ZERO_INTEGER || v == JSON_VARIANT_MAGIC_ZERO_UNSIGNED || v == JSON_VARIANT_MAGIC_ZERO_REAL) &&
993 IN_SET(type, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL, JSON_VARIANT_NUMBER))
994 return true;
995
996 /* All other magic variant types are only equal to themselves */
997 if (json_variant_is_magic(v))
998 return false;
999
1000 /* Handle the "number" pseudo type */
1001 if (type == JSON_VARIANT_NUMBER)
1002 return IN_SET(rt, JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL);
1003
1004 /* Integer conversions are OK in many cases */
1005 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_UNSIGNED)
1006 return v->value.integer >= 0;
1007 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_INTEGER)
1008 return v->value.unsig <= INTMAX_MAX;
1009
1010 /* Any integer that can be converted lossley to a real and back may also be considered a real */
1011 if (rt == JSON_VARIANT_INTEGER && type == JSON_VARIANT_REAL)
1012 return (intmax_t) (long double) v->value.integer == v->value.integer;
1013 if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_REAL)
1014 return (uintmax_t) (long double) v->value.unsig == v->value.unsig;
1015
1016 #pragma GCC diagnostic push
1017 #pragma GCC diagnostic ignored "-Wfloat-equal"
1018 /* Any real that can be converted losslessly to an integer and back may also be considered an integer */
1019 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_INTEGER)
1020 return (long double) (intmax_t) v->value.real == v->value.real;
1021 if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_UNSIGNED)
1022 return (long double) (uintmax_t) v->value.real == v->value.real;
1023 #pragma GCC diagnostic pop
1024
1025 return false;
1026 }
1027
1028 size_t json_variant_elements(JsonVariant *v) {
1029 if (!v)
1030 return 0;
1031 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1032 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1033 return 0;
1034 if (!json_variant_is_regular(v))
1035 goto mismatch;
1036 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1037 goto mismatch;
1038 if (v->is_reference)
1039 return json_variant_elements(v->reference);
1040
1041 return v->n_elements;
1042
1043 mismatch:
1044 log_debug("Number of elements in non-array/non-object JSON variant requested, returning 0.");
1045 return 0;
1046 }
1047
1048 JsonVariant *json_variant_by_index(JsonVariant *v, size_t idx) {
1049 if (!v)
1050 return NULL;
1051 if (v == JSON_VARIANT_MAGIC_EMPTY_ARRAY ||
1052 v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1053 return NULL;
1054 if (!json_variant_is_regular(v))
1055 goto mismatch;
1056 if (!IN_SET(v->type, JSON_VARIANT_ARRAY, JSON_VARIANT_OBJECT))
1057 goto mismatch;
1058 if (v->is_reference)
1059 return json_variant_by_index(v->reference, idx);
1060 if (idx >= v->n_elements)
1061 return NULL;
1062
1063 return json_variant_conservative_normalize(v + 1 + idx);
1064
1065 mismatch:
1066 log_debug("Element in non-array/non-object JSON variant requested by index, returning NULL.");
1067 return NULL;
1068 }
1069
1070 JsonVariant *json_variant_by_key_full(JsonVariant *v, const char *key, JsonVariant **ret_key) {
1071 size_t i;
1072
1073 if (!v)
1074 goto not_found;
1075 if (!key)
1076 goto not_found;
1077 if (v == JSON_VARIANT_MAGIC_EMPTY_OBJECT)
1078 goto not_found;
1079 if (!json_variant_is_regular(v))
1080 goto mismatch;
1081 if (v->type != JSON_VARIANT_OBJECT)
1082 goto mismatch;
1083 if (v->is_reference)
1084 return json_variant_by_key(v->reference, key);
1085
1086 for (i = 0; i < v->n_elements; i += 2) {
1087 JsonVariant *p;
1088
1089 p = json_variant_dereference(v + 1 + i);
1090
1091 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1092 continue;
1093
1094 if (streq(json_variant_string(p), key)) {
1095
1096 if (ret_key)
1097 *ret_key = json_variant_conservative_normalize(v + 1 + i);
1098
1099 return json_variant_conservative_normalize(v + 1 + i + 1);
1100 }
1101 }
1102
1103 not_found:
1104 if (ret_key)
1105 *ret_key = NULL;
1106
1107 return NULL;
1108
1109 mismatch:
1110 log_debug("Element in non-object JSON variant requested by key, returning NULL.");
1111 if (ret_key)
1112 *ret_key = NULL;
1113
1114 return NULL;
1115 }
1116
1117 JsonVariant *json_variant_by_key(JsonVariant *v, const char *key) {
1118 return json_variant_by_key_full(v, key, NULL);
1119 }
1120
1121 bool json_variant_equal(JsonVariant *a, JsonVariant *b) {
1122 JsonVariantType t;
1123
1124 a = json_variant_normalize(a);
1125 b = json_variant_normalize(b);
1126
1127 if (a == b)
1128 return true;
1129
1130 t = json_variant_type(a);
1131 if (!json_variant_has_type(b, t))
1132 return false;
1133
1134 switch (t) {
1135
1136 case JSON_VARIANT_STRING:
1137 return streq(json_variant_string(a), json_variant_string(b));
1138
1139 case JSON_VARIANT_INTEGER:
1140 return json_variant_integer(a) == json_variant_integer(b);
1141
1142 case JSON_VARIANT_UNSIGNED:
1143 return json_variant_unsigned(a) == json_variant_unsigned(b);
1144
1145 case JSON_VARIANT_REAL:
1146 #pragma GCC diagnostic push
1147 #pragma GCC diagnostic ignored "-Wfloat-equal"
1148 return json_variant_real(a) == json_variant_real(b);
1149 #pragma GCC diagnostic pop
1150
1151 case JSON_VARIANT_BOOLEAN:
1152 return json_variant_boolean(a) == json_variant_boolean(b);
1153
1154 case JSON_VARIANT_NULL:
1155 return true;
1156
1157 case JSON_VARIANT_ARRAY: {
1158 size_t i, n;
1159
1160 n = json_variant_elements(a);
1161 if (n != json_variant_elements(b))
1162 return false;
1163
1164 for (i = 0; i < n; i++) {
1165 if (!json_variant_equal(json_variant_by_index(a, i), json_variant_by_index(b, i)))
1166 return false;
1167 }
1168
1169 return true;
1170 }
1171
1172 case JSON_VARIANT_OBJECT: {
1173 size_t i, n;
1174
1175 n = json_variant_elements(a);
1176 if (n != json_variant_elements(b))
1177 return false;
1178
1179 /* Iterate through all keys in 'a' */
1180 for (i = 0; i < n; i += 2) {
1181 bool found = false;
1182 size_t j;
1183
1184 /* Match them against all keys in 'b' */
1185 for (j = 0; j < n; j += 2) {
1186 JsonVariant *key_b;
1187
1188 key_b = json_variant_by_index(b, j);
1189
1190 /* During the first iteration unmark everything */
1191 if (i == 0)
1192 key_b->is_marked = false;
1193 else if (key_b->is_marked) /* In later iterations if we already marked something, don't bother with it again */
1194 continue;
1195
1196 if (found)
1197 continue;
1198
1199 if (json_variant_equal(json_variant_by_index(a, i), key_b) &&
1200 json_variant_equal(json_variant_by_index(a, i+1), json_variant_by_index(b, j+1))) {
1201 /* Key and values match! */
1202 key_b->is_marked = found = true;
1203
1204 /* In the first iteration we continue the inner loop since we want to mark
1205 * everything, otherwise exit the loop quickly after we found what we were
1206 * looking for. */
1207 if (i != 0)
1208 break;
1209 }
1210 }
1211
1212 if (!found)
1213 return false;
1214 }
1215
1216 return true;
1217 }
1218
1219 default:
1220 assert_not_reached("Unknown variant type.");
1221 }
1222 }
1223
1224 int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column) {
1225 assert_return(v, -EINVAL);
1226
1227 if (ret_source)
1228 *ret_source = json_variant_is_regular(v) && v->source ? v->source->name : NULL;
1229
1230 if (ret_line)
1231 *ret_line = json_variant_is_regular(v) ? v->line : 0;
1232
1233 if (ret_column)
1234 *ret_column = json_variant_is_regular(v) ? v->column : 0;
1235
1236 return 0;
1237 }
1238
1239 static int print_source(FILE *f, JsonVariant *v, JsonFormatFlags flags, bool whitespace) {
1240 size_t w, k;
1241
1242 if (!FLAGS_SET(flags, JSON_FORMAT_SOURCE|JSON_FORMAT_PRETTY))
1243 return 0;
1244
1245 if (!json_variant_is_regular(v))
1246 return 0;
1247
1248 if (!v->source && v->line == 0 && v->column == 0)
1249 return 0;
1250
1251 /* The max width we need to format the line numbers for this source file */
1252 w = (v->source && v->source->max_line > 0) ?
1253 DECIMAL_STR_WIDTH(v->source->max_line) :
1254 DECIMAL_STR_MAX(unsigned)-1;
1255 k = (v->source && v->source->max_column > 0) ?
1256 DECIMAL_STR_WIDTH(v->source->max_column) :
1257 DECIMAL_STR_MAX(unsigned) -1;
1258
1259 if (whitespace) {
1260 size_t i, n;
1261
1262 n = 1 + (v->source ? strlen(v->source->name) : 0) +
1263 ((v->source && (v->line > 0 || v->column > 0)) ? 1 : 0) +
1264 (v->line > 0 ? w : 0) +
1265 (((v->source || v->line > 0) && v->column > 0) ? 1 : 0) +
1266 (v->column > 0 ? k : 0) +
1267 2;
1268
1269 for (i = 0; i < n; i++)
1270 fputc(' ', f);
1271 } else {
1272 fputc('[', f);
1273
1274 if (v->source)
1275 fputs(v->source->name, f);
1276 if (v->source && (v->line > 0 || v->column > 0))
1277 fputc(':', f);
1278 if (v->line > 0)
1279 fprintf(f, "%*u", (int) w, v->line);
1280 if ((v->source || v->line > 0) || v->column > 0)
1281 fputc(':', f);
1282 if (v->column > 0)
1283 fprintf(f, "%*u", (int) k, v->column);
1284
1285 fputc(']', f);
1286 fputc(' ', f);
1287 }
1288
1289 return 0;
1290 }
1291
1292 static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const char *prefix) {
1293 int r;
1294
1295 assert(f);
1296 assert(v);
1297
1298 switch (json_variant_type(v)) {
1299
1300 case JSON_VARIANT_REAL: {
1301 locale_t loc;
1302
1303 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
1304 if (loc == (locale_t) 0)
1305 return -errno;
1306
1307 if (flags & JSON_FORMAT_COLOR)
1308 fputs(ANSI_HIGHLIGHT_BLUE, f);
1309
1310 fprintf(f, "%.*Le", DECIMAL_DIG, json_variant_real(v));
1311
1312 if (flags & JSON_FORMAT_COLOR)
1313 fputs(ANSI_NORMAL, f);
1314
1315 freelocale(loc);
1316 break;
1317 }
1318
1319 case JSON_VARIANT_INTEGER:
1320 if (flags & JSON_FORMAT_COLOR)
1321 fputs(ANSI_HIGHLIGHT_BLUE, f);
1322
1323 fprintf(f, "%" PRIdMAX, json_variant_integer(v));
1324
1325 if (flags & JSON_FORMAT_COLOR)
1326 fputs(ANSI_NORMAL, f);
1327 break;
1328
1329 case JSON_VARIANT_UNSIGNED:
1330 if (flags & JSON_FORMAT_COLOR)
1331 fputs(ANSI_HIGHLIGHT_BLUE, f);
1332
1333 fprintf(f, "%" PRIuMAX, json_variant_unsigned(v));
1334
1335 if (flags & JSON_FORMAT_COLOR)
1336 fputs(ANSI_NORMAL, f);
1337 break;
1338
1339 case JSON_VARIANT_BOOLEAN:
1340
1341 if (flags & JSON_FORMAT_COLOR)
1342 fputs(ANSI_HIGHLIGHT, f);
1343
1344 if (json_variant_boolean(v))
1345 fputs("true", f);
1346 else
1347 fputs("false", f);
1348
1349 if (flags & JSON_FORMAT_COLOR)
1350 fputs(ANSI_NORMAL, f);
1351
1352 break;
1353
1354 case JSON_VARIANT_NULL:
1355 if (flags & JSON_FORMAT_COLOR)
1356 fputs(ANSI_HIGHLIGHT, f);
1357
1358 fputs("null", f);
1359
1360 if (flags & JSON_FORMAT_COLOR)
1361 fputs(ANSI_NORMAL, f);
1362 break;
1363
1364 case JSON_VARIANT_STRING: {
1365 const char *q;
1366
1367 fputc('"', f);
1368
1369 if (flags & JSON_FORMAT_COLOR)
1370 fputs(ANSI_GREEN, f);
1371
1372 for (q = json_variant_string(v); *q; q++) {
1373
1374 switch (*q) {
1375
1376 case '"':
1377 fputs("\\\"", f);
1378 break;
1379
1380 case '\\':
1381 fputs("\\\\", f);
1382 break;
1383
1384 case '\b':
1385 fputs("\\b", f);
1386 break;
1387
1388 case '\f':
1389 fputs("\\f", f);
1390 break;
1391
1392 case '\n':
1393 fputs("\\n", f);
1394 break;
1395
1396 case '\r':
1397 fputs("\\r", f);
1398 break;
1399
1400 case '\t':
1401 fputs("\\t", f);
1402 break;
1403
1404 default:
1405 if ((signed char) *q >= 0 && *q < ' ')
1406 fprintf(f, "\\u%04x", *q);
1407 else
1408 fputc(*q, f);
1409 break;
1410 }
1411 }
1412
1413 if (flags & JSON_FORMAT_COLOR)
1414 fputs(ANSI_NORMAL, f);
1415
1416 fputc('"', f);
1417 break;
1418 }
1419
1420 case JSON_VARIANT_ARRAY: {
1421 size_t i, n;
1422
1423 n = json_variant_elements(v);
1424
1425 if (n == 0)
1426 fputs("[]", f);
1427 else {
1428 _cleanup_free_ char *joined = NULL;
1429 const char *prefix2;
1430
1431 if (flags & JSON_FORMAT_PRETTY) {
1432 joined = strjoin(strempty(prefix), "\t");
1433 if (!joined)
1434 return -ENOMEM;
1435
1436 prefix2 = joined;
1437 fputs("[\n", f);
1438 } else {
1439 prefix2 = strempty(prefix);
1440 fputc('[', f);
1441 }
1442
1443 for (i = 0; i < n; i++) {
1444 JsonVariant *e;
1445
1446 assert_se(e = json_variant_by_index(v, i));
1447
1448 if (i > 0) {
1449 if (flags & JSON_FORMAT_PRETTY)
1450 fputs(",\n", f);
1451 else
1452 fputc(',', f);
1453 }
1454
1455 if (flags & JSON_FORMAT_PRETTY) {
1456 print_source(f, e, flags, false);
1457 fputs(prefix2, f);
1458 }
1459
1460 r = json_format(f, e, flags, prefix2);
1461 if (r < 0)
1462 return r;
1463 }
1464
1465 if (flags & JSON_FORMAT_PRETTY) {
1466 fputc('\n', f);
1467 print_source(f, v, flags, true);
1468 fputs(strempty(prefix), f);
1469 }
1470
1471 fputc(']', f);
1472 }
1473 break;
1474 }
1475
1476 case JSON_VARIANT_OBJECT: {
1477 size_t i, n;
1478
1479 n = json_variant_elements(v);
1480
1481 if (n == 0)
1482 fputs("{}", f);
1483 else {
1484 _cleanup_free_ char *joined = NULL;
1485 const char *prefix2;
1486
1487 if (flags & JSON_FORMAT_PRETTY) {
1488 joined = strjoin(strempty(prefix), "\t");
1489 if (!joined)
1490 return -ENOMEM;
1491
1492 prefix2 = joined;
1493 fputs("{\n", f);
1494 } else {
1495 prefix2 = strempty(prefix);
1496 fputc('{', f);
1497 }
1498
1499 for (i = 0; i < n; i += 2) {
1500 JsonVariant *e;
1501
1502 e = json_variant_by_index(v, i);
1503
1504 if (i > 0) {
1505 if (flags & JSON_FORMAT_PRETTY)
1506 fputs(",\n", f);
1507 else
1508 fputc(',', f);
1509 }
1510
1511 if (flags & JSON_FORMAT_PRETTY) {
1512 print_source(f, e, flags, false);
1513 fputs(prefix2, f);
1514 }
1515
1516 r = json_format(f, e, flags, prefix2);
1517 if (r < 0)
1518 return r;
1519
1520 fputs(flags & JSON_FORMAT_PRETTY ? " : " : ":", f);
1521
1522 r = json_format(f, json_variant_by_index(v, i+1), flags, prefix2);
1523 if (r < 0)
1524 return r;
1525 }
1526
1527 if (flags & JSON_FORMAT_PRETTY) {
1528 fputc('\n', f);
1529 print_source(f, v, flags, true);
1530 fputs(strempty(prefix), f);
1531 }
1532
1533 fputc('}', f);
1534 }
1535 break;
1536 }
1537
1538 default:
1539 assert_not_reached("Unexpected variant type.");
1540 }
1541
1542 return 0;
1543 }
1544
1545 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
1546 _cleanup_free_ char *s = NULL;
1547 size_t sz = 0;
1548 int r;
1549
1550 assert_return(v, -EINVAL);
1551 assert_return(ret, -EINVAL);
1552
1553 {
1554 _cleanup_fclose_ FILE *f = NULL;
1555
1556 f = open_memstream(&s, &sz);
1557 if (!f)
1558 return -ENOMEM;
1559
1560 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
1561
1562 json_variant_dump(v, flags, f, NULL);
1563
1564 r = fflush_and_check(f);
1565 }
1566 if (r < 0)
1567 return r;
1568
1569 assert(s);
1570 *ret = TAKE_PTR(s);
1571
1572 return (int) sz;
1573 }
1574
1575 void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix) {
1576 if (!v)
1577 return;
1578
1579 if (!f)
1580 f = stdout;
1581
1582 print_source(f, v, flags, false);
1583
1584 if (((flags & (JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_COLOR)) == JSON_FORMAT_COLOR_AUTO) && colors_enabled())
1585 flags |= JSON_FORMAT_COLOR;
1586
1587 if (flags & JSON_FORMAT_SSE)
1588 fputs("data: ", f);
1589 if (flags & JSON_FORMAT_SEQ)
1590 fputc('\x1e', f); /* ASCII Record Separator */
1591
1592 json_format(f, v, flags, prefix);
1593
1594 if (flags & (JSON_FORMAT_PRETTY|JSON_FORMAT_SEQ|JSON_FORMAT_SSE|JSON_FORMAT_NEWLINE))
1595 fputc('\n', f);
1596 if (flags & JSON_FORMAT_SSE)
1597 fputc('\n', f); /* In case of SSE add a second newline */
1598 }
1599
1600 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
1601 JsonVariantType t;
1602 JsonVariant *c;
1603 JsonValue value;
1604 const void *source;
1605 size_t k;
1606
1607 assert(nv);
1608 assert(v);
1609
1610 /* Let's copy the simple types literally, and the larger types by references */
1611 t = json_variant_type(v);
1612 switch (t) {
1613 case JSON_VARIANT_INTEGER:
1614 k = sizeof(intmax_t);
1615 value.integer = json_variant_integer(v);
1616 source = &value;
1617 break;
1618
1619 case JSON_VARIANT_UNSIGNED:
1620 k = sizeof(uintmax_t);
1621 value.unsig = json_variant_unsigned(v);
1622 source = &value;
1623 break;
1624
1625 case JSON_VARIANT_REAL:
1626 k = sizeof(long double);
1627 value.real = json_variant_real(v);
1628 source = &value;
1629 break;
1630
1631 case JSON_VARIANT_BOOLEAN:
1632 k = sizeof(bool);
1633 value.boolean = json_variant_boolean(v);
1634 source = &value;
1635 break;
1636
1637 case JSON_VARIANT_NULL:
1638 k = 0;
1639 source = NULL;
1640 break;
1641
1642 case JSON_VARIANT_STRING:
1643 source = json_variant_string(v);
1644 k = strnlen(source, INLINE_STRING_MAX + 1);
1645 if (k <= INLINE_STRING_MAX) {
1646 k ++;
1647 break;
1648 }
1649
1650 _fallthrough_;
1651
1652 default:
1653 /* Everything else copy by reference */
1654
1655 c = malloc0(offsetof(JsonVariant, reference) + sizeof(JsonVariant*));
1656 if (!c)
1657 return -ENOMEM;
1658
1659 c->n_ref = 1;
1660 c->type = t;
1661 c->is_reference = true;
1662 c->reference = json_variant_ref(json_variant_normalize(v));
1663
1664 *nv = c;
1665 return 0;
1666 }
1667
1668 c = malloc0(offsetof(JsonVariant, value) + k);
1669 if (!c)
1670 return -ENOMEM;
1671
1672 c->n_ref = 1;
1673 c->type = t;
1674
1675 memcpy_safe(&c->value, source, k);
1676
1677 *nv = c;
1678 return 0;
1679 }
1680
1681 static bool json_single_ref(JsonVariant *v) {
1682
1683 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
1684
1685 if (!json_variant_is_regular(v))
1686 return false;
1687
1688 if (v->is_embedded)
1689 return json_single_ref(v->parent);
1690
1691 assert(v->n_ref > 0);
1692 return v->n_ref == 1;
1693 }
1694
1695 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
1696 JsonVariant *w;
1697 int r;
1698
1699 assert(v);
1700
1701 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole referencer of
1702 * the object. If not, allocates a new object, possibly a surrogate for the original one */
1703
1704 if (!*v)
1705 return 0;
1706
1707 if (source && line > source->max_line)
1708 source->max_line = line;
1709 if (source && column > source->max_column)
1710 source->max_column = column;
1711
1712 if (!json_variant_is_regular(*v)) {
1713
1714 if (!source && line == 0 && column == 0)
1715 return 0;
1716
1717 } else {
1718 if (json_source_equal((*v)->source, source) &&
1719 (*v)->line == line &&
1720 (*v)->column == column)
1721 return 0;
1722
1723 if (json_single_ref(*v)) { /* Sole reference? */
1724 json_source_unref((*v)->source);
1725 (*v)->source = json_source_ref(source);
1726 (*v)->line = line;
1727 (*v)->column = column;
1728 return 1;
1729 }
1730 }
1731
1732 r = json_variant_copy(&w, *v);
1733 if (r < 0)
1734 return r;
1735
1736 assert(json_variant_is_regular(w));
1737 assert(!w->is_embedded);
1738 assert(w->n_ref == 1);
1739 assert(!w->source);
1740
1741 w->source = json_source_ref(source);
1742 w->line = line;
1743 w->column = column;
1744
1745 json_variant_unref(*v);
1746 *v = w;
1747
1748 return 1;
1749 }
1750
1751 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
1752 assert(line);
1753 assert(column);
1754 assert(s || n == 0);
1755
1756 while (n > 0) {
1757
1758 if (*s == '\n') {
1759 (*line)++;
1760 *column = 1;
1761 } else if ((signed char) *s >= 0 && *s < 127) /* Process ASCII chars quickly */
1762 (*column)++;
1763 else {
1764 int w;
1765
1766 w = utf8_encoded_valid_unichar(s);
1767 if (w < 0) /* count invalid unichars as normal characters */
1768 w = 1;
1769 else if ((size_t) w > n) /* never read more than the specified number of characters */
1770 w = (int) n;
1771
1772 (*column)++;
1773
1774 s += w;
1775 n -= w;
1776 continue;
1777 }
1778
1779 s++;
1780 n--;
1781 }
1782 }
1783
1784 static int unhex_ucs2(const char *c, uint16_t *ret) {
1785 int aa, bb, cc, dd;
1786 uint16_t x;
1787
1788 assert(c);
1789 assert(ret);
1790
1791 aa = unhexchar(c[0]);
1792 if (aa < 0)
1793 return -EINVAL;
1794
1795 bb = unhexchar(c[1]);
1796 if (bb < 0)
1797 return -EINVAL;
1798
1799 cc = unhexchar(c[2]);
1800 if (cc < 0)
1801 return -EINVAL;
1802
1803 dd = unhexchar(c[3]);
1804 if (dd < 0)
1805 return -EINVAL;
1806
1807 x = ((uint16_t) aa << 12) |
1808 ((uint16_t) bb << 8) |
1809 ((uint16_t) cc << 4) |
1810 ((uint16_t) dd);
1811
1812 if (x <= 0)
1813 return -EINVAL;
1814
1815 *ret = x;
1816
1817 return 0;
1818 }
1819
1820 static int json_parse_string(const char **p, char **ret) {
1821 _cleanup_free_ char *s = NULL;
1822 size_t n = 0, allocated = 0;
1823 const char *c;
1824
1825 assert(p);
1826 assert(*p);
1827 assert(ret);
1828
1829 c = *p;
1830
1831 if (*c != '"')
1832 return -EINVAL;
1833
1834 c++;
1835
1836 for (;;) {
1837 int len;
1838
1839 /* Check for EOF */
1840 if (*c == 0)
1841 return -EINVAL;
1842
1843 /* Check for control characters 0x00..0x1f */
1844 if (*c > 0 && *c < ' ')
1845 return -EINVAL;
1846
1847 /* Check for control character 0x7f */
1848 if (*c == 0x7f)
1849 return -EINVAL;
1850
1851 if (*c == '"') {
1852 if (!s) {
1853 s = strdup("");
1854 if (!s)
1855 return -ENOMEM;
1856 } else
1857 s[n] = 0;
1858
1859 *p = c + 1;
1860
1861 *ret = TAKE_PTR(s);
1862 return JSON_TOKEN_STRING;
1863 }
1864
1865 if (*c == '\\') {
1866 char ch = 0;
1867 c++;
1868
1869 if (*c == 0)
1870 return -EINVAL;
1871
1872 if (IN_SET(*c, '"', '\\', '/'))
1873 ch = *c;
1874 else if (*c == 'b')
1875 ch = '\b';
1876 else if (*c == 'f')
1877 ch = '\f';
1878 else if (*c == 'n')
1879 ch = '\n';
1880 else if (*c == 'r')
1881 ch = '\r';
1882 else if (*c == 't')
1883 ch = '\t';
1884 else if (*c == 'u') {
1885 char16_t x;
1886 int r;
1887
1888 r = unhex_ucs2(c + 1, &x);
1889 if (r < 0)
1890 return r;
1891
1892 c += 5;
1893
1894 if (!GREEDY_REALLOC(s, allocated, n + 5))
1895 return -ENOMEM;
1896
1897 if (!utf16_is_surrogate(x))
1898 n += utf8_encode_unichar(s + n, (char32_t) x);
1899 else if (utf16_is_trailing_surrogate(x))
1900 return -EINVAL;
1901 else {
1902 char16_t y;
1903
1904 if (c[0] != '\\' || c[1] != 'u')
1905 return -EINVAL;
1906
1907 r = unhex_ucs2(c + 2, &y);
1908 if (r < 0)
1909 return r;
1910
1911 c += 6;
1912
1913 if (!utf16_is_trailing_surrogate(y))
1914 return -EINVAL;
1915
1916 n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
1917 }
1918
1919 continue;
1920 } else
1921 return -EINVAL;
1922
1923 if (!GREEDY_REALLOC(s, allocated, n + 2))
1924 return -ENOMEM;
1925
1926 s[n++] = ch;
1927 c ++;
1928 continue;
1929 }
1930
1931 len = utf8_encoded_valid_unichar(c);
1932 if (len < 0)
1933 return len;
1934
1935 if (!GREEDY_REALLOC(s, allocated, n + len + 1))
1936 return -ENOMEM;
1937
1938 memcpy(s + n, c, len);
1939 n += len;
1940 c += len;
1941 }
1942 }
1943
1944 static int json_parse_number(const char **p, JsonValue *ret) {
1945 bool negative = false, exponent_negative = false, is_real = false;
1946 long double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
1947 intmax_t i = 0;
1948 uintmax_t u = 0;
1949 const char *c;
1950
1951 assert(p);
1952 assert(*p);
1953 assert(ret);
1954
1955 c = *p;
1956
1957 if (*c == '-') {
1958 negative = true;
1959 c++;
1960 }
1961
1962 if (*c == '0')
1963 c++;
1964 else {
1965 if (!strchr("123456789", *c) || *c == 0)
1966 return -EINVAL;
1967
1968 do {
1969 if (!is_real) {
1970 if (negative) {
1971
1972 if (i < INTMAX_MIN / 10) /* overflow */
1973 is_real = true;
1974 else {
1975 intmax_t t = 10 * i;
1976
1977 if (t < INTMAX_MIN + (*c - '0')) /* overflow */
1978 is_real = true;
1979 else
1980 i = t - (*c - '0');
1981 }
1982 } else {
1983 if (u > UINTMAX_MAX / 10) /* overflow */
1984 is_real = true;
1985 else {
1986 uintmax_t t = 10 * u;
1987
1988 if (t > UINTMAX_MAX - (*c - '0')) /* overflow */
1989 is_real = true;
1990 else
1991 u = t + (*c - '0');
1992 }
1993 }
1994 }
1995
1996 x = 10.0 * x + (*c - '0');
1997
1998 c++;
1999 } while (strchr("0123456789", *c) && *c != 0);
2000 }
2001
2002 if (*c == '.') {
2003 is_real = true;
2004 c++;
2005
2006 if (!strchr("0123456789", *c) || *c == 0)
2007 return -EINVAL;
2008
2009 do {
2010 y = 10.0 * y + (*c - '0');
2011 shift = 10.0 * shift;
2012 c++;
2013 } while (strchr("0123456789", *c) && *c != 0);
2014 }
2015
2016 if (IN_SET(*c, 'e', 'E')) {
2017 is_real = true;
2018 c++;
2019
2020 if (*c == '-') {
2021 exponent_negative = true;
2022 c++;
2023 } else if (*c == '+')
2024 c++;
2025
2026 if (!strchr("0123456789", *c) || *c == 0)
2027 return -EINVAL;
2028
2029 do {
2030 exponent = 10.0 * exponent + (*c - '0');
2031 c++;
2032 } while (strchr("0123456789", *c) && *c != 0);
2033 }
2034
2035 *p = c;
2036
2037 if (is_real) {
2038 ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10l((exponent_negative ? -1.0 : 1.0) * exponent);
2039 return JSON_TOKEN_REAL;
2040 } else if (negative) {
2041 ret->integer = i;
2042 return JSON_TOKEN_INTEGER;
2043 } else {
2044 ret->unsig = u;
2045 return JSON_TOKEN_UNSIGNED;
2046 }
2047 }
2048
2049 int json_tokenize(
2050 const char **p,
2051 char **ret_string,
2052 JsonValue *ret_value,
2053 unsigned *ret_line, /* 'ret_line' returns the line at the beginning of this token */
2054 unsigned *ret_column,
2055 void **state,
2056 unsigned *line, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2057 unsigned *column) {
2058
2059 unsigned start_line, start_column;
2060 const char *start, *c;
2061 size_t n;
2062 int t, r;
2063
2064 enum {
2065 STATE_NULL,
2066 STATE_VALUE,
2067 STATE_VALUE_POST,
2068 };
2069
2070 assert(p);
2071 assert(*p);
2072 assert(ret_string);
2073 assert(ret_value);
2074 assert(ret_line);
2075 assert(ret_column);
2076 assert(line);
2077 assert(column);
2078 assert(state);
2079
2080 t = PTR_TO_INT(*state);
2081 if (t == STATE_NULL) {
2082 *line = 1;
2083 *column = 1;
2084 t = STATE_VALUE;
2085 }
2086
2087 /* Skip over the whitespace */
2088 n = strspn(*p, WHITESPACE);
2089 inc_lines_columns(line, column, *p, n);
2090 c = *p + n;
2091
2092 /* Remember where we started processing this token */
2093 start = c;
2094 start_line = *line;
2095 start_column = *column;
2096
2097 if (*c == 0) {
2098 *ret_string = NULL;
2099 *ret_value = JSON_VALUE_NULL;
2100 r = JSON_TOKEN_END;
2101 goto finish;
2102 }
2103
2104 switch (t) {
2105
2106 case STATE_VALUE:
2107
2108 if (*c == '{') {
2109 c++;
2110 *state = INT_TO_PTR(STATE_VALUE);
2111 r = JSON_TOKEN_OBJECT_OPEN;
2112 goto null_return;
2113
2114 } else if (*c == '}') {
2115 c++;
2116 *state = INT_TO_PTR(STATE_VALUE_POST);
2117 r = JSON_TOKEN_OBJECT_CLOSE;
2118 goto null_return;
2119
2120 } else if (*c == '[') {
2121 c++;
2122 *state = INT_TO_PTR(STATE_VALUE);
2123 r = JSON_TOKEN_ARRAY_OPEN;
2124 goto null_return;
2125
2126 } else if (*c == ']') {
2127 c++;
2128 *state = INT_TO_PTR(STATE_VALUE_POST);
2129 r = JSON_TOKEN_ARRAY_CLOSE;
2130 goto null_return;
2131
2132 } else if (*c == '"') {
2133
2134 r = json_parse_string(&c, ret_string);
2135 if (r < 0)
2136 return r;
2137
2138 *ret_value = JSON_VALUE_NULL;
2139 *state = INT_TO_PTR(STATE_VALUE_POST);
2140 goto finish;
2141
2142 } else if (strchr("-0123456789", *c)) {
2143
2144 r = json_parse_number(&c, ret_value);
2145 if (r < 0)
2146 return r;
2147
2148 *ret_string = NULL;
2149 *state = INT_TO_PTR(STATE_VALUE_POST);
2150 goto finish;
2151
2152 } else if (startswith(c, "true")) {
2153 *ret_string = NULL;
2154 ret_value->boolean = true;
2155 c += 4;
2156 *state = INT_TO_PTR(STATE_VALUE_POST);
2157 r = JSON_TOKEN_BOOLEAN;
2158 goto finish;
2159
2160 } else if (startswith(c, "false")) {
2161 *ret_string = NULL;
2162 ret_value->boolean = false;
2163 c += 5;
2164 *state = INT_TO_PTR(STATE_VALUE_POST);
2165 r = JSON_TOKEN_BOOLEAN;
2166 goto finish;
2167
2168 } else if (startswith(c, "null")) {
2169 *ret_string = NULL;
2170 *ret_value = JSON_VALUE_NULL;
2171 c += 4;
2172 *state = INT_TO_PTR(STATE_VALUE_POST);
2173 r = JSON_TOKEN_NULL;
2174 goto finish;
2175
2176 }
2177
2178 return -EINVAL;
2179
2180 case STATE_VALUE_POST:
2181
2182 if (*c == ':') {
2183 c++;
2184 *state = INT_TO_PTR(STATE_VALUE);
2185 r = JSON_TOKEN_COLON;
2186 goto null_return;
2187
2188 } else if (*c == ',') {
2189 c++;
2190 *state = INT_TO_PTR(STATE_VALUE);
2191 r = JSON_TOKEN_COMMA;
2192 goto null_return;
2193
2194 } else if (*c == '}') {
2195 c++;
2196 *state = INT_TO_PTR(STATE_VALUE_POST);
2197 r = JSON_TOKEN_OBJECT_CLOSE;
2198 goto null_return;
2199
2200 } else if (*c == ']') {
2201 c++;
2202 *state = INT_TO_PTR(STATE_VALUE_POST);
2203 r = JSON_TOKEN_ARRAY_CLOSE;
2204 goto null_return;
2205 }
2206
2207 return -EINVAL;
2208
2209 default:
2210 assert_not_reached("Unexpected tokenizer state");
2211 }
2212
2213 null_return:
2214 *ret_string = NULL;
2215 *ret_value = JSON_VALUE_NULL;
2216
2217 finish:
2218 inc_lines_columns(line, column, start, c - start);
2219 *p = c;
2220
2221 *ret_line = start_line;
2222 *ret_column = start_column;
2223
2224 return r;
2225 }
2226
2227 typedef enum JsonExpect {
2228 /* The following values are used by json_parse() */
2229 EXPECT_TOPLEVEL,
2230 EXPECT_END,
2231 EXPECT_OBJECT_FIRST_KEY,
2232 EXPECT_OBJECT_NEXT_KEY,
2233 EXPECT_OBJECT_COLON,
2234 EXPECT_OBJECT_VALUE,
2235 EXPECT_OBJECT_COMMA,
2236 EXPECT_ARRAY_FIRST_ELEMENT,
2237 EXPECT_ARRAY_NEXT_ELEMENT,
2238 EXPECT_ARRAY_COMMA,
2239
2240 /* And these are used by json_build() */
2241 EXPECT_ARRAY_ELEMENT,
2242 EXPECT_OBJECT_KEY,
2243 } JsonExpect;
2244
2245 typedef struct JsonStack {
2246 JsonExpect expect;
2247 JsonVariant **elements;
2248 size_t n_elements, n_elements_allocated;
2249 unsigned line_before;
2250 unsigned column_before;
2251 size_t n_suppress; /* When building: if > 0, suppress this many subsequent elements. If == (size_t) -1, suppress all subsequent elements */
2252 } JsonStack;
2253
2254 static void json_stack_release(JsonStack *s) {
2255 assert(s);
2256
2257 json_variant_unref_many(s->elements, s->n_elements);
2258 s->elements = mfree(s->elements);
2259 }
2260
2261 static int json_parse_internal(
2262 const char **input,
2263 JsonSource *source,
2264 JsonVariant **ret,
2265 unsigned *line,
2266 unsigned *column,
2267 bool continue_end) {
2268
2269 size_t n_stack = 1, n_stack_allocated = 0, i;
2270 unsigned line_buffer = 0, column_buffer = 0;
2271 void *tokenizer_state = NULL;
2272 JsonStack *stack = NULL;
2273 const char *p;
2274 int r;
2275
2276 assert_return(input, -EINVAL);
2277 assert_return(ret, -EINVAL);
2278
2279 p = *input;
2280
2281 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack))
2282 return -ENOMEM;
2283
2284 stack[0] = (JsonStack) {
2285 .expect = EXPECT_TOPLEVEL,
2286 };
2287
2288 if (!line)
2289 line = &line_buffer;
2290 if (!column)
2291 column = &column_buffer;
2292
2293 for (;;) {
2294 _cleanup_free_ char *string = NULL;
2295 unsigned line_token, column_token;
2296 JsonVariant *add = NULL;
2297 JsonStack *current;
2298 JsonValue value;
2299 int token;
2300
2301 assert(n_stack > 0);
2302 current = stack + n_stack - 1;
2303
2304 if (continue_end && current->expect == EXPECT_END)
2305 goto done;
2306
2307 token = json_tokenize(&p, &string, &value, &line_token, &column_token, &tokenizer_state, line, column);
2308 if (token < 0) {
2309 r = token;
2310 goto finish;
2311 }
2312
2313 switch (token) {
2314
2315 case JSON_TOKEN_END:
2316 if (current->expect != EXPECT_END) {
2317 r = -EINVAL;
2318 goto finish;
2319 }
2320
2321 assert(current->n_elements == 1);
2322 assert(n_stack == 1);
2323 goto done;
2324
2325 case JSON_TOKEN_COLON:
2326
2327 if (current->expect != EXPECT_OBJECT_COLON) {
2328 r = -EINVAL;
2329 goto finish;
2330 }
2331
2332 current->expect = EXPECT_OBJECT_VALUE;
2333 break;
2334
2335 case JSON_TOKEN_COMMA:
2336
2337 if (current->expect == EXPECT_OBJECT_COMMA)
2338 current->expect = EXPECT_OBJECT_NEXT_KEY;
2339 else if (current->expect == EXPECT_ARRAY_COMMA)
2340 current->expect = EXPECT_ARRAY_NEXT_ELEMENT;
2341 else {
2342 r = -EINVAL;
2343 goto finish;
2344 }
2345
2346 break;
2347
2348 case JSON_TOKEN_OBJECT_OPEN:
2349
2350 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2351 r = -EINVAL;
2352 goto finish;
2353 }
2354
2355 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2356 r = -ENOMEM;
2357 goto finish;
2358 }
2359 current = stack + n_stack - 1;
2360
2361 /* Prepare the expect for when we return from the child */
2362 if (current->expect == EXPECT_TOPLEVEL)
2363 current->expect = EXPECT_END;
2364 else if (current->expect == EXPECT_OBJECT_VALUE)
2365 current->expect = EXPECT_OBJECT_COMMA;
2366 else {
2367 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2368 current->expect = EXPECT_ARRAY_COMMA;
2369 }
2370
2371 stack[n_stack++] = (JsonStack) {
2372 .expect = EXPECT_OBJECT_FIRST_KEY,
2373 .line_before = line_token,
2374 .column_before = column_token,
2375 };
2376
2377 current = stack + n_stack - 1;
2378 break;
2379
2380 case JSON_TOKEN_OBJECT_CLOSE:
2381 if (!IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_COMMA)) {
2382 r = -EINVAL;
2383 goto finish;
2384 }
2385
2386 assert(n_stack > 1);
2387
2388 r = json_variant_new_object(&add, current->elements, current->n_elements);
2389 if (r < 0)
2390 goto finish;
2391
2392 line_token = current->line_before;
2393 column_token = current->column_before;
2394
2395 json_stack_release(current);
2396 n_stack--, current--;
2397
2398 break;
2399
2400 case JSON_TOKEN_ARRAY_OPEN:
2401 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2402 r = -EINVAL;
2403 goto finish;
2404 }
2405
2406 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2407 r = -ENOMEM;
2408 goto finish;
2409 }
2410 current = stack + n_stack - 1;
2411
2412 /* Prepare the expect for when we return from the child */
2413 if (current->expect == EXPECT_TOPLEVEL)
2414 current->expect = EXPECT_END;
2415 else if (current->expect == EXPECT_OBJECT_VALUE)
2416 current->expect = EXPECT_OBJECT_COMMA;
2417 else {
2418 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2419 current->expect = EXPECT_ARRAY_COMMA;
2420 }
2421
2422 stack[n_stack++] = (JsonStack) {
2423 .expect = EXPECT_ARRAY_FIRST_ELEMENT,
2424 .line_before = line_token,
2425 .column_before = column_token,
2426 };
2427
2428 break;
2429
2430 case JSON_TOKEN_ARRAY_CLOSE:
2431 if (!IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_COMMA)) {
2432 r = -EINVAL;
2433 goto finish;
2434 }
2435
2436 assert(n_stack > 1);
2437
2438 r = json_variant_new_array(&add, current->elements, current->n_elements);
2439 if (r < 0)
2440 goto finish;
2441
2442 line_token = current->line_before;
2443 column_token = current->column_before;
2444
2445 json_stack_release(current);
2446 n_stack--, current--;
2447 break;
2448
2449 case JSON_TOKEN_STRING:
2450 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)) {
2451 r = -EINVAL;
2452 goto finish;
2453 }
2454
2455 r = json_variant_new_string(&add, string);
2456 if (r < 0)
2457 goto finish;
2458
2459 if (current->expect == EXPECT_TOPLEVEL)
2460 current->expect = EXPECT_END;
2461 else if (IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_NEXT_KEY))
2462 current->expect = EXPECT_OBJECT_COLON;
2463 else if (current->expect == EXPECT_OBJECT_VALUE)
2464 current->expect = EXPECT_OBJECT_COMMA;
2465 else {
2466 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2467 current->expect = EXPECT_ARRAY_COMMA;
2468 }
2469
2470 break;
2471
2472 case JSON_TOKEN_REAL:
2473 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2474 r = -EINVAL;
2475 goto finish;
2476 }
2477
2478 r = json_variant_new_real(&add, value.real);
2479 if (r < 0)
2480 goto finish;
2481
2482 if (current->expect == EXPECT_TOPLEVEL)
2483 current->expect = EXPECT_END;
2484 else if (current->expect == EXPECT_OBJECT_VALUE)
2485 current->expect = EXPECT_OBJECT_COMMA;
2486 else {
2487 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2488 current->expect = EXPECT_ARRAY_COMMA;
2489 }
2490
2491 break;
2492
2493 case JSON_TOKEN_INTEGER:
2494 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2495 r = -EINVAL;
2496 goto finish;
2497 }
2498
2499 r = json_variant_new_integer(&add, value.integer);
2500 if (r < 0)
2501 goto finish;
2502
2503 if (current->expect == EXPECT_TOPLEVEL)
2504 current->expect = EXPECT_END;
2505 else if (current->expect == EXPECT_OBJECT_VALUE)
2506 current->expect = EXPECT_OBJECT_COMMA;
2507 else {
2508 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2509 current->expect = EXPECT_ARRAY_COMMA;
2510 }
2511
2512 break;
2513
2514 case JSON_TOKEN_UNSIGNED:
2515 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2516 r = -EINVAL;
2517 goto finish;
2518 }
2519
2520 r = json_variant_new_unsigned(&add, value.unsig);
2521 if (r < 0)
2522 goto finish;
2523
2524 if (current->expect == EXPECT_TOPLEVEL)
2525 current->expect = EXPECT_END;
2526 else if (current->expect == EXPECT_OBJECT_VALUE)
2527 current->expect = EXPECT_OBJECT_COMMA;
2528 else {
2529 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2530 current->expect = EXPECT_ARRAY_COMMA;
2531 }
2532
2533 break;
2534
2535 case JSON_TOKEN_BOOLEAN:
2536 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2537 r = -EINVAL;
2538 goto finish;
2539 }
2540
2541 r = json_variant_new_boolean(&add, value.boolean);
2542 if (r < 0)
2543 goto finish;
2544
2545 if (current->expect == EXPECT_TOPLEVEL)
2546 current->expect = EXPECT_END;
2547 else if (current->expect == EXPECT_OBJECT_VALUE)
2548 current->expect = EXPECT_OBJECT_COMMA;
2549 else {
2550 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2551 current->expect = EXPECT_ARRAY_COMMA;
2552 }
2553
2554 break;
2555
2556 case JSON_TOKEN_NULL:
2557 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2558 r = -EINVAL;
2559 goto finish;
2560 }
2561
2562 r = json_variant_new_null(&add);
2563 if (r < 0)
2564 goto finish;
2565
2566 if (current->expect == EXPECT_TOPLEVEL)
2567 current->expect = EXPECT_END;
2568 else if (current->expect == EXPECT_OBJECT_VALUE)
2569 current->expect = EXPECT_OBJECT_COMMA;
2570 else {
2571 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2572 current->expect = EXPECT_ARRAY_COMMA;
2573 }
2574
2575 break;
2576
2577 default:
2578 assert_not_reached("Unexpected token");
2579 }
2580
2581 if (add) {
2582 (void) json_variant_set_source(&add, source, line_token, column_token);
2583
2584 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
2585 r = -ENOMEM;
2586 goto finish;
2587 }
2588
2589 current->elements[current->n_elements++] = add;
2590 }
2591 }
2592
2593 done:
2594 assert(n_stack == 1);
2595 assert(stack[0].n_elements == 1);
2596
2597 *ret = json_variant_ref(stack[0].elements[0]);
2598 *input = p;
2599 r = 0;
2600
2601 finish:
2602 for (i = 0; i < n_stack; i++)
2603 json_stack_release(stack + i);
2604
2605 free(stack);
2606
2607 return r;
2608 }
2609
2610 int json_parse(const char *input, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
2611 return json_parse_internal(&input, NULL, ret, ret_line, ret_column, false);
2612 }
2613
2614 int json_parse_continue(const char **p, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
2615 return json_parse_internal(p, NULL, ret, ret_line, ret_column, true);
2616 }
2617
2618 int json_parse_file(FILE *f, const char *path, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
2619 _cleanup_(json_source_unrefp) JsonSource *source = NULL;
2620 _cleanup_free_ char *text = NULL;
2621 const char *p;
2622 int r;
2623
2624 if (f)
2625 r = read_full_stream(f, &text, NULL);
2626 else if (path)
2627 r = read_full_file(path, &text, NULL);
2628 else
2629 return -EINVAL;
2630 if (r < 0)
2631 return r;
2632
2633 if (path) {
2634 source = json_source_new(path);
2635 if (!source)
2636 return -ENOMEM;
2637 }
2638
2639 p = text;
2640 return json_parse_internal(&p, source, ret, ret_line, ret_column, false);
2641 }
2642
2643 int json_buildv(JsonVariant **ret, va_list ap) {
2644 JsonStack *stack = NULL;
2645 size_t n_stack = 1, n_stack_allocated = 0, i;
2646 int r;
2647
2648 assert_return(ret, -EINVAL);
2649
2650 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack))
2651 return -ENOMEM;
2652
2653 stack[0] = (JsonStack) {
2654 .expect = EXPECT_TOPLEVEL,
2655 };
2656
2657 for (;;) {
2658 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL;
2659 size_t n_subtract = 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
2660 * have been added to the current variant */
2661 JsonStack *current;
2662 int command;
2663
2664 assert(n_stack > 0);
2665 current = stack + n_stack - 1;
2666
2667 if (current->expect == EXPECT_END)
2668 goto done;
2669
2670 command = va_arg(ap, int);
2671
2672 switch (command) {
2673
2674 case _JSON_BUILD_STRING: {
2675 const char *p;
2676
2677 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2678 r = -EINVAL;
2679 goto finish;
2680 }
2681
2682 p = va_arg(ap, const char *);
2683
2684 if (current->n_suppress == 0) {
2685 r = json_variant_new_string(&add, p);
2686 if (r < 0)
2687 goto finish;
2688 }
2689
2690 n_subtract = 1;
2691
2692 if (current->expect == EXPECT_TOPLEVEL)
2693 current->expect = EXPECT_END;
2694 else if (current->expect == EXPECT_OBJECT_VALUE)
2695 current->expect = EXPECT_OBJECT_KEY;
2696 else
2697 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2698
2699 break;
2700 }
2701
2702 case _JSON_BUILD_INTEGER: {
2703 intmax_t j;
2704
2705 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2706 r = -EINVAL;
2707 goto finish;
2708 }
2709
2710 j = va_arg(ap, intmax_t);
2711
2712 if (current->n_suppress == 0) {
2713 r = json_variant_new_integer(&add, j);
2714 if (r < 0)
2715 goto finish;
2716 }
2717
2718 n_subtract = 1;
2719
2720 if (current->expect == EXPECT_TOPLEVEL)
2721 current->expect = EXPECT_END;
2722 else if (current->expect == EXPECT_OBJECT_VALUE)
2723 current->expect = EXPECT_OBJECT_KEY;
2724 else
2725 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2726
2727 break;
2728 }
2729
2730 case _JSON_BUILD_UNSIGNED: {
2731 uintmax_t j;
2732
2733 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2734 r = -EINVAL;
2735 goto finish;
2736 }
2737
2738 j = va_arg(ap, uintmax_t);
2739
2740 if (current->n_suppress == 0) {
2741 r = json_variant_new_unsigned(&add, j);
2742 if (r < 0)
2743 goto finish;
2744 }
2745
2746 n_subtract = 1;
2747
2748 if (current->expect == EXPECT_TOPLEVEL)
2749 current->expect = EXPECT_END;
2750 else if (current->expect == EXPECT_OBJECT_VALUE)
2751 current->expect = EXPECT_OBJECT_KEY;
2752 else
2753 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2754
2755 break;
2756 }
2757
2758 case _JSON_BUILD_REAL: {
2759 long double d;
2760
2761 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2762 r = -EINVAL;
2763 goto finish;
2764 }
2765
2766 d = va_arg(ap, long double);
2767
2768 if (current->n_suppress == 0) {
2769 r = json_variant_new_real(&add, d);
2770 if (r < 0)
2771 goto finish;
2772 }
2773
2774 n_subtract = 1;
2775
2776 if (current->expect == EXPECT_TOPLEVEL)
2777 current->expect = EXPECT_END;
2778 else if (current->expect == EXPECT_OBJECT_VALUE)
2779 current->expect = EXPECT_OBJECT_KEY;
2780 else
2781 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2782
2783 break;
2784 }
2785
2786 case _JSON_BUILD_BOOLEAN: {
2787 bool b;
2788
2789 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2790 r = -EINVAL;
2791 goto finish;
2792 }
2793
2794 b = va_arg(ap, int);
2795
2796 if (current->n_suppress == 0) {
2797 r = json_variant_new_boolean(&add, b);
2798 if (r < 0)
2799 goto finish;
2800 }
2801
2802 n_subtract = 1;
2803
2804 if (current->expect == EXPECT_TOPLEVEL)
2805 current->expect = EXPECT_END;
2806 else if (current->expect == EXPECT_OBJECT_VALUE)
2807 current->expect = EXPECT_OBJECT_KEY;
2808 else
2809 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2810
2811 break;
2812 }
2813
2814 case _JSON_BUILD_NULL:
2815
2816 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2817 r = -EINVAL;
2818 goto finish;
2819 }
2820
2821 if (current->n_suppress == 0) {
2822 r = json_variant_new_null(&add);
2823 if (r < 0)
2824 goto finish;
2825 }
2826
2827 n_subtract = 1;
2828
2829 if (current->expect == EXPECT_TOPLEVEL)
2830 current->expect = EXPECT_END;
2831 else if (current->expect == EXPECT_OBJECT_VALUE)
2832 current->expect = EXPECT_OBJECT_KEY;
2833 else
2834 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2835
2836 break;
2837
2838 case _JSON_BUILD_VARIANT:
2839
2840 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2841 r = -EINVAL;
2842 goto finish;
2843 }
2844
2845 /* Note that we don't care for current->n_suppress here, after all the variant is already
2846 * allocated anyway... */
2847 add = va_arg(ap, JsonVariant*);
2848 if (!add)
2849 add = JSON_VARIANT_MAGIC_NULL;
2850 else
2851 json_variant_ref(add);
2852
2853 n_subtract = 1;
2854
2855 if (current->expect == EXPECT_TOPLEVEL)
2856 current->expect = EXPECT_END;
2857 else if (current->expect == EXPECT_OBJECT_VALUE)
2858 current->expect = EXPECT_OBJECT_KEY;
2859 else
2860 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2861
2862 break;
2863
2864 case _JSON_BUILD_LITERAL: {
2865 const char *l;
2866
2867 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2868 r = -EINVAL;
2869 goto finish;
2870 }
2871
2872 l = va_arg(ap, const char *);
2873
2874 if (l) {
2875 /* Note that we don't care for current->n_suppress here, we should generate parsing
2876 * errors even in suppressed object properties */
2877
2878 r = json_parse(l, &add, NULL, NULL);
2879 if (r < 0)
2880 goto finish;
2881 } else
2882 add = JSON_VARIANT_MAGIC_NULL;
2883
2884 n_subtract = 1;
2885
2886 if (current->expect == EXPECT_TOPLEVEL)
2887 current->expect = EXPECT_END;
2888 else if (current->expect == EXPECT_OBJECT_VALUE)
2889 current->expect = EXPECT_OBJECT_KEY;
2890 else
2891 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2892
2893 break;
2894 }
2895
2896 case _JSON_BUILD_ARRAY_BEGIN:
2897
2898 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2899 r = -EINVAL;
2900 goto finish;
2901 }
2902
2903 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2904 r = -ENOMEM;
2905 goto finish;
2906 }
2907 current = stack + n_stack - 1;
2908
2909 if (current->expect == EXPECT_TOPLEVEL)
2910 current->expect = EXPECT_END;
2911 else if (current->expect == EXPECT_OBJECT_VALUE)
2912 current->expect = EXPECT_OBJECT_KEY;
2913 else
2914 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2915
2916 stack[n_stack++] = (JsonStack) {
2917 .expect = EXPECT_ARRAY_ELEMENT,
2918 .n_suppress = current->n_suppress != 0 ? (size_t) -1 : 0, /* if we shall suppress the
2919 * new array, then we should
2920 * also suppress all array
2921 * members */
2922 };
2923
2924 break;
2925
2926 case _JSON_BUILD_ARRAY_END:
2927 if (current->expect != EXPECT_ARRAY_ELEMENT) {
2928 r = -EINVAL;
2929 goto finish;
2930 }
2931
2932 assert(n_stack > 1);
2933
2934 if (current->n_suppress == 0) {
2935 r = json_variant_new_array(&add, current->elements, current->n_elements);
2936 if (r < 0)
2937 goto finish;
2938 }
2939
2940 n_subtract = 1;
2941
2942 json_stack_release(current);
2943 n_stack--, current--;
2944
2945 break;
2946
2947 case _JSON_BUILD_STRV: {
2948 char **l;
2949
2950 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2951 r = -EINVAL;
2952 goto finish;
2953 }
2954
2955 l = va_arg(ap, char **);
2956
2957 if (current->n_suppress == 0) {
2958 r = json_variant_new_array_strv(&add, l);
2959 if (r < 0)
2960 goto finish;
2961 }
2962
2963 n_subtract = 1;
2964
2965 if (current->expect == EXPECT_TOPLEVEL)
2966 current->expect = EXPECT_END;
2967 else if (current->expect == EXPECT_OBJECT_VALUE)
2968 current->expect = EXPECT_OBJECT_KEY;
2969 else
2970 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2971
2972 break;
2973 }
2974
2975 case _JSON_BUILD_OBJECT_BEGIN:
2976
2977 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2978 r = -EINVAL;
2979 goto finish;
2980 }
2981
2982 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2983 r = -ENOMEM;
2984 goto finish;
2985 }
2986 current = stack + n_stack - 1;
2987
2988 if (current->expect == EXPECT_TOPLEVEL)
2989 current->expect = EXPECT_END;
2990 else if (current->expect == EXPECT_OBJECT_VALUE)
2991 current->expect = EXPECT_OBJECT_KEY;
2992 else
2993 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2994
2995 stack[n_stack++] = (JsonStack) {
2996 .expect = EXPECT_OBJECT_KEY,
2997 .n_suppress = current->n_suppress != 0 ? (size_t) -1 : 0, /* if we shall suppress the
2998 * new object, then we should
2999 * also suppress all object
3000 * members */
3001 };
3002
3003 break;
3004
3005 case _JSON_BUILD_OBJECT_END:
3006
3007 if (current->expect != EXPECT_OBJECT_KEY) {
3008 r = -EINVAL;
3009 goto finish;
3010 }
3011
3012 assert(n_stack > 1);
3013
3014 if (current->n_suppress == 0) {
3015 r = json_variant_new_object(&add, current->elements, current->n_elements);
3016 if (r < 0)
3017 goto finish;
3018 }
3019
3020 n_subtract = 1;
3021
3022 json_stack_release(current);
3023 n_stack--, current--;
3024
3025 break;
3026
3027 case _JSON_BUILD_PAIR: {
3028 const char *n;
3029
3030 if (current->expect != EXPECT_OBJECT_KEY) {
3031 r = -EINVAL;
3032 goto finish;
3033 }
3034
3035 n = va_arg(ap, const char *);
3036
3037 if (current->n_suppress == 0) {
3038 r = json_variant_new_string(&add, n);
3039 if (r < 0)
3040 goto finish;
3041 }
3042
3043 n_subtract = 1;
3044
3045 current->expect = EXPECT_OBJECT_VALUE;
3046 break;
3047 }
3048
3049 case _JSON_BUILD_PAIR_CONDITION: {
3050 const char *n;
3051 bool b;
3052
3053 if (current->expect != EXPECT_OBJECT_KEY) {
3054 r = -EINVAL;
3055 goto finish;
3056 }
3057
3058 b = va_arg(ap, int);
3059 n = va_arg(ap, const char *);
3060
3061 if (b && current->n_suppress == 0) {
3062 r = json_variant_new_string(&add, n);
3063 if (r < 0)
3064 goto finish;
3065 }
3066
3067 n_subtract = 1; /* we generated one item */
3068
3069 if (!b && current->n_suppress != (size_t) -1)
3070 current->n_suppress += 2; /* Suppress this one and the next item */
3071
3072 current->expect = EXPECT_OBJECT_VALUE;
3073 break;
3074 }}
3075
3076 /* If a variant was generated, add it to our current variant, but only if we are not supposed to suppress additions */
3077 if (add && current->n_suppress == 0) {
3078 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
3079 r = -ENOMEM;
3080 goto finish;
3081 }
3082
3083 current->elements[current->n_elements++] = TAKE_PTR(add);
3084 }
3085
3086 /* If we are supposed to suppress items, let's subtract how many items where generated from that
3087 * counter. Except if the counter is (size_t) -1, i.e. we shall suppress an infinite number of elements
3088 * on this stack level */
3089 if (current->n_suppress != (size_t) -1) {
3090 if (current->n_suppress <= n_subtract) /* Saturated */
3091 current->n_suppress = 0;
3092 else
3093 current->n_suppress -= n_subtract;
3094 }
3095 }
3096
3097 done:
3098 assert(n_stack == 1);
3099 assert(stack[0].n_elements == 1);
3100
3101 *ret = json_variant_ref(stack[0].elements[0]);
3102 r = 0;
3103
3104 finish:
3105 for (i = 0; i < n_stack; i++)
3106 json_stack_release(stack + i);
3107
3108 free(stack);
3109
3110 va_end(ap);
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 if (error < 0)
3144 error = -error;
3145
3146 errno = error;
3147
3148 va_start(ap, format);
3149 (void) vsnprintf(buffer, sizeof buffer, format, ap);
3150 va_end(ap);
3151
3152 if (variant) {
3153 r = json_variant_get_source(variant, &source, &source_line, &source_column);
3154 if (r < 0)
3155 return r;
3156 } else {
3157 source = NULL;
3158 source_line = 0;
3159 source_column = 0;
3160 }
3161
3162 if (source && source_line > 0 && source_column > 0)
3163 return log_struct_internal(
3164 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3165 error,
3166 file, line, func,
3167 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3168 "CONFIG_FILE=%s", source,
3169 "CONFIG_LINE=%u", source_line,
3170 "CONFIG_COLUMN=%u", source_column,
3171 LOG_MESSAGE("%s:%u: %s", source, line, buffer),
3172 NULL);
3173 else
3174 return log_struct_internal(
3175 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3176 error,
3177 file, line, func,
3178 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3179 LOG_MESSAGE("%s", buffer),
3180 NULL);
3181 }
3182
3183 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) {
3184 const JsonDispatch *p;
3185 size_t i, n, m;
3186 int r, done = 0;
3187 bool *found;
3188
3189 if (!json_variant_is_object(v)) {
3190 json_log(v, flags, 0, "JSON variant is not an object.");
3191
3192 if (flags & JSON_PERMISSIVE)
3193 return 0;
3194
3195 return -EINVAL;
3196 }
3197
3198 for (p = table, m = 0; p->name; p++)
3199 m++;
3200
3201 found = newa0(bool, m);
3202
3203 n = json_variant_elements(v);
3204 for (i = 0; i < n; i += 2) {
3205 JsonVariant *key, *value;
3206
3207 assert_se(key = json_variant_by_index(v, i));
3208 assert_se(value = json_variant_by_index(v, i+1));
3209
3210 for (p = table; p->name; p++)
3211 if (p->name == (const char*) -1 ||
3212 streq_ptr(json_variant_string(key), p->name))
3213 break;
3214
3215 if (p->name) { /* Found a matching entry! :-) */
3216 JsonDispatchFlags merged_flags;
3217
3218 merged_flags = flags | p->flags;
3219
3220 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
3221 !json_variant_has_type(value, p->type)) {
3222
3223 json_log(value, merged_flags, 0,
3224 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
3225 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
3226
3227 if (merged_flags & JSON_PERMISSIVE)
3228 continue;
3229
3230 return -EINVAL;
3231 }
3232
3233 if (found[p-table]) {
3234 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
3235
3236 if (merged_flags & JSON_PERMISSIVE)
3237 continue;
3238
3239 return -ENOTUNIQ;
3240 }
3241
3242 found[p-table] = true;
3243
3244 if (p->callback) {
3245 r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset);
3246 if (r < 0) {
3247 if (merged_flags & JSON_PERMISSIVE)
3248 continue;
3249
3250 return r;
3251 }
3252 }
3253
3254 done ++;
3255
3256 } else { /* Didn't find a matching entry! :-( */
3257
3258 if (bad) {
3259 r = bad(json_variant_string(key), value, flags, userdata);
3260 if (r < 0) {
3261 if (flags & JSON_PERMISSIVE)
3262 continue;
3263
3264 return r;
3265 } else
3266 done ++;
3267
3268 } else {
3269 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
3270
3271 if (flags & JSON_PERMISSIVE)
3272 continue;
3273
3274 return -EADDRNOTAVAIL;
3275 }
3276 }
3277 }
3278
3279 for (p = table; p->name; p++) {
3280 JsonDispatchFlags merged_flags = p->flags | flags;
3281
3282 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
3283 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
3284
3285 if ((merged_flags & JSON_PERMISSIVE))
3286 continue;
3287
3288 return -ENXIO;
3289 }
3290 }
3291
3292 return done;
3293 }
3294
3295 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3296 bool *b = userdata;
3297
3298 assert(variant);
3299 assert(b);
3300
3301 if (!json_variant_is_boolean(variant)) {
3302 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3303 return -EINVAL;
3304 }
3305
3306 *b = json_variant_boolean(variant);
3307 return 0;
3308 }
3309
3310 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3311 int *b = userdata;
3312
3313 assert(variant);
3314 assert(b);
3315
3316 if (!json_variant_is_boolean(variant)) {
3317 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3318 return -EINVAL;
3319 }
3320
3321 *b = json_variant_boolean(variant);
3322 return 0;
3323 }
3324
3325 int json_dispatch_integer(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3326 intmax_t *i = userdata;
3327
3328 assert(variant);
3329 assert(i);
3330
3331 if (!json_variant_is_integer(variant)) {
3332 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3333 return -EINVAL;
3334 }
3335
3336 *i = json_variant_integer(variant);
3337 return 0;
3338 }
3339
3340 int json_dispatch_unsigned(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3341 uintmax_t *u = userdata;
3342
3343 assert(variant);
3344 assert(u);
3345
3346 if (!json_variant_is_unsigned(variant)) {
3347 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3348 return -EINVAL;
3349 }
3350
3351 *u = json_variant_unsigned(variant);
3352 return 0;
3353 }
3354
3355 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3356 uint32_t *u = userdata;
3357
3358 assert(variant);
3359 assert(u);
3360
3361 if (!json_variant_is_unsigned(variant)) {
3362 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3363 return -EINVAL;
3364 }
3365
3366 if (json_variant_unsigned(variant) > UINT32_MAX) {
3367 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3368 return -ERANGE;
3369 }
3370
3371 *u = (uint32_t) json_variant_unsigned(variant);
3372 return 0;
3373 }
3374
3375 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3376 int32_t *i = userdata;
3377
3378 assert(variant);
3379 assert(i);
3380
3381 if (!json_variant_is_integer(variant)) {
3382 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3383 return -EINVAL;
3384 }
3385
3386 if (json_variant_integer(variant) < INT32_MIN || json_variant_integer(variant) > INT32_MAX) {
3387 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3388 return -ERANGE;
3389 }
3390
3391 *i = (int32_t) json_variant_integer(variant);
3392 return 0;
3393 }
3394
3395 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3396 char **s = userdata;
3397 int r;
3398
3399 assert(variant);
3400 assert(s);
3401
3402 if (json_variant_is_null(variant)) {
3403 *s = mfree(*s);
3404 return 0;
3405 }
3406
3407 if (!json_variant_is_string(variant)) {
3408 json_log(variant, flags, 0, "JSON field '%s' is not a string.", strna(name));
3409 return -EINVAL;
3410 }
3411
3412 r = free_and_strdup(s, json_variant_string(variant));
3413 if (r < 0)
3414 return json_log(variant, flags, r, "Failed to allocate string: %m");
3415
3416 return 0;
3417 }
3418
3419 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3420 _cleanup_strv_free_ char **l = NULL;
3421 char ***s = userdata;
3422 size_t i;
3423 int r;
3424
3425 assert(variant);
3426 assert(s);
3427
3428 if (json_variant_is_null(variant)) {
3429 *s = strv_free(*s);
3430 return 0;
3431 }
3432
3433 if (!json_variant_is_array(variant)) {
3434 json_log(variant, 0, flags, "JSON field '%s' is not an array.", strna(name));
3435 return -EINVAL;
3436 }
3437
3438 for (i = 0; i < json_variant_elements(variant); i++) {
3439 JsonVariant *e;
3440
3441 assert_se(e = json_variant_by_index(variant, i));
3442
3443 if (!json_variant_is_string(e)) {
3444 json_log(e, 0, flags, "JSON array element is not a string.");
3445 return -EINVAL;
3446 }
3447
3448 r = strv_extend(&l, json_variant_string(e));
3449 if (r < 0)
3450 return json_log(variant, flags, r, "Failed to append array element: %m");
3451 }
3452
3453 strv_free_and_replace(*s, l);
3454 return 0;
3455 }
3456
3457 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3458 JsonVariant **p = userdata;
3459
3460 assert(variant);
3461 assert(p);
3462
3463 json_variant_unref(*p);
3464 *p = json_variant_ref(variant);
3465
3466 return 0;
3467 }
3468
3469 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
3470 [JSON_VARIANT_STRING] = "string",
3471 [JSON_VARIANT_INTEGER] = "integer",
3472 [JSON_VARIANT_UNSIGNED] = "unsigned",
3473 [JSON_VARIANT_REAL] = "real",
3474 [JSON_VARIANT_NUMBER] = "number",
3475 [JSON_VARIANT_BOOLEAN] = "boolean",
3476 [JSON_VARIANT_ARRAY] = "array",
3477 [JSON_VARIANT_OBJECT] = "object",
3478 [JSON_VARIANT_NULL] = "null",
3479 };
3480
3481 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);