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