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