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