1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include <fcntl.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 
10 #include "sd-id128.h"
11 
12 #include "ether-addr-util.h"
13 #include "in-addr-util.h"
14 #include "log.h"
15 #include "macro.h"
16 #include "string-util.h"
17 #include "strv.h"
18 #include "time-util.h"
19 
20 /*
21   In case you wonder why we have our own JSON implementation, here are a couple of reasons why this implementation has
22   benefits over various other implementations:
23 
24   - We need support for 64bit signed and unsigned integers, i.e. the full 64,5bit range of -9223372036854775808…18446744073709551615
25   - All our variants are immutable after creation
26   - Special values such as true, false, zero, null, empty strings, empty array, empty objects require zero dynamic memory
27   - Progressive parsing
28   - Our integer/real type implicitly converts, but only if that's safe and loss-lessly possible
29   - There's a "builder" for putting together objects easily in varargs function calls
30   - There's a "dispatcher" for mapping objects to C data structures
31   - Every variant optionally carries parsing location information, which simplifies debugging and parse log error generation
32   - Formatter has color, line, column support
33 
34   Limitations:
35   - Doesn't allow embedded NUL in strings
36   - Can't store integers outside of the -9223372036854775808…18446744073709551615 range (it will use 'double' for
37     values outside this range, which is lossy)
38   - Can't store negative zero (will be treated identical to positive zero, and not retained across serialization)
39   - Can't store non-integer numbers that can't be stored in "double" losslessly
40   - Allows creation and parsing of objects with duplicate keys. The "dispatcher" will refuse them however. This means
41     we can parse and pass around such objects, but will carefully refuse them when we convert them into our own data.
42 
43   (These limitations should be pretty much in line with those of other JSON implementations, in fact might be less
44   limiting in most cases even.)
45 */
46 
47 typedef struct JsonVariant JsonVariant;
48 
49 typedef enum JsonVariantType {
50         JSON_VARIANT_STRING,
51         JSON_VARIANT_INTEGER,
52         JSON_VARIANT_UNSIGNED,
53         JSON_VARIANT_REAL,
54         JSON_VARIANT_NUMBER, /* This a pseudo-type: we can never create variants of this type, but we use it as wildcard check for the above three types */
55         JSON_VARIANT_BOOLEAN,
56         JSON_VARIANT_ARRAY,
57         JSON_VARIANT_OBJECT,
58         JSON_VARIANT_NULL,
59         _JSON_VARIANT_TYPE_MAX,
60         _JSON_VARIANT_TYPE_INVALID = -EINVAL,
61 } JsonVariantType;
62 
63 int json_variant_new_stringn(JsonVariant **ret, const char *s, size_t n);
64 int json_variant_new_base64(JsonVariant **ret, const void *p, size_t n);
65 int json_variant_new_hex(JsonVariant **ret, const void *p, size_t n);
66 int json_variant_new_integer(JsonVariant **ret, int64_t i);
67 int json_variant_new_unsigned(JsonVariant **ret, uint64_t u);
68 int json_variant_new_real(JsonVariant **ret, double d);
69 int json_variant_new_boolean(JsonVariant **ret, bool b);
70 int json_variant_new_array(JsonVariant **ret, JsonVariant **array, size_t n);
71 int json_variant_new_array_bytes(JsonVariant **ret, const void *p, size_t n);
72 int json_variant_new_array_strv(JsonVariant **ret, char **l);
73 int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n);
74 int json_variant_new_null(JsonVariant **ret);
75 int json_variant_new_id128(JsonVariant **ret, sd_id128_t id);
76 
json_variant_new_string(JsonVariant ** ret,const char * s)77 static inline int json_variant_new_string(JsonVariant **ret, const char *s) {
78         return json_variant_new_stringn(ret, s, SIZE_MAX);
79 }
80 
81 JsonVariant *json_variant_ref(JsonVariant *v);
82 JsonVariant *json_variant_unref(JsonVariant *v);
83 void json_variant_unref_many(JsonVariant **array, size_t n);
84 
85 #define JSON_VARIANT_REPLACE(v, q)        \
86         do {                              \
87                 typeof(v)* _v = &(v);     \
88                 typeof(q) _q = (q);       \
89                 json_variant_unref(*_v);  \
90                 *_v = _q;                 \
91         } while(0)
92 
93 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonVariant *, json_variant_unref);
94 
95 const char *json_variant_string(JsonVariant *v);
96 int64_t json_variant_integer(JsonVariant *v);
97 uint64_t json_variant_unsigned(JsonVariant *v);
98 double json_variant_real(JsonVariant *v);
99 bool json_variant_boolean(JsonVariant *v);
100 
101 JsonVariantType json_variant_type(JsonVariant *v);
102 bool json_variant_has_type(JsonVariant *v, JsonVariantType type);
103 
json_variant_is_string(JsonVariant * v)104 static inline bool json_variant_is_string(JsonVariant *v) {
105         return json_variant_has_type(v, JSON_VARIANT_STRING);
106 }
107 
json_variant_is_integer(JsonVariant * v)108 static inline bool json_variant_is_integer(JsonVariant *v) {
109         return json_variant_has_type(v, JSON_VARIANT_INTEGER);
110 }
111 
json_variant_is_unsigned(JsonVariant * v)112 static inline bool json_variant_is_unsigned(JsonVariant *v) {
113         return json_variant_has_type(v, JSON_VARIANT_UNSIGNED);
114 }
115 
json_variant_is_real(JsonVariant * v)116 static inline bool json_variant_is_real(JsonVariant *v) {
117         return json_variant_has_type(v, JSON_VARIANT_REAL);
118 }
119 
json_variant_is_number(JsonVariant * v)120 static inline bool json_variant_is_number(JsonVariant *v) {
121         return json_variant_has_type(v, JSON_VARIANT_NUMBER);
122 }
123 
json_variant_is_boolean(JsonVariant * v)124 static inline bool json_variant_is_boolean(JsonVariant *v) {
125         return json_variant_has_type(v, JSON_VARIANT_BOOLEAN);
126 }
127 
json_variant_is_array(JsonVariant * v)128 static inline bool json_variant_is_array(JsonVariant *v) {
129         return json_variant_has_type(v, JSON_VARIANT_ARRAY);
130 }
131 
json_variant_is_object(JsonVariant * v)132 static inline bool json_variant_is_object(JsonVariant *v) {
133         return json_variant_has_type(v, JSON_VARIANT_OBJECT);
134 }
135 
json_variant_is_null(JsonVariant * v)136 static inline bool json_variant_is_null(JsonVariant *v) {
137         return json_variant_has_type(v, JSON_VARIANT_NULL);
138 }
139 
140 bool json_variant_is_negative(JsonVariant *v);
141 bool json_variant_is_blank_object(JsonVariant *v);
142 bool json_variant_is_blank_array(JsonVariant *v);
143 bool json_variant_is_normalized(JsonVariant *v);
144 bool json_variant_is_sorted(JsonVariant *v);
145 
146 size_t json_variant_elements(JsonVariant *v);
147 JsonVariant *json_variant_by_index(JsonVariant *v, size_t index);
148 JsonVariant *json_variant_by_key(JsonVariant *v, const char *key);
149 JsonVariant *json_variant_by_key_full(JsonVariant *v, const char *key, JsonVariant **ret_key);
150 
151 bool json_variant_equal(JsonVariant *a, JsonVariant *b);
152 
153 void json_variant_sensitive(JsonVariant *v);
154 bool json_variant_is_sensitive(JsonVariant *v);
155 
156 struct json_variant_foreach_state {
157         JsonVariant *variant;
158         size_t idx;
159 };
160 
161 #define _JSON_VARIANT_ARRAY_FOREACH(i, v, state)                        \
162         for (struct json_variant_foreach_state state = { (v), 0 };      \
163              json_variant_is_array(state.variant) &&                    \
164                      state.idx < json_variant_elements(state.variant) && \
165                      ({ i = json_variant_by_index(state.variant, state.idx); \
166                              true; });                                  \
167              state.idx++)
168 #define JSON_VARIANT_ARRAY_FOREACH(i, v)                                \
169         _JSON_VARIANT_ARRAY_FOREACH(i, v, UNIQ_T(state, UNIQ))
170 
171 #define _JSON_VARIANT_OBJECT_FOREACH(k, e, v, state)                    \
172         for (struct json_variant_foreach_state state = { (v), 0 };      \
173              json_variant_is_object(state.variant) &&                   \
174                      state.idx < json_variant_elements(state.variant) && \
175                      ({ k = json_variant_string(json_variant_by_index(state.variant, state.idx)); \
176                              e = json_variant_by_index(state.variant, state.idx + 1); \
177                              true; });                                  \
178              state.idx += 2)
179 #define JSON_VARIANT_OBJECT_FOREACH(k, e, v)                            \
180         _JSON_VARIANT_OBJECT_FOREACH(k, e, v, UNIQ_T(state, UNIQ))
181 
182 int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column);
183 
184 typedef enum JsonFormatFlags {
185         JSON_FORMAT_NEWLINE     = 1 << 0, /* suffix with newline */
186         JSON_FORMAT_PRETTY      = 1 << 1, /* add internal whitespace to appeal to human readers */
187         JSON_FORMAT_PRETTY_AUTO = 1 << 2, /* same, but only if connected to a tty (and JSON_FORMAT_NEWLINE otherwise) */
188         JSON_FORMAT_COLOR       = 1 << 3, /* insert ANSI color sequences */
189         JSON_FORMAT_COLOR_AUTO  = 1 << 4, /* insert ANSI color sequences if colors_enabled() says so */
190         JSON_FORMAT_SOURCE      = 1 << 5, /* prefix with source filename/line/column */
191         JSON_FORMAT_SSE         = 1 << 6, /* prefix/suffix with W3C server-sent events */
192         JSON_FORMAT_SEQ         = 1 << 7, /* prefix/suffix with RFC 7464 application/json-seq */
193         JSON_FORMAT_FLUSH       = 1 << 8, /* call fflush() after dumping JSON */
194         JSON_FORMAT_OFF         = 1 << 9, /* make json_variant_format() fail with -ENOEXEC */
195 } JsonFormatFlags;
196 
197 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret);
198 void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix);
199 
200 int json_variant_filter(JsonVariant **v, char **to_remove);
201 
202 int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value);
203 int json_variant_set_field_string(JsonVariant **v, const char *field, const char *value);
204 int json_variant_set_field_integer(JsonVariant **v, const char *field, int64_t value);
205 int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uint64_t value);
206 int json_variant_set_field_boolean(JsonVariant **v, const char *field, bool b);
207 int json_variant_set_field_strv(JsonVariant **v, const char *field, char **l);
208 
209 int json_variant_append_array(JsonVariant **v, JsonVariant *element);
210 
211 int json_variant_merge(JsonVariant **v, JsonVariant *m);
212 
213 int json_variant_strv(JsonVariant *v, char ***ret);
214 
215 int json_variant_sort(JsonVariant **v);
216 int json_variant_normalize(JsonVariant **v);
217 
218 typedef enum JsonParseFlags {
219         JSON_PARSE_SENSITIVE = 1 << 0, /* mark variant as "sensitive", i.e. something containing secret key material or such */
220 } JsonParseFlags;
221 
222 int json_parse(const char *string, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);
223 int json_parse_continue(const char **p, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);
224 int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);
225 
json_parse_file(FILE * f,const char * path,JsonParseFlags flags,JsonVariant ** ret,unsigned * ret_line,unsigned * ret_column)226 static inline int json_parse_file(FILE *f, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
227         return json_parse_file_at(f, AT_FDCWD, path, flags, ret, ret_line, ret_column);
228 }
229 
230 enum {
231         _JSON_BUILD_STRING,
232         _JSON_BUILD_INTEGER,
233         _JSON_BUILD_UNSIGNED,
234         _JSON_BUILD_REAL,
235         _JSON_BUILD_BOOLEAN,
236         _JSON_BUILD_ARRAY_BEGIN,
237         _JSON_BUILD_ARRAY_END,
238         _JSON_BUILD_OBJECT_BEGIN,
239         _JSON_BUILD_OBJECT_END,
240         _JSON_BUILD_PAIR,
241         _JSON_BUILD_PAIR_CONDITION,
242         _JSON_BUILD_NULL,
243         _JSON_BUILD_VARIANT,
244         _JSON_BUILD_VARIANT_ARRAY,
245         _JSON_BUILD_LITERAL,
246         _JSON_BUILD_STRV,
247         _JSON_BUILD_BASE64,
248         _JSON_BUILD_HEX,
249         _JSON_BUILD_ID128,
250         _JSON_BUILD_BYTE_ARRAY,
251         _JSON_BUILD_HW_ADDR,
252         _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO,
253         _JSON_BUILD_PAIR_FINITE_USEC,
254         _JSON_BUILD_PAIR_STRING_NON_EMPTY,
255         _JSON_BUILD_PAIR_STRV_NON_EMPTY,
256         _JSON_BUILD_PAIR_VARIANT_NON_NULL,
257         _JSON_BUILD_PAIR_VARIANT_ARRAY_NON_EMPTY,
258         _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL,
259         _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL,
260         _JSON_BUILD_PAIR_IN_ADDR_NON_NULL,
261         _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL,
262         _JSON_BUILD_PAIR_HW_ADDR_NON_NULL,
263         _JSON_BUILD_MAX,
264 };
265 
266 #define JSON_BUILD_STRING(s) _JSON_BUILD_STRING, (const char*) { s }
267 #define JSON_BUILD_INTEGER(i) _JSON_BUILD_INTEGER, (int64_t) { i }
268 #define JSON_BUILD_UNSIGNED(u) _JSON_BUILD_UNSIGNED, (uint64_t) { u }
269 #define JSON_BUILD_REAL(d) _JSON_BUILD_REAL, (double) { d }
270 #define JSON_BUILD_BOOLEAN(b) _JSON_BUILD_BOOLEAN, (bool) { b }
271 #define JSON_BUILD_ARRAY(...) _JSON_BUILD_ARRAY_BEGIN, __VA_ARGS__, _JSON_BUILD_ARRAY_END
272 #define JSON_BUILD_EMPTY_ARRAY _JSON_BUILD_ARRAY_BEGIN, _JSON_BUILD_ARRAY_END
273 #define JSON_BUILD_OBJECT(...) _JSON_BUILD_OBJECT_BEGIN, __VA_ARGS__, _JSON_BUILD_OBJECT_END
274 #define JSON_BUILD_EMPTY_OBJECT _JSON_BUILD_OBJECT_BEGIN, _JSON_BUILD_OBJECT_END
275 #define JSON_BUILD_PAIR(n, ...) _JSON_BUILD_PAIR, (const char*) { n }, __VA_ARGS__
276 #define JSON_BUILD_PAIR_CONDITION(c, n, ...) _JSON_BUILD_PAIR_CONDITION, (bool) { c }, (const char*) { n }, __VA_ARGS__
277 #define JSON_BUILD_NULL _JSON_BUILD_NULL
278 #define JSON_BUILD_VARIANT(v) _JSON_BUILD_VARIANT, (JsonVariant*) { v }
279 #define JSON_BUILD_VARIANT_ARRAY(v, n) _JSON_BUILD_VARIANT_ARRAY, (JsonVariant **) { v }, (size_t) { n }
280 #define JSON_BUILD_LITERAL(l) _JSON_BUILD_LITERAL, (const char*) { l }
281 #define JSON_BUILD_STRV(l) _JSON_BUILD_STRV, (char**) { l }
282 #define JSON_BUILD_BASE64(p, n) _JSON_BUILD_BASE64, (const void*) { p }, (size_t) { n }
283 #define JSON_BUILD_HEX(p, n) _JSON_BUILD_HEX, (const void*) { p }, (size_t) { n }
284 #define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, (const sd_id128_t*) { &(id) }
285 #define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, (const void*) { v }, (size_t) { n }
286 #define JSON_BUILD_CONST_STRING(s) _JSON_BUILD_VARIANT, JSON_VARIANT_STRING_CONST(s)
287 #define JSON_BUILD_IN4_ADDR(v) JSON_BUILD_BYTE_ARRAY((const struct in_addr*) { v }, sizeof(struct in_addr))
288 #define JSON_BUILD_IN6_ADDR(v) JSON_BUILD_BYTE_ARRAY((const struct in6_addr*) { v }, sizeof(struct in6_addr))
289 #define JSON_BUILD_IN_ADDR(v, f) JSON_BUILD_BYTE_ARRAY(((const union in_addr_union*) { v })->bytes, FAMILY_ADDRESS_SIZE_SAFE(f))
290 #define JSON_BUILD_ETHER_ADDR(v) JSON_BUILD_BYTE_ARRAY(((const struct ether_addr*) { v })->ether_addr_octet, sizeof(struct ether_addr))
291 #define JSON_BUILD_HW_ADDR(v) _JSON_BUILD_HW_ADDR, (const struct hw_addr_data*) { v }
292 
293 #define JSON_BUILD_PAIR_STRING(name, s) JSON_BUILD_PAIR(name, JSON_BUILD_STRING(s))
294 #define JSON_BUILD_PAIR_INTEGER(name, i) JSON_BUILD_PAIR(name, JSON_BUILD_INTEGER(i))
295 #define JSON_BUILD_PAIR_UNSIGNED(name, u) JSON_BUILD_PAIR(name, JSON_BUILD_UNSIGNED(u))
296 #define JSON_BUILD_PAIR_REAL(name, d) JSON_BUILD_PAIR(name, JSON_BUILD_REAL(d))
297 #define JSON_BUILD_PAIR_BOOLEAN(name, b) JSON_BUILD_PAIR(name, JSON_BUILD_BOOLEAN(b))
298 #define JSON_BUILD_PAIR_ARRAY(name, ...) JSON_BUILD_PAIR(name, JSON_BUILD_ARRAY(__VA_ARGS__))
299 #define JSON_BUILD_PAIR_EMPTY_ARRAY(name) JSON_BUILD_PAIR(name, JSON_BUILD_EMPTY_ARRAY)
300 #define JSON_BUILD_PAIR_OBJECT(name, ...) JSON_BUILD_PAIR(name, JSON_BUILD_OBJECT(__VA_ARGS__))
301 #define JSON_BUILD_PAIR_EMPTY_OBJECT(name) JSON_BUILD_PAIR(name, JSON_BUILD_EMPTY_OBJECT)
302 #define JSON_BUILD_PAIR_NULL(name) JSON_BUILD_PAIR(name, JSON_BUILD_NULL)
303 #define JSON_BUILD_PAIR_VARIANT(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_VARIANT(v))
304 #define JSON_BUILD_PAIR_VARIANT_ARRAY(name, v, n) JSON_BUILD_PAIR(name, JSON_BUILD_VARIANT_ARRAY(v, n))
305 #define JSON_BUILD_PAIR_LITERAL(name, l) JSON_BUILD_PAIR(name, JSON_BUILD_LITERAL(l))
306 #define JSON_BUILD_PAIR_STRV(name, l) JSON_BUILD_PAIR(name, JSON_BUILD_STRV(l))
307 #define JSON_BUILD_PAIR_BASE64(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_BASE64(p, n))
308 #define JSON_BUILD_PAIR_HEX(name, p, n) JSON_BUILD_PAIR(name, JSON_BUILD_HEX(p, n))
309 #define JSON_BUILD_PAIR_ID128(name, id) JSON_BUILD_PAIR(name, JSON_BUILD_ID128(id))
310 #define JSON_BUILD_PAIR_BYTE_ARRAY(name, v, n) JSON_BUILD_PAIR(name, JSON_BUILD_BYTE_ARRAY(v, n))
311 #define JSON_BUILD_PAIR_IN4_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_IN4_ADDR(v))
312 #define JSON_BUILD_PAIR_IN6_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_IN6_ADDR(v))
313 #define JSON_BUILD_PAIR_IN_ADDR(name, v, f) JSON_BUILD_PAIR(name, JSON_BUILD_IN_ADDR(v, f))
314 #define JSON_BUILD_PAIR_ETHER_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_ETHER_ADDR(v))
315 #define JSON_BUILD_PAIR_HW_ADDR(name, v) JSON_BUILD_PAIR(name, JSON_BUILD_HW_ADDR(v))
316 
317 #define JSON_BUILD_PAIR_UNSIGNED_NON_ZERO(name, u) _JSON_BUILD_PAIR_UNSIGNED_NON_ZERO, (const char*) { name }, (uint64_t) { u }
318 #define JSON_BUILD_PAIR_FINITE_USEC(name, u) _JSON_BUILD_PAIR_FINITE_USEC, (const char*) { name }, (usec_t) { u }
319 #define JSON_BUILD_PAIR_STRING_NON_EMPTY(name, s) _JSON_BUILD_PAIR_STRING_NON_EMPTY, (const char*) { name }, (const char*) { s }
320 #define JSON_BUILD_PAIR_STRV_NON_EMPTY(name, l) _JSON_BUILD_PAIR_STRV_NON_EMPTY, (const char*) { name }, (char**) { l }
321 #define JSON_BUILD_PAIR_VARIANT_NON_NULL(name, v) _JSON_BUILD_PAIR_VARIANT_NON_NULL, (const char*) { name }, (JsonVariant*) { v }
322 #define JSON_BUILD_PAIR_IN4_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_IN4_ADDR_NON_NULL, (const char*) { name }, (const struct in_addr*) { v }
323 #define JSON_BUILD_PAIR_IN6_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_IN6_ADDR_NON_NULL, (const char*) { name }, (const struct in6_addr*) { v }
324 #define JSON_BUILD_PAIR_IN_ADDR_NON_NULL(name, v, f) _JSON_BUILD_PAIR_IN_ADDR_NON_NULL, (const char*) { name }, (const union in_addr_union*) { v }, (int) { f }
325 #define JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_ETHER_ADDR_NON_NULL, (const char*) { name }, (const struct ether_addr*) { v }
326 #define JSON_BUILD_PAIR_HW_ADDR_NON_NULL(name, v) _JSON_BUILD_PAIR_HW_ADDR_NON_NULL, (const char*) { name }, (const struct hw_addr_data*) { v }
327 
328 int json_build(JsonVariant **ret, ...);
329 int json_buildv(JsonVariant **ret, va_list ap);
330 
331 /* A bitmask of flags used by the dispatch logic. Note that this is a combined bit mask, that is generated from the bit
332  * mask originally passed into json_dispatch(), the individual bitmask associated with the static JsonDispatch callout
333  * entry, as well the bitmask specified for json_log() calls */
334 typedef enum JsonDispatchFlags {
335         /* The following three may be set in JsonDispatch's .flags field or the json_dispatch() flags parameter  */
336         JSON_PERMISSIVE = 1 << 0, /* Shall parsing errors be considered fatal for this property? */
337         JSON_MANDATORY  = 1 << 1, /* Should existence of this property be mandatory? */
338         JSON_LOG        = 1 << 2, /* Should the parser log about errors? */
339         JSON_SAFE       = 1 << 3, /* Don't accept "unsafe" strings in json_dispatch_string() + json_dispatch_string() */
340         JSON_RELAX      = 1 << 4, /* Use relaxed user name checking in json_dispatch_user_group_name */
341 
342         /* The following two may be passed into log_json() in addition to those above */
343         JSON_DEBUG      = 1 << 5, /* Indicates that this log message is a debug message */
344         JSON_WARNING    = 1 << 6, /* Indicates that this log message is a warning message */
345 } JsonDispatchFlags;
346 
347 typedef int (*JsonDispatchCallback)(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
348 
349 typedef struct JsonDispatch {
350         const char *name;
351         JsonVariantType type;
352         JsonDispatchCallback callback;
353         size_t offset;
354         JsonDispatchFlags flags;
355 } JsonDispatch;
356 
357 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata);
358 
359 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
360 int json_dispatch_const_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
361 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
362 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
363 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
364 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
365 int json_dispatch_int64(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
366 int json_dispatch_uint64(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
367 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
368 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
369 int json_dispatch_uid_gid(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
370 int json_dispatch_user_group_name(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
371 int json_dispatch_id128(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
372 int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
373 
374 assert_cc(sizeof(uint32_t) == sizeof(unsigned));
375 #define json_dispatch_uint json_dispatch_uint32
376 
377 assert_cc(sizeof(int32_t) == sizeof(int));
378 #define json_dispatch_int json_dispatch_int32
379 
json_dispatch_level(JsonDispatchFlags flags)380 static inline int json_dispatch_level(JsonDispatchFlags flags) {
381 
382         /* Did the user request no logging? If so, then never log higher than LOG_DEBUG. Also, if this is marked as
383          * debug message, then also log at debug level. */
384 
385         if (!(flags & JSON_LOG) ||
386             (flags & JSON_DEBUG))
387                 return LOG_DEBUG;
388 
389         /* Are we invoked in permissive mode, or is this explicitly marked as warning message? Then this should be
390          * printed at LOG_WARNING */
391         if (flags & (JSON_PERMISSIVE|JSON_WARNING))
392                 return LOG_WARNING;
393 
394         /* Otherwise it's an error. */
395         return LOG_ERR;
396 }
397 
398 int json_log_internal(JsonVariant *variant, int level, int error, const char *file, int line, const char *func, const char *format, ...)  _printf_(7, 8);
399 
400 #define json_log(variant, flags, error, ...)                            \
401         ({                                                              \
402                 int _level = json_dispatch_level(flags), _e = (error);  \
403                 (log_get_max_level() >= LOG_PRI(_level))                \
404                         ? json_log_internal(variant, _level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
405                         : -ERRNO_VALUE(_e);                             \
406         })
407 
408 #define json_log_oom(variant, flags) \
409         json_log(variant, flags, SYNTHETIC_ERRNO(ENOMEM), "Out of memory.")
410 
411 #define JSON_VARIANT_STRING_CONST(x) _JSON_VARIANT_STRING_CONST(UNIQ, (x))
412 
413 #define _JSON_VARIANT_STRING_CONST(xq, x)                               \
414         ({                                                              \
415                 _align_(2) static const char UNIQ_T(json_string_const, xq)[] = (x); \
416                 assert((((uintptr_t) UNIQ_T(json_string_const, xq)) & 1) == 0); \
417                 (JsonVariant*) ((uintptr_t) UNIQ_T(json_string_const, xq) + 1); \
418         })
419 
420 int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size);
421 int json_variant_unhex(JsonVariant *v, void **ret, size_t *ret_size);
422 
423 const char *json_variant_type_to_string(JsonVariantType t);
424 JsonVariantType json_variant_type_from_string(const char *s);
425