]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/json.c
pkgconfig: define variables relative to ${prefix}/${rootprefix}/${sysconfdir}
[thirdparty/systemd.git] / src / basic / 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, unsigned 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, unsigned 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 '/':
1385 fputs("\\/", f);
1386 break;
1387
1388 case '\b':
1389 fputs("\\b", f);
1390 break;
1391
1392 case '\f':
1393 fputs("\\f", f);
1394 break;
1395
1396 case '\n':
1397 fputs("\\n", f);
1398 break;
1399
1400 case '\r':
1401 fputs("\\r", f);
1402 break;
1403
1404 case '\t':
1405 fputs("\\t", f);
1406 break;
1407
1408 default:
1409 if ((signed char) *q >= 0 && *q < ' ')
1410 fprintf(f, "\\u%04x", *q);
1411 else
1412 fputc(*q, f);
1413 break;
1414 }
1415 }
1416
1417 if (flags & JSON_FORMAT_COLOR)
1418 fputs(ANSI_NORMAL, f);
1419
1420 fputc('"', f);
1421 break;
1422 }
1423
1424 case JSON_VARIANT_ARRAY: {
1425 size_t i, n;
1426
1427 n = json_variant_elements(v);
1428
1429 if (n == 0)
1430 fputs("[]", f);
1431 else {
1432 _cleanup_free_ char *joined = NULL;
1433 const char *prefix2;
1434
1435 if (flags & JSON_FORMAT_PRETTY) {
1436 joined = strjoin(strempty(prefix), "\t");
1437 if (!joined)
1438 return -ENOMEM;
1439
1440 prefix2 = joined;
1441 fputs("[\n", f);
1442 } else {
1443 prefix2 = strempty(prefix);
1444 fputc('[', f);
1445 }
1446
1447 for (i = 0; i < n; i++) {
1448 JsonVariant *e;
1449
1450 assert_se(e = json_variant_by_index(v, i));
1451
1452 if (i > 0) {
1453 if (flags & JSON_FORMAT_PRETTY)
1454 fputs(",\n", f);
1455 else
1456 fputc(',', f);
1457 }
1458
1459 if (flags & JSON_FORMAT_PRETTY) {
1460 print_source(f, e, flags, false);
1461 fputs(prefix2, f);
1462 }
1463
1464 r = json_format(f, e, flags, prefix2);
1465 if (r < 0)
1466 return r;
1467 }
1468
1469 if (flags & JSON_FORMAT_PRETTY) {
1470 fputc('\n', f);
1471 print_source(f, v, flags, true);
1472 fputs(strempty(prefix), f);
1473 }
1474
1475 fputc(']', f);
1476 }
1477 break;
1478 }
1479
1480 case JSON_VARIANT_OBJECT: {
1481 size_t i, n;
1482
1483 n = json_variant_elements(v);
1484
1485 if (n == 0)
1486 fputs("{}", f);
1487 else {
1488 _cleanup_free_ char *joined = NULL;
1489 const char *prefix2;
1490
1491 if (flags & JSON_FORMAT_PRETTY) {
1492 joined = strjoin(strempty(prefix), "\t");
1493 if (!joined)
1494 return -ENOMEM;
1495
1496 prefix2 = joined;
1497 fputs("{\n", f);
1498 } else {
1499 prefix2 = strempty(prefix);
1500 fputc('{', f);
1501 }
1502
1503 for (i = 0; i < n; i += 2) {
1504 JsonVariant *e;
1505
1506 e = json_variant_by_index(v, i);
1507
1508 if (i > 0) {
1509 if (flags & JSON_FORMAT_PRETTY)
1510 fputs(",\n", f);
1511 else
1512 fputc(',', f);
1513 }
1514
1515 if (flags & JSON_FORMAT_PRETTY) {
1516 print_source(f, e, flags, false);
1517 fputs(prefix2, f);
1518 }
1519
1520 r = json_format(f, e, flags, prefix2);
1521 if (r < 0)
1522 return r;
1523
1524 fputs(flags & JSON_FORMAT_PRETTY ? " : " : ":", f);
1525
1526 r = json_format(f, json_variant_by_index(v, i+1), flags, prefix2);
1527 if (r < 0)
1528 return r;
1529 }
1530
1531 if (flags & JSON_FORMAT_PRETTY) {
1532 fputc('\n', f);
1533 print_source(f, v, flags, true);
1534 fputs(strempty(prefix), f);
1535 }
1536
1537 fputc('}', f);
1538 }
1539 break;
1540 }
1541
1542 default:
1543 assert_not_reached("Unexpected variant type.");
1544 }
1545
1546 return 0;
1547 }
1548
1549 int json_variant_format(JsonVariant *v, unsigned flags, char **ret) {
1550 _cleanup_free_ char *s = NULL;
1551 size_t sz = 0;
1552 int r;
1553
1554 assert_return(v, -EINVAL);
1555 assert_return(ret, -EINVAL);
1556
1557 {
1558 _cleanup_fclose_ FILE *f = NULL;
1559
1560 f = open_memstream(&s, &sz);
1561 if (!f)
1562 return -ENOMEM;
1563
1564 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
1565
1566 json_variant_dump(v, flags, f, NULL);
1567
1568 r = fflush_and_check(f);
1569 }
1570 if (r < 0)
1571 return r;
1572
1573 assert(s);
1574 *ret = TAKE_PTR(s);
1575
1576 return (int) sz;
1577 }
1578
1579 void json_variant_dump(JsonVariant *v, unsigned flags, FILE *f, const char *prefix) {
1580 if (!v)
1581 return;
1582
1583 if (!f)
1584 f = stdout;
1585
1586 print_source(f, v, flags, false);
1587
1588 if (flags & JSON_FORMAT_SSE)
1589 fputs("data: ", f);
1590 if (flags & JSON_FORMAT_SEQ)
1591 fputc('\x1e', f); /* ASCII Record Separator */
1592
1593 json_format(f, v, flags, prefix);
1594
1595 if (flags & (JSON_FORMAT_PRETTY|JSON_FORMAT_SEQ|JSON_FORMAT_SSE|JSON_FORMAT_NEWLINE))
1596 fputc('\n', f);
1597 if (flags & JSON_FORMAT_SSE)
1598 fputc('\n', f); /* In case of SSE add a second newline */
1599 }
1600
1601 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
1602 JsonVariantType t;
1603 JsonVariant *c;
1604 JsonValue value;
1605 const void *source;
1606 size_t k;
1607
1608 assert(nv);
1609 assert(v);
1610
1611 /* Let's copy the simple types literally, and the larger types by references */
1612 t = json_variant_type(v);
1613 switch (t) {
1614 case JSON_VARIANT_INTEGER:
1615 k = sizeof(intmax_t);
1616 value.integer = json_variant_integer(v);
1617 source = &value;
1618 break;
1619
1620 case JSON_VARIANT_UNSIGNED:
1621 k = sizeof(uintmax_t);
1622 value.unsig = json_variant_unsigned(v);
1623 source = &value;
1624 break;
1625
1626 case JSON_VARIANT_REAL:
1627 k = sizeof(long double);
1628 value.real = json_variant_real(v);
1629 source = &value;
1630 break;
1631
1632 case JSON_VARIANT_BOOLEAN:
1633 k = sizeof(bool);
1634 value.boolean = json_variant_boolean(v);
1635 source = &value;
1636 break;
1637
1638 case JSON_VARIANT_NULL:
1639 k = 0;
1640 source = NULL;
1641 break;
1642
1643 case JSON_VARIANT_STRING:
1644 source = json_variant_string(v);
1645 k = strnlen(source, INLINE_STRING_MAX + 1);
1646 if (k <= INLINE_STRING_MAX) {
1647 k ++;
1648 break;
1649 }
1650
1651 _fallthrough_;
1652
1653 default:
1654 /* Everything else copy by reference */
1655
1656 c = malloc0(offsetof(JsonVariant, reference) + sizeof(JsonVariant*));
1657 if (!c)
1658 return -ENOMEM;
1659
1660 c->n_ref = 1;
1661 c->type = t;
1662 c->is_reference = true;
1663 c->reference = json_variant_ref(json_variant_normalize(v));
1664
1665 *nv = c;
1666 return 0;
1667 }
1668
1669 c = malloc0(offsetof(JsonVariant, value) + k);
1670 if (!c)
1671 return -ENOMEM;
1672
1673 c->n_ref = 1;
1674 c->type = t;
1675
1676 memcpy_safe(&c->value, source, k);
1677
1678 *nv = c;
1679 return 0;
1680 }
1681
1682 static bool json_single_ref(JsonVariant *v) {
1683
1684 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
1685
1686 if (!json_variant_is_regular(v))
1687 return false;
1688
1689 if (v->is_embedded)
1690 return json_single_ref(v->parent);
1691
1692 assert(v->n_ref > 0);
1693 return v->n_ref == 1;
1694 }
1695
1696 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
1697 JsonVariant *w;
1698 int r;
1699
1700 assert(v);
1701
1702 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole referencer of
1703 * the object. If not, allocates a new object, possibly a surrogate for the original one */
1704
1705 if (!*v)
1706 return 0;
1707
1708 if (source && line > source->max_line)
1709 source->max_line = line;
1710 if (source && column > source->max_column)
1711 source->max_column = column;
1712
1713 if (!json_variant_is_regular(*v)) {
1714
1715 if (!source && line == 0 && column == 0)
1716 return 0;
1717
1718 } else {
1719 if (json_source_equal((*v)->source, source) &&
1720 (*v)->line == line &&
1721 (*v)->column == column)
1722 return 0;
1723
1724 if (json_single_ref(*v)) { /* Sole reference? */
1725 json_source_unref((*v)->source);
1726 (*v)->source = json_source_ref(source);
1727 (*v)->line = line;
1728 (*v)->column = column;
1729 return 1;
1730 }
1731 }
1732
1733 r = json_variant_copy(&w, *v);
1734 if (r < 0)
1735 return r;
1736
1737 assert(json_variant_is_regular(w));
1738 assert(!w->is_embedded);
1739 assert(w->n_ref == 1);
1740 assert(!w->source);
1741
1742 w->source = json_source_ref(source);
1743 w->line = line;
1744 w->column = column;
1745
1746 json_variant_unref(*v);
1747 *v = w;
1748
1749 return 1;
1750 }
1751
1752 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
1753 assert(line);
1754 assert(column);
1755 assert(s || n == 0);
1756
1757 while (n > 0) {
1758
1759 if (*s == '\n') {
1760 (*line)++;
1761 *column = 1;
1762 } else if ((signed char) *s >= 0 && *s < 127) /* Process ASCII chars quickly */
1763 (*column)++;
1764 else {
1765 int w;
1766
1767 w = utf8_encoded_valid_unichar(s);
1768 if (w < 0) /* count invalid unichars as normal characters */
1769 w = 1;
1770 else if ((size_t) w > n) /* never read more than the specified number of characters */
1771 w = (int) n;
1772
1773 (*column)++;
1774
1775 s += w;
1776 n -= w;
1777 continue;
1778 }
1779
1780 s++;
1781 n--;
1782 }
1783 }
1784
1785 static int unhex_ucs2(const char *c, uint16_t *ret) {
1786 int aa, bb, cc, dd;
1787 uint16_t x;
1788
1789 assert(c);
1790 assert(ret);
1791
1792 aa = unhexchar(c[0]);
1793 if (aa < 0)
1794 return -EINVAL;
1795
1796 bb = unhexchar(c[1]);
1797 if (bb < 0)
1798 return -EINVAL;
1799
1800 cc = unhexchar(c[2]);
1801 if (cc < 0)
1802 return -EINVAL;
1803
1804 dd = unhexchar(c[3]);
1805 if (dd < 0)
1806 return -EINVAL;
1807
1808 x = ((uint16_t) aa << 12) |
1809 ((uint16_t) bb << 8) |
1810 ((uint16_t) cc << 4) |
1811 ((uint16_t) dd);
1812
1813 if (x <= 0)
1814 return -EINVAL;
1815
1816 *ret = x;
1817
1818 return 0;
1819 }
1820
1821 static int json_parse_string(const char **p, char **ret) {
1822 _cleanup_free_ char *s = NULL;
1823 size_t n = 0, allocated = 0;
1824 const char *c;
1825
1826 assert(p);
1827 assert(*p);
1828 assert(ret);
1829
1830 c = *p;
1831
1832 if (*c != '"')
1833 return -EINVAL;
1834
1835 c++;
1836
1837 for (;;) {
1838 int len;
1839
1840 /* Check for EOF */
1841 if (*c == 0)
1842 return -EINVAL;
1843
1844 /* Check for control characters 0x00..0x1f */
1845 if (*c > 0 && *c < ' ')
1846 return -EINVAL;
1847
1848 /* Check for control character 0x7f */
1849 if (*c == 0x7f)
1850 return -EINVAL;
1851
1852 if (*c == '"') {
1853 if (!s) {
1854 s = strdup("");
1855 if (!s)
1856 return -ENOMEM;
1857 } else
1858 s[n] = 0;
1859
1860 *p = c + 1;
1861
1862 *ret = TAKE_PTR(s);
1863 return JSON_TOKEN_STRING;
1864 }
1865
1866 if (*c == '\\') {
1867 char ch = 0;
1868 c++;
1869
1870 if (*c == 0)
1871 return -EINVAL;
1872
1873 if (IN_SET(*c, '"', '\\', '/'))
1874 ch = *c;
1875 else if (*c == 'b')
1876 ch = '\b';
1877 else if (*c == 'f')
1878 ch = '\f';
1879 else if (*c == 'n')
1880 ch = '\n';
1881 else if (*c == 'r')
1882 ch = '\r';
1883 else if (*c == 't')
1884 ch = '\t';
1885 else if (*c == 'u') {
1886 char16_t x;
1887 int r;
1888
1889 r = unhex_ucs2(c + 1, &x);
1890 if (r < 0)
1891 return r;
1892
1893 c += 5;
1894
1895 if (!GREEDY_REALLOC(s, allocated, n + 5))
1896 return -ENOMEM;
1897
1898 if (!utf16_is_surrogate(x))
1899 n += utf8_encode_unichar(s + n, (char32_t) x);
1900 else if (utf16_is_trailing_surrogate(x))
1901 return -EINVAL;
1902 else {
1903 char16_t y;
1904
1905 if (c[0] != '\\' || c[1] != 'u')
1906 return -EINVAL;
1907
1908 r = unhex_ucs2(c + 2, &y);
1909 if (r < 0)
1910 return r;
1911
1912 c += 6;
1913
1914 if (!utf16_is_trailing_surrogate(y))
1915 return -EINVAL;
1916
1917 n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
1918 }
1919
1920 continue;
1921 } else
1922 return -EINVAL;
1923
1924 if (!GREEDY_REALLOC(s, allocated, n + 2))
1925 return -ENOMEM;
1926
1927 s[n++] = ch;
1928 c ++;
1929 continue;
1930 }
1931
1932 len = utf8_encoded_valid_unichar(c);
1933 if (len < 0)
1934 return len;
1935
1936 if (!GREEDY_REALLOC(s, allocated, n + len + 1))
1937 return -ENOMEM;
1938
1939 memcpy(s + n, c, len);
1940 n += len;
1941 c += len;
1942 }
1943 }
1944
1945 static int json_parse_number(const char **p, JsonValue *ret) {
1946 bool negative = false, exponent_negative = false, is_real = false;
1947 long double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
1948 intmax_t i = 0;
1949 uintmax_t u = 0;
1950 const char *c;
1951
1952 assert(p);
1953 assert(*p);
1954 assert(ret);
1955
1956 c = *p;
1957
1958 if (*c == '-') {
1959 negative = true;
1960 c++;
1961 }
1962
1963 if (*c == '0')
1964 c++;
1965 else {
1966 if (!strchr("123456789", *c) || *c == 0)
1967 return -EINVAL;
1968
1969 do {
1970 if (!is_real) {
1971 if (negative) {
1972
1973 if (i < INTMAX_MIN / 10) /* overflow */
1974 is_real = true;
1975 else {
1976 intmax_t t = 10 * i;
1977
1978 if (t < INTMAX_MIN + (*c - '0')) /* overflow */
1979 is_real = true;
1980 else
1981 i = t - (*c - '0');
1982 }
1983 } else {
1984 if (u > UINTMAX_MAX / 10) /* overflow */
1985 is_real = true;
1986 else {
1987 uintmax_t t = 10 * u;
1988
1989 if (t > UINTMAX_MAX - (*c - '0')) /* overflow */
1990 is_real = true;
1991 else
1992 u = t + (*c - '0');
1993 }
1994 }
1995 }
1996
1997 x = 10.0 * x + (*c - '0');
1998
1999 c++;
2000 } while (strchr("0123456789", *c) && *c != 0);
2001 }
2002
2003 if (*c == '.') {
2004 is_real = true;
2005 c++;
2006
2007 if (!strchr("0123456789", *c) || *c == 0)
2008 return -EINVAL;
2009
2010 do {
2011 y = 10.0 * y + (*c - '0');
2012 shift = 10.0 * shift;
2013 c++;
2014 } while (strchr("0123456789", *c) && *c != 0);
2015 }
2016
2017 if (IN_SET(*c, 'e', 'E')) {
2018 is_real = true;
2019 c++;
2020
2021 if (*c == '-') {
2022 exponent_negative = true;
2023 c++;
2024 } else if (*c == '+')
2025 c++;
2026
2027 if (!strchr("0123456789", *c) || *c == 0)
2028 return -EINVAL;
2029
2030 do {
2031 exponent = 10.0 * exponent + (*c - '0');
2032 c++;
2033 } while (strchr("0123456789", *c) && *c != 0);
2034 }
2035
2036 *p = c;
2037
2038 if (is_real) {
2039 ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10l((exponent_negative ? -1.0 : 1.0) * exponent);
2040 return JSON_TOKEN_REAL;
2041 } else if (negative) {
2042 ret->integer = i;
2043 return JSON_TOKEN_INTEGER;
2044 } else {
2045 ret->unsig = u;
2046 return JSON_TOKEN_UNSIGNED;
2047 }
2048 }
2049
2050 int json_tokenize(
2051 const char **p,
2052 char **ret_string,
2053 JsonValue *ret_value,
2054 unsigned *ret_line, /* 'ret_line' returns the line at the beginning of this token */
2055 unsigned *ret_column,
2056 void **state,
2057 unsigned *line, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2058 unsigned *column) {
2059
2060 unsigned start_line, start_column;
2061 const char *start, *c;
2062 size_t n;
2063 int t, r;
2064
2065 enum {
2066 STATE_NULL,
2067 STATE_VALUE,
2068 STATE_VALUE_POST,
2069 };
2070
2071 assert(p);
2072 assert(*p);
2073 assert(ret_string);
2074 assert(ret_value);
2075 assert(ret_line);
2076 assert(ret_column);
2077 assert(line);
2078 assert(column);
2079 assert(state);
2080
2081 t = PTR_TO_INT(*state);
2082 if (t == STATE_NULL) {
2083 *line = 1;
2084 *column = 1;
2085 t = STATE_VALUE;
2086 }
2087
2088 /* Skip over the whitespace */
2089 n = strspn(*p, WHITESPACE);
2090 inc_lines_columns(line, column, *p, n);
2091 c = *p + n;
2092
2093 /* Remember where we started processing this token */
2094 start = c;
2095 start_line = *line;
2096 start_column = *column;
2097
2098 if (*c == 0) {
2099 *ret_string = NULL;
2100 *ret_value = JSON_VALUE_NULL;
2101 r = JSON_TOKEN_END;
2102 goto finish;
2103 }
2104
2105 switch (t) {
2106
2107 case STATE_VALUE:
2108
2109 if (*c == '{') {
2110 c++;
2111 *state = INT_TO_PTR(STATE_VALUE);
2112 r = JSON_TOKEN_OBJECT_OPEN;
2113 goto null_return;
2114
2115 } else if (*c == '}') {
2116 c++;
2117 *state = INT_TO_PTR(STATE_VALUE_POST);
2118 r = JSON_TOKEN_OBJECT_CLOSE;
2119 goto null_return;
2120
2121 } else if (*c == '[') {
2122 c++;
2123 *state = INT_TO_PTR(STATE_VALUE);
2124 r = JSON_TOKEN_ARRAY_OPEN;
2125 goto null_return;
2126
2127 } else if (*c == ']') {
2128 c++;
2129 *state = INT_TO_PTR(STATE_VALUE_POST);
2130 r = JSON_TOKEN_ARRAY_CLOSE;
2131 goto null_return;
2132
2133 } else if (*c == '"') {
2134
2135 r = json_parse_string(&c, ret_string);
2136 if (r < 0)
2137 return r;
2138
2139 *ret_value = JSON_VALUE_NULL;
2140 *state = INT_TO_PTR(STATE_VALUE_POST);
2141 goto finish;
2142
2143 } else if (strchr("-0123456789", *c)) {
2144
2145 r = json_parse_number(&c, ret_value);
2146 if (r < 0)
2147 return r;
2148
2149 *ret_string = NULL;
2150 *state = INT_TO_PTR(STATE_VALUE_POST);
2151 goto finish;
2152
2153 } else if (startswith(c, "true")) {
2154 *ret_string = NULL;
2155 ret_value->boolean = true;
2156 c += 4;
2157 *state = INT_TO_PTR(STATE_VALUE_POST);
2158 r = JSON_TOKEN_BOOLEAN;
2159 goto finish;
2160
2161 } else if (startswith(c, "false")) {
2162 *ret_string = NULL;
2163 ret_value->boolean = false;
2164 c += 5;
2165 *state = INT_TO_PTR(STATE_VALUE_POST);
2166 r = JSON_TOKEN_BOOLEAN;
2167 goto finish;
2168
2169 } else if (startswith(c, "null")) {
2170 *ret_string = NULL;
2171 *ret_value = JSON_VALUE_NULL;
2172 c += 4;
2173 *state = INT_TO_PTR(STATE_VALUE_POST);
2174 r = JSON_TOKEN_NULL;
2175 goto finish;
2176
2177 }
2178
2179 return -EINVAL;
2180
2181 case STATE_VALUE_POST:
2182
2183 if (*c == ':') {
2184 c++;
2185 *state = INT_TO_PTR(STATE_VALUE);
2186 r = JSON_TOKEN_COLON;
2187 goto null_return;
2188
2189 } else if (*c == ',') {
2190 c++;
2191 *state = INT_TO_PTR(STATE_VALUE);
2192 r = JSON_TOKEN_COMMA;
2193 goto null_return;
2194
2195 } else if (*c == '}') {
2196 c++;
2197 *state = INT_TO_PTR(STATE_VALUE_POST);
2198 r = JSON_TOKEN_OBJECT_CLOSE;
2199 goto null_return;
2200
2201 } else if (*c == ']') {
2202 c++;
2203 *state = INT_TO_PTR(STATE_VALUE_POST);
2204 r = JSON_TOKEN_ARRAY_CLOSE;
2205 goto null_return;
2206 }
2207
2208 return -EINVAL;
2209
2210 default:
2211 assert_not_reached("Unexpected tokenizer state");
2212 }
2213
2214 null_return:
2215 *ret_string = NULL;
2216 *ret_value = JSON_VALUE_NULL;
2217
2218 finish:
2219 inc_lines_columns(line, column, start, c - start);
2220 *p = c;
2221
2222 *ret_line = start_line;
2223 *ret_column = start_column;
2224
2225 return r;
2226 }
2227
2228 typedef enum JsonExpect {
2229 /* The following values are used by json_parse() */
2230 EXPECT_TOPLEVEL,
2231 EXPECT_END,
2232 EXPECT_OBJECT_FIRST_KEY,
2233 EXPECT_OBJECT_NEXT_KEY,
2234 EXPECT_OBJECT_COLON,
2235 EXPECT_OBJECT_VALUE,
2236 EXPECT_OBJECT_COMMA,
2237 EXPECT_ARRAY_FIRST_ELEMENT,
2238 EXPECT_ARRAY_NEXT_ELEMENT,
2239 EXPECT_ARRAY_COMMA,
2240
2241 /* And these are used by json_build() */
2242 EXPECT_ARRAY_ELEMENT,
2243 EXPECT_OBJECT_KEY,
2244 } JsonExpect;
2245
2246 typedef struct JsonStack {
2247 JsonExpect expect;
2248 JsonVariant **elements;
2249 size_t n_elements, n_elements_allocated;
2250 unsigned line_before;
2251 unsigned column_before;
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 JsonStack *current;
2660 int command;
2661
2662 assert(n_stack > 0);
2663 current = stack + n_stack - 1;
2664
2665 if (current->expect == EXPECT_END)
2666 goto done;
2667
2668 command = va_arg(ap, int);
2669
2670 switch (command) {
2671
2672 case _JSON_BUILD_STRING: {
2673 const char *p;
2674
2675 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2676 r = -EINVAL;
2677 goto finish;
2678 }
2679
2680 p = va_arg(ap, const char *);
2681
2682 r = json_variant_new_string(&add, p);
2683 if (r < 0)
2684 goto finish;
2685
2686 if (current->expect == EXPECT_TOPLEVEL)
2687 current->expect = EXPECT_END;
2688 else if (current->expect == EXPECT_OBJECT_VALUE)
2689 current->expect = EXPECT_OBJECT_KEY;
2690 else
2691 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2692
2693 break;
2694 }
2695
2696 case _JSON_BUILD_INTEGER: {
2697 intmax_t j;
2698
2699 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2700 r = -EINVAL;
2701 goto finish;
2702 }
2703
2704 j = va_arg(ap, intmax_t);
2705
2706 r = json_variant_new_integer(&add, j);
2707 if (r < 0)
2708 goto finish;
2709
2710 if (current->expect == EXPECT_TOPLEVEL)
2711 current->expect = EXPECT_END;
2712 else if (current->expect == EXPECT_OBJECT_VALUE)
2713 current->expect = EXPECT_OBJECT_KEY;
2714 else
2715 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2716
2717 break;
2718 }
2719
2720 case _JSON_BUILD_UNSIGNED: {
2721 uintmax_t j;
2722
2723 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2724 r = -EINVAL;
2725 goto finish;
2726 }
2727
2728 j = va_arg(ap, uintmax_t);
2729
2730 r = json_variant_new_unsigned(&add, j);
2731 if (r < 0)
2732 goto finish;
2733
2734 if (current->expect == EXPECT_TOPLEVEL)
2735 current->expect = EXPECT_END;
2736 else if (current->expect == EXPECT_OBJECT_VALUE)
2737 current->expect = EXPECT_OBJECT_KEY;
2738 else
2739 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2740
2741 break;
2742 }
2743
2744 case _JSON_BUILD_REAL: {
2745 long double d;
2746
2747 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2748 r = -EINVAL;
2749 goto finish;
2750 }
2751
2752 d = va_arg(ap, long double);
2753
2754 r = json_variant_new_real(&add, d);
2755 if (r < 0)
2756 goto finish;
2757
2758 if (current->expect == EXPECT_TOPLEVEL)
2759 current->expect = EXPECT_END;
2760 else if (current->expect == EXPECT_OBJECT_VALUE)
2761 current->expect = EXPECT_OBJECT_KEY;
2762 else
2763 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2764
2765 break;
2766 }
2767
2768 case _JSON_BUILD_BOOLEAN: {
2769 bool b;
2770
2771 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2772 r = -EINVAL;
2773 goto finish;
2774 }
2775
2776 b = va_arg(ap, int);
2777
2778 r = json_variant_new_boolean(&add, b);
2779 if (r < 0)
2780 goto finish;
2781
2782 if (current->expect == EXPECT_TOPLEVEL)
2783 current->expect = EXPECT_END;
2784 else if (current->expect == EXPECT_OBJECT_VALUE)
2785 current->expect = EXPECT_OBJECT_KEY;
2786 else
2787 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2788
2789 break;
2790 }
2791
2792 case _JSON_BUILD_NULL:
2793
2794 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2795 r = -EINVAL;
2796 goto finish;
2797 }
2798
2799 r = json_variant_new_null(&add);
2800 if (r < 0)
2801 goto finish;
2802
2803 if (current->expect == EXPECT_TOPLEVEL)
2804 current->expect = EXPECT_END;
2805 else if (current->expect == EXPECT_OBJECT_VALUE)
2806 current->expect = EXPECT_OBJECT_KEY;
2807 else
2808 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2809
2810 break;
2811
2812 case _JSON_BUILD_VARIANT:
2813
2814 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2815 r = -EINVAL;
2816 goto finish;
2817 }
2818
2819 add = va_arg(ap, JsonVariant*);
2820 if (!add)
2821 add = JSON_VARIANT_MAGIC_NULL;
2822 else
2823 json_variant_ref(add);
2824
2825 if (current->expect == EXPECT_TOPLEVEL)
2826 current->expect = EXPECT_END;
2827 else if (current->expect == EXPECT_OBJECT_VALUE)
2828 current->expect = EXPECT_OBJECT_KEY;
2829 else
2830 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2831
2832 break;
2833
2834 case _JSON_BUILD_LITERAL: {
2835 const char *l;
2836
2837 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2838 r = -EINVAL;
2839 goto finish;
2840 }
2841
2842 l = va_arg(ap, const char *);
2843
2844 if (!l)
2845 add = JSON_VARIANT_MAGIC_NULL;
2846 else {
2847 r = json_parse(l, &add, NULL, NULL);
2848 if (r < 0)
2849 goto finish;
2850 }
2851
2852 if (current->expect == EXPECT_TOPLEVEL)
2853 current->expect = EXPECT_END;
2854 else if (current->expect == EXPECT_OBJECT_VALUE)
2855 current->expect = EXPECT_OBJECT_KEY;
2856 else
2857 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2858
2859 break;
2860 }
2861
2862 case _JSON_BUILD_ARRAY_BEGIN:
2863
2864 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2865 r = -EINVAL;
2866 goto finish;
2867 }
2868
2869 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2870 r = -ENOMEM;
2871 goto finish;
2872 }
2873 current = stack + n_stack - 1;
2874
2875 if (current->expect == EXPECT_TOPLEVEL)
2876 current->expect = EXPECT_END;
2877 else if (current->expect == EXPECT_OBJECT_VALUE)
2878 current->expect = EXPECT_OBJECT_KEY;
2879 else
2880 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2881
2882 stack[n_stack++] = (JsonStack) {
2883 .expect = EXPECT_ARRAY_ELEMENT,
2884 };
2885
2886 break;
2887
2888 case _JSON_BUILD_ARRAY_END:
2889 if (current->expect != EXPECT_ARRAY_ELEMENT) {
2890 r = -EINVAL;
2891 goto finish;
2892 }
2893
2894 assert(n_stack > 1);
2895
2896 r = json_variant_new_array(&add, current->elements, current->n_elements);
2897 if (r < 0)
2898 goto finish;
2899
2900 json_stack_release(current);
2901 n_stack--, current--;
2902
2903 break;
2904
2905 case _JSON_BUILD_STRV: {
2906 char **l;
2907
2908 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2909 r = -EINVAL;
2910 goto finish;
2911 }
2912
2913 l = va_arg(ap, char **);
2914
2915 r = json_variant_new_array_strv(&add, l);
2916 if (r < 0)
2917 goto finish;
2918
2919 if (current->expect == EXPECT_TOPLEVEL)
2920 current->expect = EXPECT_END;
2921 else if (current->expect == EXPECT_OBJECT_VALUE)
2922 current->expect = EXPECT_OBJECT_KEY;
2923 else
2924 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2925
2926 break;
2927 }
2928
2929 case _JSON_BUILD_OBJECT_BEGIN:
2930
2931 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
2932 r = -EINVAL;
2933 goto finish;
2934 }
2935
2936 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2937 r = -ENOMEM;
2938 goto finish;
2939 }
2940 current = stack + n_stack - 1;
2941
2942 if (current->expect == EXPECT_TOPLEVEL)
2943 current->expect = EXPECT_END;
2944 else if (current->expect == EXPECT_OBJECT_VALUE)
2945 current->expect = EXPECT_OBJECT_KEY;
2946 else
2947 assert(current->expect == EXPECT_ARRAY_ELEMENT);
2948
2949 stack[n_stack++] = (JsonStack) {
2950 .expect = EXPECT_OBJECT_KEY,
2951 };
2952
2953 break;
2954
2955 case _JSON_BUILD_OBJECT_END:
2956
2957 if (current->expect != EXPECT_OBJECT_KEY) {
2958 r = -EINVAL;
2959 goto finish;
2960 }
2961
2962 assert(n_stack > 1);
2963
2964 r = json_variant_new_object(&add, current->elements, current->n_elements);
2965 if (r < 0)
2966 goto finish;
2967
2968 json_stack_release(current);
2969 n_stack--, current--;
2970
2971 break;
2972
2973 case _JSON_BUILD_PAIR: {
2974 const char *n;
2975
2976 if (current->expect != EXPECT_OBJECT_KEY) {
2977 r = -EINVAL;
2978 goto finish;
2979 }
2980
2981 n = va_arg(ap, const char *);
2982
2983 r = json_variant_new_string(&add, n);
2984 if (r < 0)
2985 goto finish;
2986
2987 current->expect = EXPECT_OBJECT_VALUE;
2988 break;
2989 }}
2990
2991 if (add) {
2992 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
2993 r = -ENOMEM;
2994 goto finish;
2995 }
2996
2997 current->elements[current->n_elements++] = TAKE_PTR(add);
2998 }
2999 }
3000
3001 done:
3002 assert(n_stack == 1);
3003 assert(stack[0].n_elements == 1);
3004
3005 *ret = json_variant_ref(stack[0].elements[0]);
3006 r = 0;
3007
3008 finish:
3009 for (i = 0; i < n_stack; i++)
3010 json_stack_release(stack + i);
3011
3012 free(stack);
3013
3014 va_end(ap);
3015
3016 return r;
3017 }
3018
3019 int json_build(JsonVariant **ret, ...) {
3020 va_list ap;
3021 int r;
3022
3023 va_start(ap, ret);
3024 r = json_buildv(ret, ap);
3025 va_end(ap);
3026
3027 return r;
3028 }
3029
3030 int json_log_internal(
3031 JsonVariant *variant,
3032 int level,
3033 int error,
3034 const char *file,
3035 int line,
3036 const char *func,
3037 const char *format, ...) {
3038
3039 PROTECT_ERRNO;
3040
3041 unsigned source_line, source_column;
3042 char buffer[LINE_MAX];
3043 const char *source;
3044 va_list ap;
3045 int r;
3046
3047 if (error < 0)
3048 error = -error;
3049
3050 errno = error;
3051
3052 va_start(ap, format);
3053 (void) vsnprintf(buffer, sizeof buffer, format, ap);
3054 va_end(ap);
3055
3056 if (variant) {
3057 r = json_variant_get_source(variant, &source, &source_line, &source_column);
3058 if (r < 0)
3059 return r;
3060 } else {
3061 source = NULL;
3062 source_line = 0;
3063 source_column = 0;
3064 }
3065
3066 if (source && source_line > 0 && source_column > 0)
3067 return log_struct_internal(
3068 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3069 error,
3070 file, line, func,
3071 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3072 "CONFIG_FILE=%s", source,
3073 "CONFIG_LINE=%u", source_line,
3074 "CONFIG_COLUMN=%u", source_column,
3075 LOG_MESSAGE("%s:%u: %s", source, line, buffer),
3076 NULL);
3077 else
3078 return log_struct_internal(
3079 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3080 error,
3081 file, line, func,
3082 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3083 LOG_MESSAGE("%s", buffer),
3084 NULL);
3085 }
3086
3087 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) {
3088 const JsonDispatch *p;
3089 size_t i, n, m;
3090 int r, done = 0;
3091 bool *found;
3092
3093 if (!json_variant_is_object(v)) {
3094 json_log(v, flags, 0, "JSON variant is not an object.");
3095
3096 if (flags & JSON_PERMISSIVE)
3097 return 0;
3098
3099 return -EINVAL;
3100 }
3101
3102 for (p = table, m = 0; p->name; p++)
3103 m++;
3104
3105 found = newa0(bool, m);
3106
3107 n = json_variant_elements(v);
3108 for (i = 0; i < n; i += 2) {
3109 JsonVariant *key, *value;
3110
3111 assert_se(key = json_variant_by_index(v, i));
3112 assert_se(value = json_variant_by_index(v, i+1));
3113
3114 for (p = table; p->name; p++)
3115 if (p->name == (const char*) -1 ||
3116 streq_ptr(json_variant_string(key), p->name))
3117 break;
3118
3119 if (p->name) { /* Found a matching entry! :-) */
3120 JsonDispatchFlags merged_flags;
3121
3122 merged_flags = flags | p->flags;
3123
3124 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
3125 !json_variant_has_type(value, p->type)) {
3126
3127 json_log(value, merged_flags, 0,
3128 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
3129 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
3130
3131 if (merged_flags & JSON_PERMISSIVE)
3132 continue;
3133
3134 return -EINVAL;
3135 }
3136
3137 if (found[p-table]) {
3138 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
3139
3140 if (merged_flags & JSON_PERMISSIVE)
3141 continue;
3142
3143 return -ENOTUNIQ;
3144 }
3145
3146 found[p-table] = true;
3147
3148 if (p->callback) {
3149 r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset);
3150 if (r < 0) {
3151 if (merged_flags & JSON_PERMISSIVE)
3152 continue;
3153
3154 return r;
3155 }
3156 }
3157
3158 done ++;
3159
3160 } else { /* Didn't find a matching entry! :-( */
3161
3162 if (bad) {
3163 r = bad(json_variant_string(key), value, flags, userdata);
3164 if (r < 0) {
3165 if (flags & JSON_PERMISSIVE)
3166 continue;
3167
3168 return r;
3169 } else
3170 done ++;
3171
3172 } else {
3173 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
3174
3175 if (flags & JSON_PERMISSIVE)
3176 continue;
3177
3178 return -EADDRNOTAVAIL;
3179 }
3180 }
3181 }
3182
3183 for (p = table; p->name; p++) {
3184 JsonDispatchFlags merged_flags = p->flags | flags;
3185
3186 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
3187 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
3188
3189 if ((merged_flags & JSON_PERMISSIVE))
3190 continue;
3191
3192 return -ENXIO;
3193 }
3194 }
3195
3196 return done;
3197 }
3198
3199 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3200 bool *b = userdata;
3201
3202 assert(variant);
3203 assert(b);
3204
3205 if (!json_variant_is_boolean(variant)) {
3206 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3207 return -EINVAL;
3208 }
3209
3210 *b = json_variant_boolean(variant);
3211 return 0;
3212 }
3213
3214 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3215 int *b = userdata;
3216
3217 assert(variant);
3218 assert(b);
3219
3220 if (!json_variant_is_boolean(variant)) {
3221 json_log(variant, flags, 0, "JSON field '%s' is not a boolean.", strna(name));
3222 return -EINVAL;
3223 }
3224
3225 *b = json_variant_boolean(variant);
3226 return 0;
3227 }
3228
3229 int json_dispatch_integer(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3230 intmax_t *i = userdata;
3231
3232 assert(variant);
3233 assert(i);
3234
3235 if (!json_variant_is_integer(variant)) {
3236 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3237 return -EINVAL;
3238 }
3239
3240 *i = json_variant_integer(variant);
3241 return 0;
3242 }
3243
3244 int json_dispatch_unsigned(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3245 uintmax_t *u = userdata;
3246
3247 assert(variant);
3248 assert(u);
3249
3250 if (!json_variant_is_unsigned(variant)) {
3251 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3252 return -EINVAL;
3253 }
3254
3255 *u = json_variant_unsigned(variant);
3256 return 0;
3257 }
3258
3259 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3260 uint32_t *u = userdata;
3261
3262 assert(variant);
3263 assert(u);
3264
3265 if (!json_variant_is_unsigned(variant)) {
3266 json_log(variant, flags, 0, "JSON field '%s' is not an unsigned integer.", strna(name));
3267 return -EINVAL;
3268 }
3269
3270 if (json_variant_unsigned(variant) > UINT32_MAX) {
3271 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3272 return -ERANGE;
3273 }
3274
3275 *u = (uint32_t) json_variant_unsigned(variant);
3276 return 0;
3277 }
3278
3279 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3280 int32_t *i = userdata;
3281
3282 assert(variant);
3283 assert(i);
3284
3285 if (!json_variant_is_integer(variant)) {
3286 json_log(variant, flags, 0, "JSON field '%s' is not an integer.", strna(name));
3287 return -EINVAL;
3288 }
3289
3290 if (json_variant_integer(variant) < INT32_MIN || json_variant_integer(variant) > INT32_MAX) {
3291 json_log(variant, flags, 0, "JSON field '%s' out of bounds.", strna(name));
3292 return -ERANGE;
3293 }
3294
3295 *i = (int32_t) json_variant_integer(variant);
3296 return 0;
3297 }
3298
3299 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3300 char **s = userdata;
3301 int r;
3302
3303 assert(variant);
3304 assert(s);
3305
3306 if (json_variant_is_null(variant)) {
3307 *s = mfree(*s);
3308 return 0;
3309 }
3310
3311 if (!json_variant_is_string(variant)) {
3312 json_log(variant, flags, 0, "JSON field '%s' is not a string.", strna(name));
3313 return -EINVAL;
3314 }
3315
3316 r = free_and_strdup(s, json_variant_string(variant));
3317 if (r < 0)
3318 return json_log(variant, flags, r, "Failed to allocate string: %m");
3319
3320 return 0;
3321 }
3322
3323 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3324 _cleanup_strv_free_ char **l = NULL;
3325 char ***s = userdata;
3326 size_t i;
3327 int r;
3328
3329 assert(variant);
3330 assert(s);
3331
3332 if (json_variant_is_null(variant)) {
3333 *s = strv_free(*s);
3334 return 0;
3335 }
3336
3337 if (!json_variant_is_array(variant)) {
3338 json_log(variant, 0, flags, "JSON field '%s' is not an array.", strna(name));
3339 return -EINVAL;
3340 }
3341
3342 for (i = 0; i < json_variant_elements(variant); i++) {
3343 JsonVariant *e;
3344
3345 assert_se(e = json_variant_by_index(variant, i));
3346
3347 if (!json_variant_is_string(e)) {
3348 json_log(e, 0, flags, "JSON array element is not a string.");
3349 return -EINVAL;
3350 }
3351
3352 r = strv_extend(&l, json_variant_string(e));
3353 if (r < 0)
3354 return json_log(variant, flags, r, "Failed to append array element: %m");
3355 }
3356
3357 strv_free_and_replace(*s, l);
3358 return 0;
3359 }
3360
3361 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3362 JsonVariant **p = userdata;
3363
3364 assert(variant);
3365 assert(p);
3366
3367 json_variant_unref(*p);
3368 *p = json_variant_ref(variant);
3369
3370 return 0;
3371 }
3372
3373 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
3374 [JSON_VARIANT_STRING] = "string",
3375 [JSON_VARIANT_INTEGER] = "integer",
3376 [JSON_VARIANT_UNSIGNED] = "unsigned",
3377 [JSON_VARIANT_REAL] = "real",
3378 [JSON_VARIANT_NUMBER] = "number",
3379 [JSON_VARIANT_BOOLEAN] = "boolean",
3380 [JSON_VARIANT_ARRAY] = "array",
3381 [JSON_VARIANT_OBJECT] = "object",
3382 [JSON_VARIANT_NULL] = "null",
3383 };
3384
3385 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);