]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/json.h
Merge pull request #15396 from keszybz/dbus-api-docs
[thirdparty/systemd.git] / src / shared / json.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
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 "macro.h"
11 #include "string-util.h"
12 #include "log.h"
13
14 /*
15 In case you wonder why we have our own JSON implementation, here are a couple of reasons why this implementation has
16 benefits over various other implementations:
17
18 - We need support for 64bit signed and unsigned integers, i.e. the full 64,5bit range of -9223372036854775808…18446744073709551615
19 - All our variants are immutable after creation
20 - Special values such as true, false, zero, null, empty strings, empty array, empty objects require zero dynamic memory
21 - Progressive parsing
22 - Our integer/real type implicitly converts, but only if that's safe and loss-lessly possible
23 - There's a "builder" for putting together objects easily in varargs function calls
24 - There's a "dispatcher" for mapping objects to C data structures
25 - Every variant optionally carries parsing location information, which simplifies debugging and parse log error generation
26 - Formatter has color, line, column support
27
28 Limitations:
29 - Doesn't allow embedded NUL in strings
30 - Can't store integers outside of the -9223372036854775808…18446744073709551615 range (it will use 'long double' for
31 values outside this range, which is lossy)
32 - Can't store negative zero (will be treated identical to positive zero, and not retained across serialization)
33 - Can't store non-integer numbers that can't be stored in "long double" losslessly
34 - Allows creation and parsing of objects with duplicate keys. The "dispatcher" will refuse them however. This means
35 we can parse and pass around such objects, but will carefully refuse them when we convert them into our own data.
36
37 (These limitations should be pretty much in line with those of other JSON implementations, in fact might be less
38 limiting in most cases even.)
39 */
40
41 typedef struct JsonVariant JsonVariant;
42
43 typedef enum JsonVariantType {
44 JSON_VARIANT_STRING,
45 JSON_VARIANT_INTEGER,
46 JSON_VARIANT_UNSIGNED,
47 JSON_VARIANT_REAL,
48 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 */
49 JSON_VARIANT_BOOLEAN,
50 JSON_VARIANT_ARRAY,
51 JSON_VARIANT_OBJECT,
52 JSON_VARIANT_NULL,
53 _JSON_VARIANT_TYPE_MAX,
54 _JSON_VARIANT_TYPE_INVALID = -1
55 } JsonVariantType;
56
57 int json_variant_new_stringn(JsonVariant **ret, const char *s, size_t n);
58 int json_variant_new_base64(JsonVariant **ret, const void *p, size_t n);
59 int json_variant_new_integer(JsonVariant **ret, intmax_t i);
60 int json_variant_new_unsigned(JsonVariant **ret, uintmax_t u);
61 int json_variant_new_real(JsonVariant **ret, long double d);
62 int json_variant_new_boolean(JsonVariant **ret, bool b);
63 int json_variant_new_array(JsonVariant **ret, JsonVariant **array, size_t n);
64 int json_variant_new_array_bytes(JsonVariant **ret, const void *p, size_t n);
65 int json_variant_new_array_strv(JsonVariant **ret, char **l);
66 int json_variant_new_object(JsonVariant **ret, JsonVariant **array, size_t n);
67 int json_variant_new_null(JsonVariant **ret);
68
69 static inline int json_variant_new_string(JsonVariant **ret, const char *s) {
70 return json_variant_new_stringn(ret, s, (size_t) -1);
71 }
72
73 JsonVariant *json_variant_ref(JsonVariant *v);
74 JsonVariant *json_variant_unref(JsonVariant *v);
75 void json_variant_unref_many(JsonVariant **array, size_t n);
76
77 DEFINE_TRIVIAL_CLEANUP_FUNC(JsonVariant *, json_variant_unref);
78
79 const char *json_variant_string(JsonVariant *v);
80 intmax_t json_variant_integer(JsonVariant *v);
81 uintmax_t json_variant_unsigned(JsonVariant *v);
82 long double json_variant_real(JsonVariant *v);
83 bool json_variant_boolean(JsonVariant *v);
84
85 JsonVariantType json_variant_type(JsonVariant *v);
86 bool json_variant_has_type(JsonVariant *v, JsonVariantType type);
87
88 static inline bool json_variant_is_string(JsonVariant *v) {
89 return json_variant_has_type(v, JSON_VARIANT_STRING);
90 }
91
92 static inline bool json_variant_is_integer(JsonVariant *v) {
93 return json_variant_has_type(v, JSON_VARIANT_INTEGER);
94 }
95
96 static inline bool json_variant_is_unsigned(JsonVariant *v) {
97 return json_variant_has_type(v, JSON_VARIANT_UNSIGNED);
98 }
99
100 static inline bool json_variant_is_real(JsonVariant *v) {
101 return json_variant_has_type(v, JSON_VARIANT_REAL);
102 }
103
104 static inline bool json_variant_is_number(JsonVariant *v) {
105 return json_variant_has_type(v, JSON_VARIANT_NUMBER);
106 }
107
108 static inline bool json_variant_is_boolean(JsonVariant *v) {
109 return json_variant_has_type(v, JSON_VARIANT_BOOLEAN);
110 }
111
112 static inline bool json_variant_is_array(JsonVariant *v) {
113 return json_variant_has_type(v, JSON_VARIANT_ARRAY);
114 }
115
116 static inline bool json_variant_is_object(JsonVariant *v) {
117 return json_variant_has_type(v, JSON_VARIANT_OBJECT);
118 }
119
120 static inline bool json_variant_is_null(JsonVariant *v) {
121 return json_variant_has_type(v, JSON_VARIANT_NULL);
122 }
123
124 bool json_variant_is_negative(JsonVariant *v);
125 bool json_variant_is_blank_object(JsonVariant *v);
126 bool json_variant_is_blank_array(JsonVariant *v);
127 bool json_variant_is_normalized(JsonVariant *v);
128 bool json_variant_is_sorted(JsonVariant *v);
129
130 size_t json_variant_elements(JsonVariant *v);
131 JsonVariant *json_variant_by_index(JsonVariant *v, size_t index);
132 JsonVariant *json_variant_by_key(JsonVariant *v, const char *key);
133 JsonVariant *json_variant_by_key_full(JsonVariant *v, const char *key, JsonVariant **ret_key);
134
135 bool json_variant_equal(JsonVariant *a, JsonVariant *b);
136
137 void json_variant_sensitive(JsonVariant *v);
138
139 struct json_variant_foreach_state {
140 JsonVariant *variant;
141 size_t idx;
142 };
143
144 #define JSON_VARIANT_ARRAY_FOREACH(i, v) \
145 for (struct json_variant_foreach_state _state = { (v), 0 }; \
146 json_variant_is_array(_state.variant) && \
147 _state.idx < json_variant_elements(_state.variant) && \
148 ({ i = json_variant_by_index(_state.variant, _state.idx); \
149 true; }); \
150 _state.idx++)
151
152 #define JSON_VARIANT_OBJECT_FOREACH(k, e, v) \
153 for (struct json_variant_foreach_state _state = { (v), 0 }; \
154 json_variant_is_object(_state.variant) && \
155 _state.idx < json_variant_elements(_state.variant) && \
156 ({ k = json_variant_string(json_variant_by_index(_state.variant, _state.idx)); \
157 e = json_variant_by_index(_state.variant, _state.idx + 1); \
158 true; }); \
159 _state.idx += 2)
160
161 int json_variant_get_source(JsonVariant *v, const char **ret_source, unsigned *ret_line, unsigned *ret_column);
162
163 typedef enum JsonFormatFlags {
164 JSON_FORMAT_NEWLINE = 1 << 0, /* suffix with newline */
165 JSON_FORMAT_PRETTY = 1 << 1, /* add internal whitespace to appeal to human readers */
166 JSON_FORMAT_PRETTY_AUTO = 1 << 2, /* same, but only if connected to a tty (and JSON_FORMAT_NEWLINE otherwise) */
167 JSON_FORMAT_COLOR = 1 << 3, /* insert ANSI color sequences */
168 JSON_FORMAT_COLOR_AUTO = 1 << 4, /* insert ANSI color sequences if colors_enabled() says so */
169 JSON_FORMAT_SOURCE = 1 << 5, /* prefix with source filename/line/column */
170 JSON_FORMAT_SSE = 1 << 6, /* prefix/suffix with W3C server-sent events */
171 JSON_FORMAT_SEQ = 1 << 7, /* prefix/suffix with RFC 7464 application/json-seq */
172 JSON_FORMAT_FLUSH = 1 << 8, /* call fflush() after dumping JSON */
173 } JsonFormatFlags;
174
175 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret);
176 void json_variant_dump(JsonVariant *v, JsonFormatFlags flags, FILE *f, const char *prefix);
177
178 int json_variant_filter(JsonVariant **v, char **to_remove);
179
180 int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *value);
181 int json_variant_set_field_string(JsonVariant **v, const char *field, const char *value);
182 int json_variant_set_field_integer(JsonVariant **v, const char *field, intmax_t value);
183 int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uintmax_t value);
184 int json_variant_set_field_boolean(JsonVariant **v, const char *field, bool b);
185
186 int json_variant_append_array(JsonVariant **v, JsonVariant *element);
187
188 int json_variant_merge(JsonVariant **v, JsonVariant *m);
189
190 int json_variant_strv(JsonVariant *v, char ***ret);
191
192 int json_variant_sort(JsonVariant **v);
193 int json_variant_normalize(JsonVariant **v);
194
195 typedef enum JsonParseFlags {
196 JSON_PARSE_SENSITIVE = 1 << 0, /* mark variant as "sensitive", i.e. something containing secret key material or such */
197 } JsonParseFlags;
198
199 int json_parse(const char *string, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);
200 int json_parse_continue(const char **p, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);
201 int json_parse_file_at(FILE *f, int dir_fd, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column);
202
203 static inline int json_parse_file(FILE *f, const char *path, JsonParseFlags flags, JsonVariant **ret, unsigned *ret_line, unsigned *ret_column) {
204 return json_parse_file_at(f, AT_FDCWD, path, flags, ret, ret_line, ret_column);
205 }
206
207 enum {
208 _JSON_BUILD_STRING,
209 _JSON_BUILD_INTEGER,
210 _JSON_BUILD_UNSIGNED,
211 _JSON_BUILD_REAL,
212 _JSON_BUILD_BOOLEAN,
213 _JSON_BUILD_ARRAY_BEGIN,
214 _JSON_BUILD_ARRAY_END,
215 _JSON_BUILD_OBJECT_BEGIN,
216 _JSON_BUILD_OBJECT_END,
217 _JSON_BUILD_PAIR,
218 _JSON_BUILD_PAIR_CONDITION,
219 _JSON_BUILD_NULL,
220 _JSON_BUILD_VARIANT,
221 _JSON_BUILD_VARIANT_ARRAY,
222 _JSON_BUILD_LITERAL,
223 _JSON_BUILD_STRV,
224 _JSON_BUILD_BASE64,
225 _JSON_BUILD_MAX,
226 };
227
228 #define JSON_BUILD_STRING(s) _JSON_BUILD_STRING, ({ const char *_x = s; _x; })
229 #define JSON_BUILD_INTEGER(i) _JSON_BUILD_INTEGER, ({ intmax_t _x = i; _x; })
230 #define JSON_BUILD_UNSIGNED(u) _JSON_BUILD_UNSIGNED, ({ uintmax_t _x = u; _x; })
231 #define JSON_BUILD_REAL(d) _JSON_BUILD_REAL, ({ long double _x = d; _x; })
232 #define JSON_BUILD_BOOLEAN(b) _JSON_BUILD_BOOLEAN, ({ bool _x = b; _x; })
233 #define JSON_BUILD_ARRAY(...) _JSON_BUILD_ARRAY_BEGIN, __VA_ARGS__, _JSON_BUILD_ARRAY_END
234 #define JSON_BUILD_EMPTY_ARRAY _JSON_BUILD_ARRAY_BEGIN, _JSON_BUILD_ARRAY_END
235 #define JSON_BUILD_OBJECT(...) _JSON_BUILD_OBJECT_BEGIN, __VA_ARGS__, _JSON_BUILD_OBJECT_END
236 #define JSON_BUILD_EMPTY_OBJECT _JSON_BUILD_OBJECT_BEGIN, _JSON_BUILD_OBJECT_END
237 #define JSON_BUILD_PAIR(n, ...) _JSON_BUILD_PAIR, ({ const char *_x = n; _x; }), __VA_ARGS__
238 #define JSON_BUILD_PAIR_CONDITION(c, n, ...) _JSON_BUILD_PAIR_CONDITION, ({ bool _x = c; _x; }), ({ const char *_x = n; _x; }), __VA_ARGS__
239 #define JSON_BUILD_NULL _JSON_BUILD_NULL
240 #define JSON_BUILD_VARIANT(v) _JSON_BUILD_VARIANT, ({ JsonVariant *_x = v; _x; })
241 #define JSON_BUILD_VARIANT_ARRAY(v, n) _JSON_BUILD_VARIANT_ARRAY, ({ JsonVariant **_x = v; _x; }), ({ size_t _y = n; _y; })
242 #define JSON_BUILD_LITERAL(l) _JSON_BUILD_LITERAL, ({ const char *_x = l; _x; })
243 #define JSON_BUILD_STRV(l) _JSON_BUILD_STRV, ({ char **_x = l; _x; })
244 #define JSON_BUILD_BASE64(p, n) _JSON_BUILD_BASE64, ({ const void *_x = p; _x; }), ({ size_t _y = n; _y; })
245
246 int json_build(JsonVariant **ret, ...);
247 int json_buildv(JsonVariant **ret, va_list ap);
248
249 /* A bitmask of flags used by the dispatch logic. Note that this is a combined bit mask, that is generated from the bit
250 * mask originally passed into json_dispatch(), the individual bitmask associated with the static JsonDispatch callout
251 * entry, as well the bitmask specified for json_log() calls */
252 typedef enum JsonDispatchFlags {
253 /* The following three may be set in JsonDispatch's .flags field or the json_dispatch() flags parameter */
254 JSON_PERMISSIVE = 1 << 0, /* Shall parsing errors be considered fatal for this property? */
255 JSON_MANDATORY = 1 << 1, /* Should existence of this property be mandatory? */
256 JSON_LOG = 1 << 2, /* Should the parser log about errors? */
257 JSON_SAFE = 1 << 3, /* Don't accept "unsafe" strings in json_dispatch_string() + json_dispatch_string() */
258 JSON_RELAX = 1 << 4, /* Use relaxed user name checking in json_dispatch_user_group_name */
259
260 /* The following two may be passed into log_json() in addition to the three above */
261 JSON_DEBUG = 1 << 4, /* Indicates that this log message is a debug message */
262 JSON_WARNING = 1 << 5, /* Indicates that this log message is a warning message */
263 } JsonDispatchFlags;
264
265 typedef int (*JsonDispatchCallback)(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
266
267 typedef struct JsonDispatch {
268 const char *name;
269 JsonVariantType type;
270 JsonDispatchCallback callback;
271 size_t offset;
272 JsonDispatchFlags flags;
273 } JsonDispatch;
274
275 int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata);
276
277 int json_dispatch_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
278 int json_dispatch_const_string(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
279 int json_dispatch_strv(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
280 int json_dispatch_boolean(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
281 int json_dispatch_tristate(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
282 int json_dispatch_variant(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
283 int json_dispatch_integer(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
284 int json_dispatch_unsigned(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
285 int json_dispatch_uint32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
286 int json_dispatch_int32(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
287 int json_dispatch_uid_gid(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
288 int json_dispatch_user_group_name(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
289 int json_dispatch_id128(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
290 int json_dispatch_unsupported(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
291
292 assert_cc(sizeof(uintmax_t) == sizeof(uint64_t));
293 #define json_dispatch_uint64 json_dispatch_unsigned
294
295 assert_cc(sizeof(intmax_t) == sizeof(int64_t));
296 #define json_dispatch_int64 json_dispatch_integer
297
298 static inline int json_dispatch_level(JsonDispatchFlags flags) {
299
300 /* Did the user request no logging? If so, then never log higher than LOG_DEBUG. Also, if this is marked as
301 * debug message, then also log at debug level. */
302
303 if (!(flags & JSON_LOG) ||
304 (flags & JSON_DEBUG))
305 return LOG_DEBUG;
306
307 /* Are we invoked in permissive mode, or is this explicitly marked as warning message? Then this should be
308 * printed at LOG_WARNING */
309 if (flags & (JSON_PERMISSIVE|JSON_WARNING))
310 return LOG_WARNING;
311
312 /* Otherwise it's an error. */
313 return LOG_ERR;
314 }
315
316 int json_log_internal(JsonVariant *variant, int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(7, 8);
317
318 #define json_log(variant, flags, error, ...) \
319 ({ \
320 int _level = json_dispatch_level(flags), _e = (error); \
321 (log_get_max_level() >= LOG_PRI(_level)) \
322 ? json_log_internal(variant, _level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
323 : -ERRNO_VALUE(_e); \
324 })
325
326 #define json_log_oom(variant, flags) \
327 json_log(variant, flags, SYNTHETIC_ERRNO(ENOMEM), "Out of memory.")
328
329 #define JSON_VARIANT_STRING_CONST(x) _JSON_VARIANT_STRING_CONST(UNIQ, (x))
330
331 #define _JSON_VARIANT_STRING_CONST(xq, x) \
332 ({ \
333 _align_(2) static const char UNIQ_T(json_string_const, xq)[] = (x); \
334 assert((((uintptr_t) UNIQ_T(json_string_const, xq)) & 1) == 0); \
335 (JsonVariant*) ((uintptr_t) UNIQ_T(json_string_const, xq) + 1); \
336 })
337
338 int json_variant_unbase64(JsonVariant *v, void **ret, size_t *ret_size);
339
340 const char *json_variant_type_to_string(JsonVariantType t);
341 JsonVariantType json_variant_type_from_string(const char *s);