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