]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/json.c
json: add json_variant_unbase64() helper
[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 if (flags & JSON_FORMAT_FLUSH)
1772 fflush(f);
1773 }
1774
1775 int json_variant_filter(JsonVariant **v, char **to_remove) {
1776 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1777 _cleanup_free_ JsonVariant **array = NULL;
1778 size_t i, n = 0, k = 0;
1779 int r;
1780
1781 assert(v);
1782
1783 if (json_variant_is_blank_object(*v))
1784 return 0;
1785 if (!json_variant_is_object(*v))
1786 return -EINVAL;
1787
1788 if (strv_isempty(to_remove))
1789 return 0;
1790
1791 for (i = 0; i < json_variant_elements(*v); i += 2) {
1792 JsonVariant *p;
1793
1794 p = json_variant_by_index(*v, i);
1795 if (!json_variant_has_type(p, JSON_VARIANT_STRING))
1796 return -EINVAL;
1797
1798 if (strv_contains(to_remove, json_variant_string(p))) {
1799 if (!array) {
1800 array = new(JsonVariant*, json_variant_elements(*v) - 2);
1801 if (!array)
1802 return -ENOMEM;
1803
1804 for (k = 0; k < i; k++)
1805 array[k] = json_variant_by_index(*v, k);
1806 }
1807
1808 n++;
1809 } else if (array) {
1810 array[k++] = p;
1811 array[k++] = json_variant_by_index(*v, i + 1);
1812 }
1813 }
1814
1815 if (n == 0)
1816 return 0;
1817
1818 r = json_variant_new_object(&w, array, k);
1819 if (r < 0)
1820 return r;
1821
1822 json_variant_unref(*v);
1823 *v = TAKE_PTR(w);
1824
1825 return (int) n;
1826 }
1827
1828 int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value) {
1829 _cleanup_(json_variant_unrefp) JsonVariant *field_variant = NULL, *w = NULL;
1830 _cleanup_free_ JsonVariant **array = NULL;
1831 size_t i, k = 0;
1832 int r;
1833
1834 assert(v);
1835 assert(field);
1836
1837 if (json_variant_is_blank_object(*v)) {
1838 array = new(JsonVariant*, 2);
1839 if (!array)
1840 return -ENOMEM;
1841
1842 } else {
1843 if (!json_variant_is_object(*v))
1844 return -EINVAL;
1845
1846 for (i = 0; i < json_variant_elements(*v); i += 2) {
1847 JsonVariant *p;
1848
1849 p = json_variant_by_index(*v, i);
1850 if (!json_variant_is_string(p))
1851 return -EINVAL;
1852
1853 if (streq(json_variant_string(p), field)) {
1854
1855 if (!array) {
1856 array = new(JsonVariant*, json_variant_elements(*v));
1857 if (!array)
1858 return -ENOMEM;
1859
1860 for (k = 0; k < i; k++)
1861 array[k] = json_variant_by_index(*v, k);
1862 }
1863
1864 } else if (array) {
1865 array[k++] = p;
1866 array[k++] = json_variant_by_index(*v, i + 1);
1867 }
1868 }
1869
1870 if (!array) {
1871 array = new(JsonVariant*, json_variant_elements(*v) + 2);
1872 if (!array)
1873 return -ENOMEM;
1874
1875 for (k = 0; k < json_variant_elements(*v); k++)
1876 array[k] = json_variant_by_index(*v, k);
1877 }
1878 }
1879
1880 r = json_variant_new_string(&field_variant, field);
1881 if (r < 0)
1882 return r;
1883
1884 array[k++] = field_variant;
1885 array[k++] = value;
1886
1887 r = json_variant_new_object(&w, array, k);
1888 if (r < 0)
1889 return r;
1890
1891 json_variant_unref(*v);
1892 *v = TAKE_PTR(w);
1893
1894 return 1;
1895 }
1896
1897 int json_variant_set_field_string(JsonVariant **v, const char *field, const char *value) {
1898 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
1899 int r;
1900
1901 r = json_variant_new_string(&m, value);
1902 if (r < 0)
1903 return r;
1904
1905 return json_variant_set_field(v, field, m);
1906 }
1907
1908 int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uintmax_t u) {
1909 _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
1910 int r;
1911
1912 r = json_variant_new_unsigned(&m, u);
1913 if (r < 0)
1914 return r;
1915
1916 return json_variant_set_field(v, field, m);
1917 }
1918
1919 int json_variant_merge(JsonVariant **v, JsonVariant *m) {
1920 _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1921 _cleanup_free_ JsonVariant **array = NULL;
1922 size_t v_elements, m_elements, i, k;
1923 bool v_blank, m_blank;
1924 int r;
1925
1926 m = json_variant_dereference(m);
1927
1928 v_blank = json_variant_is_blank_object(*v);
1929 m_blank = json_variant_is_blank_object(m);
1930
1931 if (!v_blank && !json_variant_is_object(*v))
1932 return -EINVAL;
1933 if (!m_blank && !json_variant_is_object(m))
1934 return -EINVAL;
1935
1936 if (m_blank)
1937 return 0; /* nothing to do */
1938
1939 if (v_blank) {
1940 json_variant_unref(*v);
1941 *v = json_variant_ref(m);
1942 return 1;
1943 }
1944
1945 v_elements = json_variant_elements(*v);
1946 m_elements = json_variant_elements(m);
1947 if (v_elements > SIZE_MAX - m_elements) /* overflow check */
1948 return -ENOMEM;
1949
1950 array = new(JsonVariant*, v_elements + m_elements);
1951 if (!array)
1952 return -ENOMEM;
1953
1954 k = 0;
1955 for (i = 0; i < v_elements; i += 2) {
1956 JsonVariant *u;
1957
1958 u = json_variant_by_index(*v, i);
1959 if (!json_variant_is_string(u))
1960 return -EINVAL;
1961
1962 if (json_variant_by_key(m, json_variant_string(u)))
1963 continue; /* skip if exists in second variant */
1964
1965 array[k++] = u;
1966 array[k++] = json_variant_by_index(*v, i + 1);
1967 }
1968
1969 for (i = 0; i < m_elements; i++)
1970 array[k++] = json_variant_by_index(m, i);
1971
1972 r = json_variant_new_object(&w, array, k);
1973 if (r < 0)
1974 return r;
1975
1976 json_variant_unref(*v);
1977 *v = TAKE_PTR(w);
1978
1979 return 1;
1980 }
1981
1982 int json_variant_append_array(JsonVariant **v, JsonVariant *element) {
1983 _cleanup_(json_variant_unrefp) JsonVariant *nv = NULL;
1984 bool blank;
1985 int r;
1986
1987 assert(v);
1988 assert(element);
1989
1990
1991 if (!*v || json_variant_is_null(*v))
1992 blank = true;
1993 else if (!json_variant_is_array(*v))
1994 return -EINVAL;
1995 else
1996 blank = json_variant_elements(*v) == 0;
1997
1998 if (blank)
1999 r = json_variant_new_array(&nv, (JsonVariant*[]) { element }, 1);
2000 else {
2001 _cleanup_free_ JsonVariant **array = NULL;
2002 size_t i;
2003
2004 array = new(JsonVariant*, json_variant_elements(*v) + 1);
2005 if (!array)
2006 return -ENOMEM;
2007
2008 for (i = 0; i < json_variant_elements(*v); i++)
2009 array[i] = json_variant_by_index(*v, i);
2010
2011 array[i] = element;
2012
2013 r = json_variant_new_array(&nv, array, i + 1);
2014 }
2015
2016 if (r < 0)
2017 return r;
2018
2019 json_variant_unref(*v);
2020 *v = TAKE_PTR(nv);
2021
2022 return 0;
2023 }
2024
2025 int json_variant_strv(JsonVariant *v, char ***ret) {
2026 char **l = NULL;
2027 size_t n, i;
2028 bool sensitive;
2029 int r;
2030
2031 assert(ret);
2032
2033 if (!v || json_variant_is_null(v)) {
2034 l = new0(char*, 1);
2035 if (!l)
2036 return -ENOMEM;
2037
2038 *ret = l;
2039 return 0;
2040 }
2041
2042 if (!json_variant_is_array(v))
2043 return -EINVAL;
2044
2045 sensitive = v->sensitive;
2046
2047 n = json_variant_elements(v);
2048 l = new(char*, n+1);
2049 if (!l)
2050 return -ENOMEM;
2051
2052 for (i = 0; i < n; i++) {
2053 JsonVariant *e;
2054
2055 assert_se(e = json_variant_by_index(v, i));
2056 sensitive = sensitive || e->sensitive;
2057
2058 if (!json_variant_is_string(e)) {
2059 l[i] = NULL;
2060 r = -EINVAL;
2061 goto fail;
2062 }
2063
2064 l[i] = strdup(json_variant_string(e));
2065 if (!l[i]) {
2066 r = -ENOMEM;
2067 goto fail;
2068 }
2069 }
2070
2071 l[i] = NULL;
2072 *ret = TAKE_PTR(l);
2073
2074 return 0;
2075
2076 fail:
2077 if (sensitive)
2078 strv_free_erase(l);
2079 else
2080 strv_free(l);
2081
2082 return r;
2083 }
2084
2085 static int json_variant_copy(JsonVariant **nv, JsonVariant *v) {
2086 JsonVariantType t;
2087 JsonVariant *c;
2088 JsonValue value;
2089 const void *source;
2090 size_t k;
2091
2092 assert(nv);
2093 assert(v);
2094
2095 /* Let's copy the simple types literally, and the larger types by references */
2096 t = json_variant_type(v);
2097 switch (t) {
2098 case JSON_VARIANT_INTEGER:
2099 k = sizeof(intmax_t);
2100 value.integer = json_variant_integer(v);
2101 source = &value;
2102 break;
2103
2104 case JSON_VARIANT_UNSIGNED:
2105 k = sizeof(uintmax_t);
2106 value.unsig = json_variant_unsigned(v);
2107 source = &value;
2108 break;
2109
2110 case JSON_VARIANT_REAL:
2111 k = sizeof(long double);
2112 value.real = json_variant_real(v);
2113 source = &value;
2114 break;
2115
2116 case JSON_VARIANT_BOOLEAN:
2117 k = sizeof(bool);
2118 value.boolean = json_variant_boolean(v);
2119 source = &value;
2120 break;
2121
2122 case JSON_VARIANT_NULL:
2123 k = 0;
2124 source = NULL;
2125 break;
2126
2127 case JSON_VARIANT_STRING:
2128 source = json_variant_string(v);
2129 k = strnlen(source, INLINE_STRING_MAX + 1);
2130 if (k <= INLINE_STRING_MAX) {
2131 k ++;
2132 break;
2133 }
2134
2135 _fallthrough_;
2136
2137 default:
2138 /* Everything else copy by reference */
2139
2140 c = malloc0(MAX(sizeof(JsonVariant),
2141 offsetof(JsonVariant, reference) + sizeof(JsonVariant*)));
2142 if (!c)
2143 return -ENOMEM;
2144
2145 c->n_ref = 1;
2146 c->type = t;
2147 c->is_reference = true;
2148 c->reference = json_variant_ref(json_variant_formalize(v));
2149
2150 *nv = c;
2151 return 0;
2152 }
2153
2154 c = malloc0(MAX(sizeof(JsonVariant),
2155 offsetof(JsonVariant, value) + k));
2156 if (!c)
2157 return -ENOMEM;
2158
2159 c->n_ref = 1;
2160 c->type = t;
2161
2162 memcpy_safe(&c->value, source, k);
2163
2164 *nv = c;
2165 return 0;
2166 }
2167
2168 static bool json_single_ref(JsonVariant *v) {
2169
2170 /* Checks whether the caller is the single owner of the object, i.e. can get away with changing it */
2171
2172 if (!json_variant_is_regular(v))
2173 return false;
2174
2175 if (v->is_embedded)
2176 return json_single_ref(v->parent);
2177
2178 assert(v->n_ref > 0);
2179 return v->n_ref == 1;
2180 }
2181
2182 static int json_variant_set_source(JsonVariant **v, JsonSource *source, unsigned line, unsigned column) {
2183 JsonVariant *w;
2184 int r;
2185
2186 assert(v);
2187
2188 /* Patch in source and line/column number. Tries to do this in-place if the caller is the sole referencer of
2189 * the object. If not, allocates a new object, possibly a surrogate for the original one */
2190
2191 if (!*v)
2192 return 0;
2193
2194 if (source && line > source->max_line)
2195 source->max_line = line;
2196 if (source && column > source->max_column)
2197 source->max_column = column;
2198
2199 if (!json_variant_is_regular(*v)) {
2200
2201 if (!source && line == 0 && column == 0)
2202 return 0;
2203
2204 } else {
2205 if (json_source_equal((*v)->source, source) &&
2206 (*v)->line == line &&
2207 (*v)->column == column)
2208 return 0;
2209
2210 if (json_single_ref(*v)) { /* Sole reference? */
2211 json_source_unref((*v)->source);
2212 (*v)->source = json_source_ref(source);
2213 (*v)->line = line;
2214 (*v)->column = column;
2215 return 1;
2216 }
2217 }
2218
2219 r = json_variant_copy(&w, *v);
2220 if (r < 0)
2221 return r;
2222
2223 assert(json_variant_is_regular(w));
2224 assert(!w->is_embedded);
2225 assert(w->n_ref == 1);
2226 assert(!w->source);
2227
2228 w->source = json_source_ref(source);
2229 w->line = line;
2230 w->column = column;
2231
2232 json_variant_unref(*v);
2233 *v = w;
2234
2235 return 1;
2236 }
2237
2238 static void inc_lines_columns(unsigned *line, unsigned *column, const char *s, size_t n) {
2239 assert(line);
2240 assert(column);
2241 assert(s || n == 0);
2242
2243 while (n > 0) {
2244 if (*s == '\n') {
2245 (*line)++;
2246 *column = 1;
2247 } else if ((signed char) *s >= 0 && *s < 127) /* Process ASCII chars quickly */
2248 (*column)++;
2249 else {
2250 int w;
2251
2252 w = utf8_encoded_valid_unichar(s, n);
2253 if (w < 0) /* count invalid unichars as normal characters */
2254 w = 1;
2255 else if ((size_t) w > n) /* never read more than the specified number of characters */
2256 w = (int) n;
2257
2258 (*column)++;
2259
2260 s += w;
2261 n -= w;
2262 continue;
2263 }
2264
2265 s++;
2266 n--;
2267 }
2268 }
2269
2270 static int unhex_ucs2(const char *c, uint16_t *ret) {
2271 int aa, bb, cc, dd;
2272 uint16_t x;
2273
2274 assert(c);
2275 assert(ret);
2276
2277 aa = unhexchar(c[0]);
2278 if (aa < 0)
2279 return -EINVAL;
2280
2281 bb = unhexchar(c[1]);
2282 if (bb < 0)
2283 return -EINVAL;
2284
2285 cc = unhexchar(c[2]);
2286 if (cc < 0)
2287 return -EINVAL;
2288
2289 dd = unhexchar(c[3]);
2290 if (dd < 0)
2291 return -EINVAL;
2292
2293 x = ((uint16_t) aa << 12) |
2294 ((uint16_t) bb << 8) |
2295 ((uint16_t) cc << 4) |
2296 ((uint16_t) dd);
2297
2298 if (x <= 0)
2299 return -EINVAL;
2300
2301 *ret = x;
2302
2303 return 0;
2304 }
2305
2306 static int json_parse_string(const char **p, char **ret) {
2307 _cleanup_free_ char *s = NULL;
2308 size_t n = 0, allocated = 0;
2309 const char *c;
2310
2311 assert(p);
2312 assert(*p);
2313 assert(ret);
2314
2315 c = *p;
2316
2317 if (*c != '"')
2318 return -EINVAL;
2319
2320 c++;
2321
2322 for (;;) {
2323 int len;
2324
2325 /* Check for EOF */
2326 if (*c == 0)
2327 return -EINVAL;
2328
2329 /* Check for control characters 0x00..0x1f */
2330 if (*c > 0 && *c < ' ')
2331 return -EINVAL;
2332
2333 /* Check for control character 0x7f */
2334 if (*c == 0x7f)
2335 return -EINVAL;
2336
2337 if (*c == '"') {
2338 if (!s) {
2339 s = strdup("");
2340 if (!s)
2341 return -ENOMEM;
2342 } else
2343 s[n] = 0;
2344
2345 *p = c + 1;
2346
2347 *ret = TAKE_PTR(s);
2348 return JSON_TOKEN_STRING;
2349 }
2350
2351 if (*c == '\\') {
2352 char ch = 0;
2353 c++;
2354
2355 if (*c == 0)
2356 return -EINVAL;
2357
2358 if (IN_SET(*c, '"', '\\', '/'))
2359 ch = *c;
2360 else if (*c == 'b')
2361 ch = '\b';
2362 else if (*c == 'f')
2363 ch = '\f';
2364 else if (*c == 'n')
2365 ch = '\n';
2366 else if (*c == 'r')
2367 ch = '\r';
2368 else if (*c == 't')
2369 ch = '\t';
2370 else if (*c == 'u') {
2371 char16_t x;
2372 int r;
2373
2374 r = unhex_ucs2(c + 1, &x);
2375 if (r < 0)
2376 return r;
2377
2378 c += 5;
2379
2380 if (!GREEDY_REALLOC(s, allocated, n + 5))
2381 return -ENOMEM;
2382
2383 if (!utf16_is_surrogate(x))
2384 n += utf8_encode_unichar(s + n, (char32_t) x);
2385 else if (utf16_is_trailing_surrogate(x))
2386 return -EINVAL;
2387 else {
2388 char16_t y;
2389
2390 if (c[0] != '\\' || c[1] != 'u')
2391 return -EINVAL;
2392
2393 r = unhex_ucs2(c + 2, &y);
2394 if (r < 0)
2395 return r;
2396
2397 c += 6;
2398
2399 if (!utf16_is_trailing_surrogate(y))
2400 return -EINVAL;
2401
2402 n += utf8_encode_unichar(s + n, utf16_surrogate_pair_to_unichar(x, y));
2403 }
2404
2405 continue;
2406 } else
2407 return -EINVAL;
2408
2409 if (!GREEDY_REALLOC(s, allocated, n + 2))
2410 return -ENOMEM;
2411
2412 s[n++] = ch;
2413 c ++;
2414 continue;
2415 }
2416
2417 len = utf8_encoded_valid_unichar(c, (size_t) -1);
2418 if (len < 0)
2419 return len;
2420
2421 if (!GREEDY_REALLOC(s, allocated, n + len + 1))
2422 return -ENOMEM;
2423
2424 memcpy(s + n, c, len);
2425 n += len;
2426 c += len;
2427 }
2428 }
2429
2430 static int json_parse_number(const char **p, JsonValue *ret) {
2431 bool negative = false, exponent_negative = false, is_real = false;
2432 long double x = 0.0, y = 0.0, exponent = 0.0, shift = 1.0;
2433 intmax_t i = 0;
2434 uintmax_t u = 0;
2435 const char *c;
2436
2437 assert(p);
2438 assert(*p);
2439 assert(ret);
2440
2441 c = *p;
2442
2443 if (*c == '-') {
2444 negative = true;
2445 c++;
2446 }
2447
2448 if (*c == '0')
2449 c++;
2450 else {
2451 if (!strchr("123456789", *c) || *c == 0)
2452 return -EINVAL;
2453
2454 do {
2455 if (!is_real) {
2456 if (negative) {
2457
2458 if (i < INTMAX_MIN / 10) /* overflow */
2459 is_real = true;
2460 else {
2461 intmax_t t = 10 * i;
2462
2463 if (t < INTMAX_MIN + (*c - '0')) /* overflow */
2464 is_real = true;
2465 else
2466 i = t - (*c - '0');
2467 }
2468 } else {
2469 if (u > UINTMAX_MAX / 10) /* overflow */
2470 is_real = true;
2471 else {
2472 uintmax_t t = 10 * u;
2473
2474 if (t > UINTMAX_MAX - (*c - '0')) /* overflow */
2475 is_real = true;
2476 else
2477 u = t + (*c - '0');
2478 }
2479 }
2480 }
2481
2482 x = 10.0 * x + (*c - '0');
2483
2484 c++;
2485 } while (strchr("0123456789", *c) && *c != 0);
2486 }
2487
2488 if (*c == '.') {
2489 is_real = true;
2490 c++;
2491
2492 if (!strchr("0123456789", *c) || *c == 0)
2493 return -EINVAL;
2494
2495 do {
2496 y = 10.0 * y + (*c - '0');
2497 shift = 10.0 * shift;
2498 c++;
2499 } while (strchr("0123456789", *c) && *c != 0);
2500 }
2501
2502 if (IN_SET(*c, 'e', 'E')) {
2503 is_real = true;
2504 c++;
2505
2506 if (*c == '-') {
2507 exponent_negative = true;
2508 c++;
2509 } else if (*c == '+')
2510 c++;
2511
2512 if (!strchr("0123456789", *c) || *c == 0)
2513 return -EINVAL;
2514
2515 do {
2516 exponent = 10.0 * exponent + (*c - '0');
2517 c++;
2518 } while (strchr("0123456789", *c) && *c != 0);
2519 }
2520
2521 *p = c;
2522
2523 if (is_real) {
2524 ret->real = ((negative ? -1.0 : 1.0) * (x + (y / shift))) * exp10l((exponent_negative ? -1.0 : 1.0) * exponent);
2525 return JSON_TOKEN_REAL;
2526 } else if (negative) {
2527 ret->integer = i;
2528 return JSON_TOKEN_INTEGER;
2529 } else {
2530 ret->unsig = u;
2531 return JSON_TOKEN_UNSIGNED;
2532 }
2533 }
2534
2535 int json_tokenize(
2536 const char **p,
2537 char **ret_string,
2538 JsonValue *ret_value,
2539 unsigned *ret_line, /* 'ret_line' returns the line at the beginning of this token */
2540 unsigned *ret_column,
2541 void **state,
2542 unsigned *line, /* 'line' is used as a line state, it always reflect the line we are at after the token was read */
2543 unsigned *column) {
2544
2545 unsigned start_line, start_column;
2546 const char *start, *c;
2547 size_t n;
2548 int t, r;
2549
2550 enum {
2551 STATE_NULL,
2552 STATE_VALUE,
2553 STATE_VALUE_POST,
2554 };
2555
2556 assert(p);
2557 assert(*p);
2558 assert(ret_string);
2559 assert(ret_value);
2560 assert(ret_line);
2561 assert(ret_column);
2562 assert(line);
2563 assert(column);
2564 assert(state);
2565
2566 t = PTR_TO_INT(*state);
2567 if (t == STATE_NULL) {
2568 *line = 1;
2569 *column = 1;
2570 t = STATE_VALUE;
2571 }
2572
2573 /* Skip over the whitespace */
2574 n = strspn(*p, WHITESPACE);
2575 inc_lines_columns(line, column, *p, n);
2576 c = *p + n;
2577
2578 /* Remember where we started processing this token */
2579 start = c;
2580 start_line = *line;
2581 start_column = *column;
2582
2583 if (*c == 0) {
2584 *ret_string = NULL;
2585 *ret_value = JSON_VALUE_NULL;
2586 r = JSON_TOKEN_END;
2587 goto finish;
2588 }
2589
2590 switch (t) {
2591
2592 case STATE_VALUE:
2593
2594 if (*c == '{') {
2595 c++;
2596 *state = INT_TO_PTR(STATE_VALUE);
2597 r = JSON_TOKEN_OBJECT_OPEN;
2598 goto null_return;
2599
2600 } else if (*c == '}') {
2601 c++;
2602 *state = INT_TO_PTR(STATE_VALUE_POST);
2603 r = JSON_TOKEN_OBJECT_CLOSE;
2604 goto null_return;
2605
2606 } else if (*c == '[') {
2607 c++;
2608 *state = INT_TO_PTR(STATE_VALUE);
2609 r = JSON_TOKEN_ARRAY_OPEN;
2610 goto null_return;
2611
2612 } else if (*c == ']') {
2613 c++;
2614 *state = INT_TO_PTR(STATE_VALUE_POST);
2615 r = JSON_TOKEN_ARRAY_CLOSE;
2616 goto null_return;
2617
2618 } else if (*c == '"') {
2619
2620 r = json_parse_string(&c, ret_string);
2621 if (r < 0)
2622 return r;
2623
2624 *ret_value = JSON_VALUE_NULL;
2625 *state = INT_TO_PTR(STATE_VALUE_POST);
2626 goto finish;
2627
2628 } else if (strchr("-0123456789", *c)) {
2629
2630 r = json_parse_number(&c, ret_value);
2631 if (r < 0)
2632 return r;
2633
2634 *ret_string = NULL;
2635 *state = INT_TO_PTR(STATE_VALUE_POST);
2636 goto finish;
2637
2638 } else if (startswith(c, "true")) {
2639 *ret_string = NULL;
2640 ret_value->boolean = true;
2641 c += 4;
2642 *state = INT_TO_PTR(STATE_VALUE_POST);
2643 r = JSON_TOKEN_BOOLEAN;
2644 goto finish;
2645
2646 } else if (startswith(c, "false")) {
2647 *ret_string = NULL;
2648 ret_value->boolean = false;
2649 c += 5;
2650 *state = INT_TO_PTR(STATE_VALUE_POST);
2651 r = JSON_TOKEN_BOOLEAN;
2652 goto finish;
2653
2654 } else if (startswith(c, "null")) {
2655 *ret_string = NULL;
2656 *ret_value = JSON_VALUE_NULL;
2657 c += 4;
2658 *state = INT_TO_PTR(STATE_VALUE_POST);
2659 r = JSON_TOKEN_NULL;
2660 goto finish;
2661
2662 }
2663
2664 return -EINVAL;
2665
2666 case STATE_VALUE_POST:
2667
2668 if (*c == ':') {
2669 c++;
2670 *state = INT_TO_PTR(STATE_VALUE);
2671 r = JSON_TOKEN_COLON;
2672 goto null_return;
2673
2674 } else if (*c == ',') {
2675 c++;
2676 *state = INT_TO_PTR(STATE_VALUE);
2677 r = JSON_TOKEN_COMMA;
2678 goto null_return;
2679
2680 } else if (*c == '}') {
2681 c++;
2682 *state = INT_TO_PTR(STATE_VALUE_POST);
2683 r = JSON_TOKEN_OBJECT_CLOSE;
2684 goto null_return;
2685
2686 } else if (*c == ']') {
2687 c++;
2688 *state = INT_TO_PTR(STATE_VALUE_POST);
2689 r = JSON_TOKEN_ARRAY_CLOSE;
2690 goto null_return;
2691 }
2692
2693 return -EINVAL;
2694
2695 default:
2696 assert_not_reached("Unexpected tokenizer state");
2697 }
2698
2699 null_return:
2700 *ret_string = NULL;
2701 *ret_value = JSON_VALUE_NULL;
2702
2703 finish:
2704 inc_lines_columns(line, column, start, c - start);
2705 *p = c;
2706
2707 *ret_line = start_line;
2708 *ret_column = start_column;
2709
2710 return r;
2711 }
2712
2713 typedef enum JsonExpect {
2714 /* The following values are used by json_parse() */
2715 EXPECT_TOPLEVEL,
2716 EXPECT_END,
2717 EXPECT_OBJECT_FIRST_KEY,
2718 EXPECT_OBJECT_NEXT_KEY,
2719 EXPECT_OBJECT_COLON,
2720 EXPECT_OBJECT_VALUE,
2721 EXPECT_OBJECT_COMMA,
2722 EXPECT_ARRAY_FIRST_ELEMENT,
2723 EXPECT_ARRAY_NEXT_ELEMENT,
2724 EXPECT_ARRAY_COMMA,
2725
2726 /* And these are used by json_build() */
2727 EXPECT_ARRAY_ELEMENT,
2728 EXPECT_OBJECT_KEY,
2729 } JsonExpect;
2730
2731 typedef struct JsonStack {
2732 JsonExpect expect;
2733 JsonVariant **elements;
2734 size_t n_elements, n_elements_allocated;
2735 unsigned line_before;
2736 unsigned column_before;
2737 size_t n_suppress; /* When building: if > 0, suppress this many subsequent elements. If == (size_t) -1, suppress all subsequent elements */
2738 } JsonStack;
2739
2740 static void json_stack_release(JsonStack *s) {
2741 assert(s);
2742
2743 json_variant_unref_many(s->elements, s->n_elements);
2744 s->elements = mfree(s->elements);
2745 }
2746
2747 static int json_parse_internal(
2748 const char **input,
2749 JsonSource *source,
2750 JsonParseFlags flags,
2751 JsonVariant **ret,
2752 unsigned *line,
2753 unsigned *column,
2754 bool continue_end) {
2755
2756 size_t n_stack = 1, n_stack_allocated = 0, i;
2757 unsigned line_buffer = 0, column_buffer = 0;
2758 void *tokenizer_state = NULL;
2759 JsonStack *stack = NULL;
2760 const char *p;
2761 int r;
2762
2763 assert_return(input, -EINVAL);
2764 assert_return(ret, -EINVAL);
2765
2766 p = *input;
2767
2768 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack))
2769 return -ENOMEM;
2770
2771 stack[0] = (JsonStack) {
2772 .expect = EXPECT_TOPLEVEL,
2773 };
2774
2775 if (!line)
2776 line = &line_buffer;
2777 if (!column)
2778 column = &column_buffer;
2779
2780 for (;;) {
2781 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL;
2782 _cleanup_free_ char *string = NULL;
2783 unsigned line_token, column_token;
2784 JsonStack *current;
2785 JsonValue value;
2786 int token;
2787
2788 assert(n_stack > 0);
2789 current = stack + n_stack - 1;
2790
2791 if (continue_end && current->expect == EXPECT_END)
2792 goto done;
2793
2794 token = json_tokenize(&p, &string, &value, &line_token, &column_token, &tokenizer_state, line, column);
2795 if (token < 0) {
2796 r = token;
2797 goto finish;
2798 }
2799
2800 switch (token) {
2801
2802 case JSON_TOKEN_END:
2803 if (current->expect != EXPECT_END) {
2804 r = -EINVAL;
2805 goto finish;
2806 }
2807
2808 assert(current->n_elements == 1);
2809 assert(n_stack == 1);
2810 goto done;
2811
2812 case JSON_TOKEN_COLON:
2813
2814 if (current->expect != EXPECT_OBJECT_COLON) {
2815 r = -EINVAL;
2816 goto finish;
2817 }
2818
2819 current->expect = EXPECT_OBJECT_VALUE;
2820 break;
2821
2822 case JSON_TOKEN_COMMA:
2823
2824 if (current->expect == EXPECT_OBJECT_COMMA)
2825 current->expect = EXPECT_OBJECT_NEXT_KEY;
2826 else if (current->expect == EXPECT_ARRAY_COMMA)
2827 current->expect = EXPECT_ARRAY_NEXT_ELEMENT;
2828 else {
2829 r = -EINVAL;
2830 goto finish;
2831 }
2832
2833 break;
2834
2835 case JSON_TOKEN_OBJECT_OPEN:
2836
2837 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2838 r = -EINVAL;
2839 goto finish;
2840 }
2841
2842 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2843 r = -ENOMEM;
2844 goto finish;
2845 }
2846 current = stack + n_stack - 1;
2847
2848 /* Prepare the expect for when we return from the child */
2849 if (current->expect == EXPECT_TOPLEVEL)
2850 current->expect = EXPECT_END;
2851 else if (current->expect == EXPECT_OBJECT_VALUE)
2852 current->expect = EXPECT_OBJECT_COMMA;
2853 else {
2854 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2855 current->expect = EXPECT_ARRAY_COMMA;
2856 }
2857
2858 stack[n_stack++] = (JsonStack) {
2859 .expect = EXPECT_OBJECT_FIRST_KEY,
2860 .line_before = line_token,
2861 .column_before = column_token,
2862 };
2863
2864 current = stack + n_stack - 1;
2865 break;
2866
2867 case JSON_TOKEN_OBJECT_CLOSE:
2868 if (!IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_COMMA)) {
2869 r = -EINVAL;
2870 goto finish;
2871 }
2872
2873 assert(n_stack > 1);
2874
2875 r = json_variant_new_object(&add, current->elements, current->n_elements);
2876 if (r < 0)
2877 goto finish;
2878
2879 line_token = current->line_before;
2880 column_token = current->column_before;
2881
2882 json_stack_release(current);
2883 n_stack--, current--;
2884
2885 break;
2886
2887 case JSON_TOKEN_ARRAY_OPEN:
2888 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2889 r = -EINVAL;
2890 goto finish;
2891 }
2892
2893 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
2894 r = -ENOMEM;
2895 goto finish;
2896 }
2897 current = stack + n_stack - 1;
2898
2899 /* Prepare the expect for when we return from the child */
2900 if (current->expect == EXPECT_TOPLEVEL)
2901 current->expect = EXPECT_END;
2902 else if (current->expect == EXPECT_OBJECT_VALUE)
2903 current->expect = EXPECT_OBJECT_COMMA;
2904 else {
2905 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2906 current->expect = EXPECT_ARRAY_COMMA;
2907 }
2908
2909 stack[n_stack++] = (JsonStack) {
2910 .expect = EXPECT_ARRAY_FIRST_ELEMENT,
2911 .line_before = line_token,
2912 .column_before = column_token,
2913 };
2914
2915 break;
2916
2917 case JSON_TOKEN_ARRAY_CLOSE:
2918 if (!IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_COMMA)) {
2919 r = -EINVAL;
2920 goto finish;
2921 }
2922
2923 assert(n_stack > 1);
2924
2925 r = json_variant_new_array(&add, current->elements, current->n_elements);
2926 if (r < 0)
2927 goto finish;
2928
2929 line_token = current->line_before;
2930 column_token = current->column_before;
2931
2932 json_stack_release(current);
2933 n_stack--, current--;
2934 break;
2935
2936 case JSON_TOKEN_STRING:
2937 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)) {
2938 r = -EINVAL;
2939 goto finish;
2940 }
2941
2942 r = json_variant_new_string(&add, string);
2943 if (r < 0)
2944 goto finish;
2945
2946 if (current->expect == EXPECT_TOPLEVEL)
2947 current->expect = EXPECT_END;
2948 else if (IN_SET(current->expect, EXPECT_OBJECT_FIRST_KEY, EXPECT_OBJECT_NEXT_KEY))
2949 current->expect = EXPECT_OBJECT_COLON;
2950 else if (current->expect == EXPECT_OBJECT_VALUE)
2951 current->expect = EXPECT_OBJECT_COMMA;
2952 else {
2953 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2954 current->expect = EXPECT_ARRAY_COMMA;
2955 }
2956
2957 break;
2958
2959 case JSON_TOKEN_REAL:
2960 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2961 r = -EINVAL;
2962 goto finish;
2963 }
2964
2965 r = json_variant_new_real(&add, value.real);
2966 if (r < 0)
2967 goto finish;
2968
2969 if (current->expect == EXPECT_TOPLEVEL)
2970 current->expect = EXPECT_END;
2971 else if (current->expect == EXPECT_OBJECT_VALUE)
2972 current->expect = EXPECT_OBJECT_COMMA;
2973 else {
2974 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2975 current->expect = EXPECT_ARRAY_COMMA;
2976 }
2977
2978 break;
2979
2980 case JSON_TOKEN_INTEGER:
2981 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
2982 r = -EINVAL;
2983 goto finish;
2984 }
2985
2986 r = json_variant_new_integer(&add, value.integer);
2987 if (r < 0)
2988 goto finish;
2989
2990 if (current->expect == EXPECT_TOPLEVEL)
2991 current->expect = EXPECT_END;
2992 else if (current->expect == EXPECT_OBJECT_VALUE)
2993 current->expect = EXPECT_OBJECT_COMMA;
2994 else {
2995 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
2996 current->expect = EXPECT_ARRAY_COMMA;
2997 }
2998
2999 break;
3000
3001 case JSON_TOKEN_UNSIGNED:
3002 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3003 r = -EINVAL;
3004 goto finish;
3005 }
3006
3007 r = json_variant_new_unsigned(&add, value.unsig);
3008 if (r < 0)
3009 goto finish;
3010
3011 if (current->expect == EXPECT_TOPLEVEL)
3012 current->expect = EXPECT_END;
3013 else if (current->expect == EXPECT_OBJECT_VALUE)
3014 current->expect = EXPECT_OBJECT_COMMA;
3015 else {
3016 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3017 current->expect = EXPECT_ARRAY_COMMA;
3018 }
3019
3020 break;
3021
3022 case JSON_TOKEN_BOOLEAN:
3023 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3024 r = -EINVAL;
3025 goto finish;
3026 }
3027
3028 r = json_variant_new_boolean(&add, value.boolean);
3029 if (r < 0)
3030 goto finish;
3031
3032 if (current->expect == EXPECT_TOPLEVEL)
3033 current->expect = EXPECT_END;
3034 else if (current->expect == EXPECT_OBJECT_VALUE)
3035 current->expect = EXPECT_OBJECT_COMMA;
3036 else {
3037 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3038 current->expect = EXPECT_ARRAY_COMMA;
3039 }
3040
3041 break;
3042
3043 case JSON_TOKEN_NULL:
3044 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT)) {
3045 r = -EINVAL;
3046 goto finish;
3047 }
3048
3049 r = json_variant_new_null(&add);
3050 if (r < 0)
3051 goto finish;
3052
3053 if (current->expect == EXPECT_TOPLEVEL)
3054 current->expect = EXPECT_END;
3055 else if (current->expect == EXPECT_OBJECT_VALUE)
3056 current->expect = EXPECT_OBJECT_COMMA;
3057 else {
3058 assert(IN_SET(current->expect, EXPECT_ARRAY_FIRST_ELEMENT, EXPECT_ARRAY_NEXT_ELEMENT));
3059 current->expect = EXPECT_ARRAY_COMMA;
3060 }
3061
3062 break;
3063
3064 default:
3065 assert_not_reached("Unexpected token");
3066 }
3067
3068 if (add) {
3069 /* If we are asked to make this parsed object sensitive, then let's apply this
3070 * immediately after allocating each variant, so that when we abort half-way
3071 * everything we already allocated that is then freed is correctly marked. */
3072 if (FLAGS_SET(flags, JSON_PARSE_SENSITIVE))
3073 json_variant_sensitive(add);
3074
3075 (void) json_variant_set_source(&add, source, line_token, column_token);
3076
3077 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
3078 r = -ENOMEM;
3079 goto finish;
3080 }
3081
3082 current->elements[current->n_elements++] = TAKE_PTR(add);
3083 }
3084 }
3085
3086 done:
3087 assert(n_stack == 1);
3088 assert(stack[0].n_elements == 1);
3089
3090 *ret = json_variant_ref(stack[0].elements[0]);
3091 *input = p;
3092 r = 0;
3093
3094 finish:
3095 for (i = 0; i < n_stack; i++)
3096 json_stack_release(stack + i);
3097
3098 free(stack);
3099
3100 return r;
3101 }
3102
3103 int json_parse(const char *input, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
3104 return json_parse_internal(&input, NULL, flags, ret, ret_line, ret_column, false);
3105 }
3106
3107 int json_parse_continue(const char **p, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
3108 return json_parse_internal(p, NULL, flags, ret, ret_line, ret_column, true);
3109 }
3110
3111 int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
3112 _cleanup_(json_source_unrefp) JsonSource *source = NULL;
3113 _cleanup_free_ char *text = NULL;
3114 const char *p;
3115 int r;
3116
3117 if (f)
3118 r = read_full_stream(f, &text, NULL);
3119 else if (path)
3120 r = read_full_file_full(dir_fd, path, 0, &text, NULL);
3121 else
3122 return -EINVAL;
3123 if (r < 0)
3124 return r;
3125
3126 if (path) {
3127 source = json_source_new(path);
3128 if (!source)
3129 return -ENOMEM;
3130 }
3131
3132 p = text;
3133 return json_parse_internal(&p, source, flags, ret, ret_line, ret_column, false);
3134 }
3135
3136 int json_buildv(JsonVariant **ret, va_list ap) {
3137 JsonStack *stack = NULL;
3138 size_t n_stack = 1, n_stack_allocated = 0, i;
3139 int r;
3140
3141 assert_return(ret, -EINVAL);
3142
3143 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack))
3144 return -ENOMEM;
3145
3146 stack[0] = (JsonStack) {
3147 .expect = EXPECT_TOPLEVEL,
3148 };
3149
3150 for (;;) {
3151 _cleanup_(json_variant_unrefp) JsonVariant *add = NULL;
3152 size_t n_subtract = 0; /* how much to subtract from current->n_suppress, i.e. how many elements would
3153 * have been added to the current variant */
3154 JsonStack *current;
3155 int command;
3156
3157 assert(n_stack > 0);
3158 current = stack + n_stack - 1;
3159
3160 if (current->expect == EXPECT_END)
3161 goto done;
3162
3163 command = va_arg(ap, int);
3164
3165 switch (command) {
3166
3167 case _JSON_BUILD_STRING: {
3168 const char *p;
3169
3170 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3171 r = -EINVAL;
3172 goto finish;
3173 }
3174
3175 p = va_arg(ap, const char *);
3176
3177 if (current->n_suppress == 0) {
3178 r = json_variant_new_string(&add, p);
3179 if (r < 0)
3180 goto finish;
3181 }
3182
3183 n_subtract = 1;
3184
3185 if (current->expect == EXPECT_TOPLEVEL)
3186 current->expect = EXPECT_END;
3187 else if (current->expect == EXPECT_OBJECT_VALUE)
3188 current->expect = EXPECT_OBJECT_KEY;
3189 else
3190 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3191
3192 break;
3193 }
3194
3195 case _JSON_BUILD_INTEGER: {
3196 intmax_t j;
3197
3198 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3199 r = -EINVAL;
3200 goto finish;
3201 }
3202
3203 j = va_arg(ap, intmax_t);
3204
3205 if (current->n_suppress == 0) {
3206 r = json_variant_new_integer(&add, j);
3207 if (r < 0)
3208 goto finish;
3209 }
3210
3211 n_subtract = 1;
3212
3213 if (current->expect == EXPECT_TOPLEVEL)
3214 current->expect = EXPECT_END;
3215 else if (current->expect == EXPECT_OBJECT_VALUE)
3216 current->expect = EXPECT_OBJECT_KEY;
3217 else
3218 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3219
3220 break;
3221 }
3222
3223 case _JSON_BUILD_UNSIGNED: {
3224 uintmax_t j;
3225
3226 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3227 r = -EINVAL;
3228 goto finish;
3229 }
3230
3231 j = va_arg(ap, uintmax_t);
3232
3233 if (current->n_suppress == 0) {
3234 r = json_variant_new_unsigned(&add, j);
3235 if (r < 0)
3236 goto finish;
3237 }
3238
3239 n_subtract = 1;
3240
3241 if (current->expect == EXPECT_TOPLEVEL)
3242 current->expect = EXPECT_END;
3243 else if (current->expect == EXPECT_OBJECT_VALUE)
3244 current->expect = EXPECT_OBJECT_KEY;
3245 else
3246 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3247
3248 break;
3249 }
3250
3251 case _JSON_BUILD_REAL: {
3252 long double d;
3253
3254 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3255 r = -EINVAL;
3256 goto finish;
3257 }
3258
3259 d = va_arg(ap, long double);
3260
3261 if (current->n_suppress == 0) {
3262 r = json_variant_new_real(&add, d);
3263 if (r < 0)
3264 goto finish;
3265 }
3266
3267 n_subtract = 1;
3268
3269 if (current->expect == EXPECT_TOPLEVEL)
3270 current->expect = EXPECT_END;
3271 else if (current->expect == EXPECT_OBJECT_VALUE)
3272 current->expect = EXPECT_OBJECT_KEY;
3273 else
3274 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3275
3276 break;
3277 }
3278
3279 case _JSON_BUILD_BOOLEAN: {
3280 bool b;
3281
3282 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3283 r = -EINVAL;
3284 goto finish;
3285 }
3286
3287 b = va_arg(ap, int);
3288
3289 if (current->n_suppress == 0) {
3290 r = json_variant_new_boolean(&add, b);
3291 if (r < 0)
3292 goto finish;
3293 }
3294
3295 n_subtract = 1;
3296
3297 if (current->expect == EXPECT_TOPLEVEL)
3298 current->expect = EXPECT_END;
3299 else if (current->expect == EXPECT_OBJECT_VALUE)
3300 current->expect = EXPECT_OBJECT_KEY;
3301 else
3302 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3303
3304 break;
3305 }
3306
3307 case _JSON_BUILD_NULL:
3308
3309 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3310 r = -EINVAL;
3311 goto finish;
3312 }
3313
3314 if (current->n_suppress == 0) {
3315 r = json_variant_new_null(&add);
3316 if (r < 0)
3317 goto finish;
3318 }
3319
3320 n_subtract = 1;
3321
3322 if (current->expect == EXPECT_TOPLEVEL)
3323 current->expect = EXPECT_END;
3324 else if (current->expect == EXPECT_OBJECT_VALUE)
3325 current->expect = EXPECT_OBJECT_KEY;
3326 else
3327 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3328
3329 break;
3330
3331 case _JSON_BUILD_VARIANT:
3332
3333 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3334 r = -EINVAL;
3335 goto finish;
3336 }
3337
3338 /* Note that we don't care for current->n_suppress here, after all the variant is already
3339 * allocated anyway... */
3340 add = va_arg(ap, JsonVariant*);
3341 if (!add)
3342 add = JSON_VARIANT_MAGIC_NULL;
3343 else
3344 json_variant_ref(add);
3345
3346 n_subtract = 1;
3347
3348 if (current->expect == EXPECT_TOPLEVEL)
3349 current->expect = EXPECT_END;
3350 else if (current->expect == EXPECT_OBJECT_VALUE)
3351 current->expect = EXPECT_OBJECT_KEY;
3352 else
3353 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3354
3355 break;
3356
3357 case _JSON_BUILD_LITERAL: {
3358 const char *l;
3359
3360 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3361 r = -EINVAL;
3362 goto finish;
3363 }
3364
3365 l = va_arg(ap, const char *);
3366
3367 if (l) {
3368 /* Note that we don't care for current->n_suppress here, we should generate parsing
3369 * errors even in suppressed object properties */
3370
3371 r = json_parse(l, 0, &add, NULL, NULL);
3372 if (r < 0)
3373 goto finish;
3374 } else
3375 add = JSON_VARIANT_MAGIC_NULL;
3376
3377 n_subtract = 1;
3378
3379 if (current->expect == EXPECT_TOPLEVEL)
3380 current->expect = EXPECT_END;
3381 else if (current->expect == EXPECT_OBJECT_VALUE)
3382 current->expect = EXPECT_OBJECT_KEY;
3383 else
3384 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3385
3386 break;
3387 }
3388
3389 case _JSON_BUILD_ARRAY_BEGIN:
3390
3391 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3392 r = -EINVAL;
3393 goto finish;
3394 }
3395
3396 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
3397 r = -ENOMEM;
3398 goto finish;
3399 }
3400 current = stack + n_stack - 1;
3401
3402 if (current->expect == EXPECT_TOPLEVEL)
3403 current->expect = EXPECT_END;
3404 else if (current->expect == EXPECT_OBJECT_VALUE)
3405 current->expect = EXPECT_OBJECT_KEY;
3406 else
3407 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3408
3409 stack[n_stack++] = (JsonStack) {
3410 .expect = EXPECT_ARRAY_ELEMENT,
3411 .n_suppress = current->n_suppress != 0 ? (size_t) -1 : 0, /* if we shall suppress the
3412 * new array, then we should
3413 * also suppress all array
3414 * members */
3415 };
3416
3417 break;
3418
3419 case _JSON_BUILD_ARRAY_END:
3420 if (current->expect != EXPECT_ARRAY_ELEMENT) {
3421 r = -EINVAL;
3422 goto finish;
3423 }
3424
3425 assert(n_stack > 1);
3426
3427 if (current->n_suppress == 0) {
3428 r = json_variant_new_array(&add, current->elements, current->n_elements);
3429 if (r < 0)
3430 goto finish;
3431 }
3432
3433 n_subtract = 1;
3434
3435 json_stack_release(current);
3436 n_stack--, current--;
3437
3438 break;
3439
3440 case _JSON_BUILD_STRV: {
3441 char **l;
3442
3443 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3444 r = -EINVAL;
3445 goto finish;
3446 }
3447
3448 l = va_arg(ap, char **);
3449
3450 if (current->n_suppress == 0) {
3451 r = json_variant_new_array_strv(&add, l);
3452 if (r < 0)
3453 goto finish;
3454 }
3455
3456 n_subtract = 1;
3457
3458 if (current->expect == EXPECT_TOPLEVEL)
3459 current->expect = EXPECT_END;
3460 else if (current->expect == EXPECT_OBJECT_VALUE)
3461 current->expect = EXPECT_OBJECT_KEY;
3462 else
3463 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3464
3465 break;
3466 }
3467
3468 case _JSON_BUILD_BASE64: {
3469 const void *p;
3470 size_t n;
3471
3472 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3473 r = -EINVAL;
3474 goto finish;
3475 }
3476
3477 p = va_arg(ap, const void *);
3478 n = va_arg(ap, size_t);
3479
3480 if (current->n_suppress == 0) {
3481 r = json_variant_new_base64(&add, p, n);
3482 if (r < 0)
3483 goto finish;
3484 }
3485
3486 n_subtract = 1;
3487
3488 if (current->expect == EXPECT_TOPLEVEL)
3489 current->expect = EXPECT_END;
3490 else if (current->expect == EXPECT_OBJECT_VALUE)
3491 current->expect = EXPECT_OBJECT_KEY;
3492 else
3493 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3494
3495 break;
3496 }
3497
3498 case _JSON_BUILD_OBJECT_BEGIN:
3499
3500 if (!IN_SET(current->expect, EXPECT_TOPLEVEL, EXPECT_OBJECT_VALUE, EXPECT_ARRAY_ELEMENT)) {
3501 r = -EINVAL;
3502 goto finish;
3503 }
3504
3505 if (!GREEDY_REALLOC(stack, n_stack_allocated, n_stack+1)) {
3506 r = -ENOMEM;
3507 goto finish;
3508 }
3509 current = stack + n_stack - 1;
3510
3511 if (current->expect == EXPECT_TOPLEVEL)
3512 current->expect = EXPECT_END;
3513 else if (current->expect == EXPECT_OBJECT_VALUE)
3514 current->expect = EXPECT_OBJECT_KEY;
3515 else
3516 assert(current->expect == EXPECT_ARRAY_ELEMENT);
3517
3518 stack[n_stack++] = (JsonStack) {
3519 .expect = EXPECT_OBJECT_KEY,
3520 .n_suppress = current->n_suppress != 0 ? (size_t) -1 : 0, /* if we shall suppress the
3521 * new object, then we should
3522 * also suppress all object
3523 * members */
3524 };
3525
3526 break;
3527
3528 case _JSON_BUILD_OBJECT_END:
3529
3530 if (current->expect != EXPECT_OBJECT_KEY) {
3531 r = -EINVAL;
3532 goto finish;
3533 }
3534
3535 assert(n_stack > 1);
3536
3537 if (current->n_suppress == 0) {
3538 r = json_variant_new_object(&add, current->elements, current->n_elements);
3539 if (r < 0)
3540 goto finish;
3541 }
3542
3543 n_subtract = 1;
3544
3545 json_stack_release(current);
3546 n_stack--, current--;
3547
3548 break;
3549
3550 case _JSON_BUILD_PAIR: {
3551 const char *n;
3552
3553 if (current->expect != EXPECT_OBJECT_KEY) {
3554 r = -EINVAL;
3555 goto finish;
3556 }
3557
3558 n = va_arg(ap, const char *);
3559
3560 if (current->n_suppress == 0) {
3561 r = json_variant_new_string(&add, n);
3562 if (r < 0)
3563 goto finish;
3564 }
3565
3566 n_subtract = 1;
3567
3568 current->expect = EXPECT_OBJECT_VALUE;
3569 break;
3570 }
3571
3572 case _JSON_BUILD_PAIR_CONDITION: {
3573 const char *n;
3574 bool b;
3575
3576 if (current->expect != EXPECT_OBJECT_KEY) {
3577 r = -EINVAL;
3578 goto finish;
3579 }
3580
3581 b = va_arg(ap, int);
3582 n = va_arg(ap, const char *);
3583
3584 if (b && current->n_suppress == 0) {
3585 r = json_variant_new_string(&add, n);
3586 if (r < 0)
3587 goto finish;
3588 }
3589
3590 n_subtract = 1; /* we generated one item */
3591
3592 if (!b && current->n_suppress != (size_t) -1)
3593 current->n_suppress += 2; /* Suppress this one and the next item */
3594
3595 current->expect = EXPECT_OBJECT_VALUE;
3596 break;
3597 }}
3598
3599 /* If a variant was generated, add it to our current variant, but only if we are not supposed to suppress additions */
3600 if (add && current->n_suppress == 0) {
3601 if (!GREEDY_REALLOC(current->elements, current->n_elements_allocated, current->n_elements + 1)) {
3602 r = -ENOMEM;
3603 goto finish;
3604 }
3605
3606 current->elements[current->n_elements++] = TAKE_PTR(add);
3607 }
3608
3609 /* If we are supposed to suppress items, let's subtract how many items where generated from that
3610 * counter. Except if the counter is (size_t) -1, i.e. we shall suppress an infinite number of elements
3611 * on this stack level */
3612 if (current->n_suppress != (size_t) -1) {
3613 if (current->n_suppress <= n_subtract) /* Saturated */
3614 current->n_suppress = 0;
3615 else
3616 current->n_suppress -= n_subtract;
3617 }
3618 }
3619
3620 done:
3621 assert(n_stack == 1);
3622 assert(stack[0].n_elements == 1);
3623
3624 *ret = json_variant_ref(stack[0].elements[0]);
3625 r = 0;
3626
3627 finish:
3628 for (i = 0; i < n_stack; i++)
3629 json_stack_release(stack + i);
3630
3631 free(stack);
3632
3633 return r;
3634 }
3635
3636 int json_build(JsonVariant **ret, ...) {
3637 va_list ap;
3638 int r;
3639
3640 va_start(ap, ret);
3641 r = json_buildv(ret, ap);
3642 va_end(ap);
3643
3644 return r;
3645 }
3646
3647 int json_log_internal(
3648 JsonVariant *variant,
3649 int level,
3650 int error,
3651 const char *file,
3652 int line,
3653 const char *func,
3654 const char *format, ...) {
3655
3656 PROTECT_ERRNO;
3657
3658 unsigned source_line, source_column;
3659 char buffer[LINE_MAX];
3660 const char *source;
3661 va_list ap;
3662 int r;
3663
3664 errno = ERRNO_VALUE(error);
3665
3666 va_start(ap, format);
3667 (void) vsnprintf(buffer, sizeof buffer, format, ap);
3668 va_end(ap);
3669
3670 if (variant) {
3671 r = json_variant_get_source(variant, &source, &source_line, &source_column);
3672 if (r < 0)
3673 return r;
3674 } else {
3675 source = NULL;
3676 source_line = 0;
3677 source_column = 0;
3678 }
3679
3680 if (source && source_line > 0 && source_column > 0)
3681 return log_struct_internal(
3682 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3683 error,
3684 file, line, func,
3685 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3686 "CONFIG_FILE=%s", source,
3687 "CONFIG_LINE=%u", source_line,
3688 "CONFIG_COLUMN=%u", source_column,
3689 LOG_MESSAGE("%s:%u:%u: %s", source, source_line, source_column, buffer),
3690 NULL);
3691 else
3692 return log_struct_internal(
3693 LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
3694 error,
3695 file, line, func,
3696 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
3697 LOG_MESSAGE("%s", buffer),
3698 NULL);
3699 }
3700
3701 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) {
3702 const JsonDispatch *p;
3703 size_t i, n, m;
3704 int r, done = 0;
3705 bool *found;
3706
3707 if (!json_variant_is_object(v)) {
3708 json_log(v, flags, 0, "JSON variant is not an object.");
3709
3710 if (flags & JSON_PERMISSIVE)
3711 return 0;
3712
3713 return -EINVAL;
3714 }
3715
3716 for (p = table, m = 0; p->name; p++)
3717 m++;
3718
3719 found = newa0(bool, m);
3720
3721 n = json_variant_elements(v);
3722 for (i = 0; i < n; i += 2) {
3723 JsonVariant *key, *value;
3724
3725 assert_se(key = json_variant_by_index(v, i));
3726 assert_se(value = json_variant_by_index(v, i+1));
3727
3728 for (p = table; p->name; p++)
3729 if (p->name == (const char*) -1 ||
3730 streq_ptr(json_variant_string(key), p->name))
3731 break;
3732
3733 if (p->name) { /* Found a matching entry! :-) */
3734 JsonDispatchFlags merged_flags;
3735
3736 merged_flags = flags | p->flags;
3737
3738 if (p->type != _JSON_VARIANT_TYPE_INVALID &&
3739 !json_variant_has_type(value, p->type)) {
3740
3741 json_log(value, merged_flags, 0,
3742 "Object field '%s' has wrong type %s, expected %s.", json_variant_string(key),
3743 json_variant_type_to_string(json_variant_type(value)), json_variant_type_to_string(p->type));
3744
3745 if (merged_flags & JSON_PERMISSIVE)
3746 continue;
3747
3748 return -EINVAL;
3749 }
3750
3751 if (found[p-table]) {
3752 json_log(value, merged_flags, 0, "Duplicate object field '%s'.", json_variant_string(key));
3753
3754 if (merged_flags & JSON_PERMISSIVE)
3755 continue;
3756
3757 return -ENOTUNIQ;
3758 }
3759
3760 found[p-table] = true;
3761
3762 if (p->callback) {
3763 r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset);
3764 if (r < 0) {
3765 if (merged_flags & JSON_PERMISSIVE)
3766 continue;
3767
3768 return r;
3769 }
3770 }
3771
3772 done ++;
3773
3774 } else { /* Didn't find a matching entry! :-( */
3775
3776 if (bad) {
3777 r = bad(json_variant_string(key), value, flags, userdata);
3778 if (r < 0) {
3779 if (flags & JSON_PERMISSIVE)
3780 continue;
3781
3782 return r;
3783 } else
3784 done ++;
3785
3786 } else {
3787 json_log(value, flags, 0, "Unexpected object field '%s'.", json_variant_string(key));
3788
3789 if (flags & JSON_PERMISSIVE)
3790 continue;
3791
3792 return -EADDRNOTAVAIL;
3793 }
3794 }
3795 }
3796
3797 for (p = table; p->name; p++) {
3798 JsonDispatchFlags merged_flags = p->flags | flags;
3799
3800 if ((merged_flags & JSON_MANDATORY) && !found[p-table]) {
3801 json_log(v, merged_flags, 0, "Missing object field '%s'.", p->name);
3802
3803 if ((merged_flags & JSON_PERMISSIVE))
3804 continue;
3805
3806 return -ENXIO;
3807 }
3808 }
3809
3810 return done;
3811 }
3812
3813 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3814 bool *b = userdata;
3815
3816 assert(variant);
3817 assert(b);
3818
3819 if (!json_variant_is_boolean(variant))
3820 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name));
3821
3822 *b = json_variant_boolean(variant);
3823 return 0;
3824 }
3825
3826 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3827 int *b = userdata;
3828
3829 assert(variant);
3830 assert(b);
3831
3832 if (json_variant_is_null(variant)) {
3833 *b = -1;
3834 return 0;
3835 }
3836
3837 if (!json_variant_is_boolean(variant))
3838 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name));
3839
3840 *b = json_variant_boolean(variant);
3841 return 0;
3842 }
3843
3844 int json_dispatch_integer(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3845 intmax_t *i = userdata;
3846
3847 assert(variant);
3848 assert(i);
3849
3850 if (!json_variant_is_integer(variant))
3851 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
3852
3853 *i = json_variant_integer(variant);
3854 return 0;
3855 }
3856
3857 int json_dispatch_unsigned(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3858 uintmax_t *u = userdata;
3859
3860 assert(variant);
3861 assert(u);
3862
3863 if (!json_variant_is_unsigned(variant))
3864 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer.", strna(name));
3865
3866 *u = json_variant_unsigned(variant);
3867 return 0;
3868 }
3869
3870 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3871 uint32_t *u = userdata;
3872
3873 assert(variant);
3874 assert(u);
3875
3876 if (!json_variant_is_unsigned(variant))
3877 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an unsigned integer.", strna(name));
3878
3879 if (json_variant_unsigned(variant) > UINT32_MAX)
3880 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
3881
3882 *u = (uint32_t) json_variant_unsigned(variant);
3883 return 0;
3884 }
3885
3886 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3887 int32_t *i = userdata;
3888
3889 assert(variant);
3890 assert(i);
3891
3892 if (!json_variant_is_integer(variant))
3893 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an integer.", strna(name));
3894
3895 if (json_variant_integer(variant) < INT32_MIN || json_variant_integer(variant) > INT32_MAX)
3896 return json_log(variant, flags, SYNTHETIC_ERRNO(ERANGE), "JSON field '%s' out of bounds.", strna(name));
3897
3898 *i = (int32_t) json_variant_integer(variant);
3899 return 0;
3900 }
3901
3902 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3903 char **s = userdata;
3904 int r;
3905
3906 assert(variant);
3907 assert(s);
3908
3909 if (json_variant_is_null(variant)) {
3910 *s = mfree(*s);
3911 return 0;
3912 }
3913
3914 if (!json_variant_is_string(variant))
3915 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
3916
3917 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
3918 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
3919
3920 r = free_and_strdup(s, json_variant_string(variant));
3921 if (r < 0)
3922 return json_log(variant, flags, r, "Failed to allocate string: %m");
3923
3924 return 0;
3925 }
3926
3927 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3928 _cleanup_strv_free_ char **l = NULL;
3929 char ***s = userdata;
3930 JsonVariant *e;
3931 int r;
3932
3933 assert(variant);
3934 assert(s);
3935
3936 if (json_variant_is_null(variant)) {
3937 *s = strv_free(*s);
3938 return 0;
3939 }
3940
3941 /* Let's be flexible here: accept a single string in place of a single-item array */
3942 if (json_variant_is_string(variant)) {
3943 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(variant)))
3944 return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
3945
3946 l = strv_new(json_variant_string(variant));
3947 if (!l)
3948 return log_oom();
3949
3950 strv_free_and_replace(*s, l);
3951 return 0;
3952 }
3953
3954 if (!json_variant_is_array(variant))
3955 return json_log(variant, SYNTHETIC_ERRNO(EINVAL), flags, "JSON field '%s' is not an array.", strna(name));
3956
3957 JSON_VARIANT_ARRAY_FOREACH(e, variant) {
3958 if (!json_variant_is_string(e))
3959 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON array element is not a string.");
3960
3961 if ((flags & JSON_SAFE) && !string_is_safe(json_variant_string(e)))
3962 return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' contains unsafe characters, refusing.", strna(name));
3963
3964 r = strv_extend(&l, json_variant_string(e));
3965 if (r < 0)
3966 return json_log(e, flags, r, "Failed to append array element: %m");
3967 }
3968
3969 strv_free_and_replace(*s, l);
3970 return 0;
3971 }
3972
3973 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
3974 JsonVariant **p = userdata;
3975
3976 assert(variant);
3977 assert(p);
3978
3979 json_variant_unref(*p);
3980 *p = json_variant_ref(variant);
3981
3982 return 0;
3983 }
3984
3985 static int json_cmp_strings(const void *x, const void *y) {
3986 JsonVariant *const *a = x, *const *b = y;
3987
3988 if (!json_variant_is_string(*a) || !json_variant_is_string(*b))
3989 return CMP(*a, *b);
3990
3991 return strcmp(json_variant_string(*a), json_variant_string(*b));
3992 }
3993
3994 int json_variant_sort(JsonVariant **v) {
3995 _cleanup_free_ JsonVariant **a = NULL;
3996 JsonVariant *n = NULL;
3997 size_t i, m;
3998 int r;
3999
4000 assert(v);
4001
4002 if (json_variant_is_sorted(*v))
4003 return 0;
4004
4005 if (!json_variant_is_object(*v))
4006 return -EMEDIUMTYPE;
4007
4008 /* Sorts they key/value pairs in an object 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_by_index(*v, i);
4017
4018 qsort(a, m/2, sizeof(JsonVariant*)*2, json_cmp_strings);
4019
4020 r = json_variant_new_object(&n, a, m);
4021 if (r < 0)
4022 return r;
4023 if (!n->sorted) /* Check if this worked. This will fail if there are multiple identical keys used. */
4024 return -ENOTUNIQ;
4025
4026 json_variant_unref(*v);
4027 *v = n;
4028
4029 return 1;
4030 }
4031
4032 int json_variant_normalize(JsonVariant **v) {
4033 _cleanup_free_ JsonVariant **a = NULL;
4034 JsonVariant *n = NULL;
4035 size_t i, j, m;
4036 int r;
4037
4038 assert(v);
4039
4040 if (json_variant_is_normalized(*v))
4041 return 0;
4042
4043 if (!json_variant_is_object(*v) && !json_variant_is_array(*v))
4044 return -EMEDIUMTYPE;
4045
4046 /* Sorts the key/value pairs in an object variant anywhere down the tree in the specified variant */
4047
4048 m = json_variant_elements(*v);
4049 a = new(JsonVariant*, m);
4050 if (!a)
4051 return -ENOMEM;
4052
4053 for (i = 0; i < m; i++) {
4054 a[i] = json_variant_ref(json_variant_by_index(*v, i));
4055
4056 r = json_variant_normalize(a + i);
4057 if (r < 0)
4058 goto finish;
4059 }
4060
4061 qsort(a, m/2, sizeof(JsonVariant*)*2, json_cmp_strings);
4062
4063 if (json_variant_is_object(*v))
4064 r = json_variant_new_object(&n, a, m);
4065 else {
4066 assert(json_variant_is_array(*v));
4067 r = json_variant_new_array(&n, a, m);
4068 }
4069 if (r < 0)
4070 goto finish;
4071 if (!n->normalized) { /* Let's see if normalization worked. It will fail if there are multiple
4072 * identical keys used in the same object anywhere, or if there are floating
4073 * point numbers used (see below) */
4074 r = -ENOTUNIQ;
4075 goto finish;
4076 }
4077
4078 json_variant_unref(*v);
4079 *v = n;
4080
4081 r = 1;
4082
4083 finish:
4084 for (j = 0; j < i; j++)
4085 json_variant_unref(a[j]);
4086
4087 return r;
4088 }
4089
4090 bool json_variant_is_normalized(JsonVariant *v) {
4091
4092 /* For now, let's consider anything containing numbers not expressible as integers as
4093 * non-normalized. That's because we cannot sensibly compare them due to accuracy issues, nor even
4094 * store them if they are too large. */
4095 if (json_variant_is_real(v) && !json_variant_is_integer(v) && !json_variant_is_unsigned(v))
4096 return false;
4097
4098 /* The concept only applies to variants that include other variants, i.e. objects and arrays. All
4099 * others are normalized anyway. */
4100 if (!json_variant_is_object(v) && !json_variant_is_array(v))
4101 return true;
4102
4103 /* Empty objects/arrays don't include any other variant, hence are always normalized too */
4104 if (json_variant_elements(v) == 0)
4105 return true;
4106
4107 return v->normalized; /* For everything else there's an explicit boolean we maintain */
4108 }
4109
4110 bool json_variant_is_sorted(JsonVariant *v) {
4111
4112 /* Returns true if all key/value pairs of an object are properly sorted. Note that this only applies
4113 * to objects, not arrays. */
4114
4115 if (!json_variant_is_object(v))
4116 return true;
4117 if (json_variant_elements(v) <= 1)
4118 return true;
4119
4120 return v->sorted;
4121 }
4122
4123 int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size) {
4124
4125 if (!json_variant_is_string(v))
4126 return -EINVAL;
4127
4128 return unbase64mem(json_variant_string(v), (size_t) -1, ret, ret_size);
4129 }
4130
4131 static const char* const json_variant_type_table[_JSON_VARIANT_TYPE_MAX] = {
4132 [JSON_VARIANT_STRING] = "string",
4133 [JSON_VARIANT_INTEGER] = "integer",
4134 [JSON_VARIANT_UNSIGNED] = "unsigned",
4135 [JSON_VARIANT_REAL] = "real",
4136 [JSON_VARIANT_NUMBER] = "number",
4137 [JSON_VARIANT_BOOLEAN] = "boolean",
4138 [JSON_VARIANT_ARRAY] = "array",
4139 [JSON_VARIANT_OBJECT] = "object",
4140 [JSON_VARIANT_NULL] = "null",
4141 };
4142
4143 DEFINE_STRING_TABLE_LOOKUP(json_variant_type, JsonVariantType);