Coverage Report

Created: 2025-07-09 06:39

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