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