]>
Commit | Line | Data |
---|---|---|
788c34be LP |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
3 | #include <math.h> | |
788c34be LP |
4 | |
5 | #include "alloc-util.h" | |
6 | #include "fd-util.h" | |
673a1e6f | 7 | #include "fileio.h" |
788c34be LP |
8 | #include "json-internal.h" |
9 | #include "json.h" | |
10 | #include "string-util.h" | |
11 | #include "strv.h" | |
adbdcfbe | 12 | #include "tests.h" |
788c34be LP |
13 | #include "util.h" |
14 | ||
15 | static void test_tokenizer(const char *data, ...) { | |
16 | unsigned line = 0, column = 0; | |
17 | void *state = NULL; | |
18 | va_list ap; | |
19 | ||
20 | va_start(ap, data); | |
21 | ||
22 | for (;;) { | |
23 | unsigned token_line, token_column; | |
24 | _cleanup_free_ char *str = NULL; | |
25 | JsonValue v = JSON_VALUE_NULL; | |
26 | int t, tt; | |
27 | ||
28 | t = json_tokenize(&data, &str, &v, &token_line, &token_column, &state, &line, &column); | |
29 | tt = va_arg(ap, int); | |
30 | ||
31 | assert_se(t == tt); | |
32 | ||
33 | if (t == JSON_TOKEN_END || t < 0) | |
34 | break; | |
35 | ||
36 | else if (t == JSON_TOKEN_STRING) { | |
37 | const char *nn; | |
38 | ||
39 | nn = va_arg(ap, const char *); | |
40 | assert_se(streq_ptr(nn, str)); | |
41 | ||
42 | } else if (t == JSON_TOKEN_REAL) { | |
43 | long double d; | |
44 | ||
45 | d = va_arg(ap, long double); | |
46 | ||
aa70783f ZJS |
47 | /* Valgrind doesn't support long double calculations and automatically downgrades to 80bit: |
48 | * http://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits. | |
49 | * Some architectures might not support long double either. | |
50 | */ | |
51 | ||
52 | assert_se(fabsl(d - v.real) < 1e-10 || | |
53 | fabsl((d - v.real) / v.real) < 1e-10); | |
788c34be LP |
54 | |
55 | } else if (t == JSON_TOKEN_INTEGER) { | |
56 | intmax_t i; | |
57 | ||
58 | i = va_arg(ap, intmax_t); | |
59 | assert_se(i == v.integer); | |
60 | ||
61 | } else if (t == JSON_TOKEN_UNSIGNED) { | |
62 | uintmax_t u; | |
63 | ||
64 | u = va_arg(ap, uintmax_t); | |
65 | assert_se(u == v.unsig); | |
66 | ||
67 | } else if (t == JSON_TOKEN_BOOLEAN) { | |
68 | bool b; | |
69 | ||
70 | b = va_arg(ap, int); | |
71 | assert_se(b == v.boolean); | |
72 | } | |
73 | } | |
74 | ||
75 | va_end(ap); | |
76 | } | |
77 | ||
78 | typedef void (*Test)(JsonVariant *); | |
79 | ||
80 | static void test_variant(const char *data, Test test) { | |
81 | _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; | |
82 | _cleanup_free_ char *s = NULL; | |
83 | int r; | |
84 | ||
85 | r = json_parse(data, &v, NULL, NULL); | |
86 | assert_se(r == 0); | |
87 | assert_se(v); | |
88 | ||
89 | r = json_variant_format(v, 0, &s); | |
90 | assert_se(r >= 0); | |
91 | assert_se(s); | |
2a04712c | 92 | assert_se((size_t) r == strlen(s)); |
788c34be LP |
93 | |
94 | log_info("formatted normally: %s\n", s); | |
95 | ||
96 | r = json_parse(data, &w, NULL, NULL); | |
97 | assert_se(r == 0); | |
98 | assert_se(w); | |
99 | assert_se(json_variant_has_type(v, json_variant_type(w))); | |
100 | assert_se(json_variant_has_type(w, json_variant_type(v))); | |
101 | assert_se(json_variant_equal(v, w)); | |
102 | ||
103 | s = mfree(s); | |
104 | w = json_variant_unref(w); | |
105 | ||
106 | r = json_variant_format(v, JSON_FORMAT_PRETTY, &s); | |
107 | assert_se(r >= 0); | |
108 | assert_se(s); | |
2a04712c | 109 | assert_se((size_t) r == strlen(s)); |
788c34be LP |
110 | |
111 | log_info("formatted prettily:\n%s", s); | |
112 | ||
113 | r = json_parse(data, &w, NULL, NULL); | |
114 | assert_se(r == 0); | |
115 | assert_se(w); | |
116 | ||
117 | assert_se(json_variant_has_type(v, json_variant_type(w))); | |
118 | assert_se(json_variant_has_type(w, json_variant_type(v))); | |
119 | assert_se(json_variant_equal(v, w)); | |
120 | ||
121 | s = mfree(s); | |
122 | r = json_variant_format(v, JSON_FORMAT_COLOR, &s); | |
123 | assert_se(r >= 0); | |
124 | assert_se(s); | |
2a04712c | 125 | assert_se((size_t) r == strlen(s)); |
788c34be LP |
126 | printf("Normal with color: %s\n", s); |
127 | ||
128 | s = mfree(s); | |
129 | r = json_variant_format(v, JSON_FORMAT_COLOR|JSON_FORMAT_PRETTY, &s); | |
130 | assert_se(r >= 0); | |
131 | assert_se(s); | |
2a04712c | 132 | assert_se((size_t) r == strlen(s)); |
788c34be LP |
133 | printf("Pretty with color:\n%s\n", s); |
134 | ||
135 | if (test) | |
136 | test(v); | |
137 | } | |
138 | ||
139 | static void test_1(JsonVariant *v) { | |
140 | JsonVariant *p, *q; | |
141 | unsigned i; | |
142 | ||
143 | /* 3 keys + 3 values */ | |
144 | assert_se(json_variant_elements(v) == 6); | |
145 | ||
146 | /* has k */ | |
147 | p = json_variant_by_key(v, "k"); | |
148 | assert_se(p && json_variant_type(p) == JSON_VARIANT_STRING); | |
149 | ||
150 | /* k equals v */ | |
151 | assert_se(streq(json_variant_string(p), "v")); | |
152 | ||
153 | /* has foo */ | |
154 | p = json_variant_by_key(v, "foo"); | |
155 | assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 3); | |
156 | ||
157 | /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */ | |
158 | for (i = 0; i < 3; ++i) { | |
159 | q = json_variant_by_index(p, i); | |
160 | assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == (i+1)); | |
161 | assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == (i+1)); | |
162 | } | |
163 | ||
164 | /* has bar */ | |
165 | p = json_variant_by_key(v, "bar"); | |
166 | assert_se(p && json_variant_type(p) == JSON_VARIANT_OBJECT && json_variant_elements(p) == 2); | |
167 | ||
168 | /* zap is null */ | |
169 | q = json_variant_by_key(p, "zap"); | |
170 | assert_se(q && json_variant_type(q) == JSON_VARIANT_NULL); | |
171 | } | |
172 | ||
173 | static void test_2(JsonVariant *v) { | |
174 | JsonVariant *p, *q; | |
175 | ||
176 | /* 2 keys + 2 values */ | |
177 | assert_se(json_variant_elements(v) == 4); | |
178 | ||
179 | /* has mutant */ | |
180 | p = json_variant_by_key(v, "mutant"); | |
181 | assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 4); | |
182 | ||
183 | /* mutant[0] == 1 */ | |
184 | q = json_variant_by_index(p, 0); | |
185 | assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == 1); | |
186 | assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == 1); | |
187 | ||
188 | /* mutant[1] == null */ | |
189 | q = json_variant_by_index(p, 1); | |
190 | assert_se(q && json_variant_type(q) == JSON_VARIANT_NULL); | |
191 | ||
192 | /* mutant[2] == "1" */ | |
193 | q = json_variant_by_index(p, 2); | |
194 | assert_se(q && json_variant_type(q) == JSON_VARIANT_STRING && streq(json_variant_string(q), "1")); | |
195 | ||
196 | /* mutant[3] == JSON_VARIANT_OBJECT */ | |
197 | q = json_variant_by_index(p, 3); | |
198 | assert_se(q && json_variant_type(q) == JSON_VARIANT_OBJECT && json_variant_elements(q) == 2); | |
199 | ||
200 | /* has 1 */ | |
201 | p = json_variant_by_key(q, "1"); | |
202 | assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 2); | |
203 | ||
204 | /* "1"[0] == 1 */ | |
205 | q = json_variant_by_index(p, 0); | |
206 | assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == 1); | |
207 | assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == 1); | |
208 | ||
209 | /* "1"[1] == "1" */ | |
210 | q = json_variant_by_index(p, 1); | |
211 | assert_se(q && json_variant_type(q) == JSON_VARIANT_STRING && streq(json_variant_string(q), "1")); | |
212 | ||
213 | /* has thisisaverylongproperty */ | |
214 | p = json_variant_by_key(v, "thisisaverylongproperty"); | |
40990eac | 215 | assert_se(p && json_variant_type(p) == JSON_VARIANT_REAL && fabsl(json_variant_real(p) - 1.27) < 0.001); |
788c34be LP |
216 | } |
217 | ||
788c34be LP |
218 | static void test_zeroes(JsonVariant *v) { |
219 | size_t i; | |
220 | ||
221 | /* Make sure zero is how we expect it. */ | |
222 | ||
223 | assert_se(json_variant_elements(v) == 13); | |
224 | ||
225 | for (i = 0; i < json_variant_elements(v); i++) { | |
226 | JsonVariant *w; | |
227 | size_t j; | |
228 | ||
229 | assert_se(w = json_variant_by_index(v, i)); | |
230 | ||
231 | assert_se(json_variant_integer(w) == 0); | |
232 | assert_se(json_variant_unsigned(w) == 0U); | |
233 | ||
234 | #pragma GCC diagnostic push | |
235 | #pragma GCC diagnostic ignored "-Wfloat-equal" | |
236 | assert_se(json_variant_real(w) == 0.0L); | |
237 | #pragma GCC diagnostic pop | |
238 | ||
239 | assert_se(json_variant_is_integer(w)); | |
240 | assert_se(json_variant_is_unsigned(w)); | |
241 | assert_se(json_variant_is_real(w)); | |
242 | assert_se(json_variant_is_number(w)); | |
243 | ||
244 | assert_se(!json_variant_is_negative(w)); | |
245 | ||
246 | assert_se(IN_SET(json_variant_type(w), JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL)); | |
247 | ||
248 | for (j = 0; j < json_variant_elements(v); j++) { | |
249 | JsonVariant *q; | |
250 | ||
251 | assert_se(q = json_variant_by_index(v, j)); | |
252 | ||
253 | assert_se(json_variant_equal(w, q)); | |
254 | } | |
255 | } | |
256 | } | |
257 | ||
258 | static void test_build(void) { | |
259 | _cleanup_(json_variant_unrefp) JsonVariant *a = NULL, *b = NULL; | |
260 | _cleanup_free_ char *s = NULL, *t = NULL; | |
261 | ||
262 | assert_se(json_build(&a, JSON_BUILD_STRING("hallo")) >= 0); | |
263 | assert_se(json_build(&b, JSON_BUILD_LITERAL(" \"hallo\" ")) >= 0); | |
264 | assert_se(json_variant_equal(a, b)); | |
265 | ||
266 | b = json_variant_unref(b); | |
267 | ||
268 | assert_se(json_build(&b, JSON_BUILD_VARIANT(a)) >= 0); | |
269 | assert_se(json_variant_equal(a, b)); | |
270 | ||
271 | b = json_variant_unref(b); | |
272 | assert_se(json_build(&b, JSON_BUILD_STRING("pief")) >= 0); | |
273 | assert_se(!json_variant_equal(a, b)); | |
274 | ||
275 | a = json_variant_unref(a); | |
276 | b = json_variant_unref(b); | |
277 | ||
278 | assert_se(json_build(&a, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("one", JSON_BUILD_INTEGER(7)), | |
279 | JSON_BUILD_PAIR("two", JSON_BUILD_REAL(2.0)), | |
280 | JSON_BUILD_PAIR("three", JSON_BUILD_INTEGER(0)))) >= 0); | |
281 | ||
282 | assert_se(json_build(&b, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("two", JSON_BUILD_INTEGER(2)), | |
283 | JSON_BUILD_PAIR("three", JSON_BUILD_REAL(0)), | |
284 | JSON_BUILD_PAIR("one", JSON_BUILD_REAL(7)))) >= 0); | |
285 | ||
286 | assert_se(json_variant_equal(a, b)); | |
287 | ||
288 | a = json_variant_unref(a); | |
289 | b = json_variant_unref(b); | |
290 | ||
14648b76 | 291 | const char* arr_1234[] = {"one", "two", "three", "four", NULL}; |
788c34be LP |
292 | assert_se(json_build(&a, JSON_BUILD_ARRAY(JSON_BUILD_OBJECT(JSON_BUILD_PAIR("x", JSON_BUILD_BOOLEAN(true)), |
293 | JSON_BUILD_PAIR("y", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("this", JSON_BUILD_NULL)))), | |
294 | JSON_BUILD_VARIANT(NULL), | |
295 | JSON_BUILD_LITERAL(NULL), | |
296 | JSON_BUILD_STRING(NULL), | |
297 | JSON_BUILD_NULL, | |
298 | JSON_BUILD_INTEGER(77), | |
14648b76 ZJS |
299 | JSON_BUILD_ARRAY(JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("foobar")), |
300 | JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("zzz"))), | |
301 | JSON_BUILD_STRV((char**) arr_1234))) >= 0); | |
788c34be LP |
302 | |
303 | assert_se(json_variant_format(a, 0, &s) >= 0); | |
304 | log_info("GOT: %s\n", s); | |
305 | assert_se(json_parse(s, &b, NULL, NULL) >= 0); | |
306 | assert_se(json_variant_equal(a, b)); | |
307 | ||
308 | a = json_variant_unref(a); | |
309 | b = json_variant_unref(b); | |
310 | ||
311 | assert_se(json_build(&a, JSON_BUILD_REAL(M_PIl)) >= 0); | |
312 | ||
313 | s = mfree(s); | |
314 | assert_se(json_variant_format(a, 0, &s) >= 0); | |
315 | log_info("GOT: %s\n", s); | |
316 | assert_se(json_parse(s, &b, NULL, NULL) >= 0); | |
317 | assert_se(json_variant_format(b, 0, &t) >= 0); | |
318 | log_info("GOT: %s\n", t); | |
319 | ||
320 | assert_se(streq(s, t)); | |
321 | ||
322 | a = json_variant_unref(a); | |
323 | b = json_variant_unref(b); | |
319a4f27 LP |
324 | |
325 | assert_se(json_build(&a, JSON_BUILD_OBJECT( | |
326 | JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")), | |
327 | JSON_BUILD_PAIR("z", JSON_BUILD_STRING("a")), | |
328 | JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c")) | |
329 | )) >= 0); | |
330 | ||
331 | assert_se(json_build(&b, JSON_BUILD_OBJECT( | |
332 | JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")), | |
333 | JSON_BUILD_PAIR_CONDITION(false, "p", JSON_BUILD_STRING("q")), | |
334 | JSON_BUILD_PAIR_CONDITION(true, "z", JSON_BUILD_STRING("a")), | |
335 | JSON_BUILD_PAIR_CONDITION(false, "j", JSON_BUILD_ARRAY(JSON_BUILD_STRING("k"), JSON_BUILD_STRING("u"), JSON_BUILD_STRING("i"))), | |
336 | JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c")) | |
337 | )) >= 0); | |
338 | ||
339 | assert_se(json_variant_equal(a, b)); | |
788c34be LP |
340 | } |
341 | ||
342 | static void test_source(void) { | |
343 | static const char data[] = | |
344 | "\n" | |
345 | "\n" | |
346 | "{\n" | |
347 | "\"foo\" : \"bar\", \n" | |
348 | "\"qüüx\" : [ 1, 2, 3,\n" | |
349 | "4,\n" | |
350 | "5 ],\n" | |
351 | "\"miep\" : { \"hallo\" : 1 },\n" | |
352 | "\n" | |
353 | "\"zzzzzz\" \n" | |
354 | ":\n" | |
355 | "[ true, \n" | |
356 | "false, 7.5, {} ]\n" | |
357 | "}\n"; | |
358 | ||
359 | _cleanup_fclose_ FILE *f = NULL; | |
360 | _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; | |
361 | ||
362 | printf("--- original begin ---\n" | |
363 | "%s" | |
364 | "--- original end ---\n", data); | |
365 | ||
673a1e6f | 366 | assert_se(f = fmemopen_unlocked((void*) data, strlen(data), "r")); |
788c34be LP |
367 | |
368 | assert_se(json_parse_file(f, "waldo", &v, NULL, NULL) >= 0); | |
369 | ||
370 | printf("--- non-pretty begin ---\n"); | |
371 | json_variant_dump(v, 0, stdout, NULL); | |
372 | printf("\n--- non-pretty end ---\n"); | |
373 | ||
374 | printf("--- pretty begin ---\n"); | |
375 | json_variant_dump(v, JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR|JSON_FORMAT_SOURCE, stdout, NULL); | |
376 | printf("--- pretty end ---\n"); | |
377 | } | |
378 | ||
b2fa0d4f | 379 | static void test_depth(void) { |
d520d519 | 380 | _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; |
b2fa0d4f LP |
381 | unsigned i; |
382 | int r; | |
383 | ||
d520d519 | 384 | v = JSON_VARIANT_STRING_CONST("start"); |
b2fa0d4f LP |
385 | |
386 | /* Let's verify that the maximum depth checks work */ | |
387 | ||
388 | for (i = 0;; i++) { | |
389 | _cleanup_(json_variant_unrefp) JsonVariant *w = NULL; | |
390 | ||
391 | assert_se(i <= UINT16_MAX); | |
392 | if (i & 1) | |
393 | r = json_variant_new_array(&w, &v, 1); | |
394 | else | |
d520d519 | 395 | r = json_variant_new_object(&w, (JsonVariant*[]) { JSON_VARIANT_STRING_CONST("key"), v }, 2); |
b2fa0d4f LP |
396 | if (r == -ELNRNG) { |
397 | log_info("max depth at %u", i); | |
398 | break; | |
399 | } | |
b6cda3ec ZJS |
400 | #if HAS_FEATURE_MEMORY_SANITIZER |
401 | /* msan doesn't like the stack nesting to be too deep. Let's quit early. */ | |
402 | if (i >= 128) { | |
403 | log_info("quitting early at depth %u", i); | |
404 | break; | |
405 | } | |
406 | #endif | |
b2fa0d4f LP |
407 | |
408 | assert_se(r >= 0); | |
409 | ||
410 | json_variant_unref(v); | |
411 | v = TAKE_PTR(w); | |
412 | } | |
413 | ||
414 | json_variant_dump(v, 0, stdout, NULL); | |
d520d519 | 415 | fputs("\n", stdout); |
b2fa0d4f LP |
416 | } |
417 | ||
788c34be | 418 | int main(int argc, char *argv[]) { |
adbdcfbe | 419 | test_setup_logging(LOG_DEBUG); |
788c34be LP |
420 | |
421 | test_tokenizer("x", -EINVAL); | |
422 | test_tokenizer("", JSON_TOKEN_END); | |
423 | test_tokenizer(" ", JSON_TOKEN_END); | |
424 | test_tokenizer("0", JSON_TOKEN_UNSIGNED, (uintmax_t) 0, JSON_TOKEN_END); | |
425 | test_tokenizer("-0", JSON_TOKEN_INTEGER, (intmax_t) 0, JSON_TOKEN_END); | |
426 | test_tokenizer("1234", JSON_TOKEN_UNSIGNED, (uintmax_t) 1234, JSON_TOKEN_END); | |
427 | test_tokenizer("-1234", JSON_TOKEN_INTEGER, (intmax_t) -1234, JSON_TOKEN_END); | |
428 | test_tokenizer("18446744073709551615", JSON_TOKEN_UNSIGNED, (uintmax_t) UINT64_MAX, JSON_TOKEN_END); | |
429 | test_tokenizer("-9223372036854775808", JSON_TOKEN_INTEGER, (intmax_t) INT64_MIN, JSON_TOKEN_END); | |
430 | test_tokenizer("18446744073709551616", JSON_TOKEN_REAL, (long double) 18446744073709551616.0L, JSON_TOKEN_END); | |
431 | test_tokenizer("-9223372036854775809", JSON_TOKEN_REAL, (long double) -9223372036854775809.0L, JSON_TOKEN_END); | |
432 | test_tokenizer("-1234", JSON_TOKEN_INTEGER, (intmax_t) -1234, JSON_TOKEN_END); | |
433 | test_tokenizer("3.141", JSON_TOKEN_REAL, (long double) 3.141, JSON_TOKEN_END); | |
434 | test_tokenizer("0.0", JSON_TOKEN_REAL, (long double) 0.0, JSON_TOKEN_END); | |
435 | test_tokenizer("7e3", JSON_TOKEN_REAL, (long double) 7e3, JSON_TOKEN_END); | |
436 | test_tokenizer("-7e-3", JSON_TOKEN_REAL, (long double) -7e-3, JSON_TOKEN_END); | |
437 | test_tokenizer("true", JSON_TOKEN_BOOLEAN, true, JSON_TOKEN_END); | |
438 | test_tokenizer("false", JSON_TOKEN_BOOLEAN, false, JSON_TOKEN_END); | |
439 | test_tokenizer("null", JSON_TOKEN_NULL, JSON_TOKEN_END); | |
440 | test_tokenizer("{}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END); | |
441 | test_tokenizer("\t {\n} \n", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END); | |
442 | test_tokenizer("[]", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END); | |
443 | test_tokenizer("\t [] \n\n", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END); | |
444 | test_tokenizer("\"\"", JSON_TOKEN_STRING, "", JSON_TOKEN_END); | |
445 | test_tokenizer("\"foo\"", JSON_TOKEN_STRING, "foo", JSON_TOKEN_END); | |
446 | test_tokenizer("\"foo\\nfoo\"", JSON_TOKEN_STRING, "foo\nfoo", JSON_TOKEN_END); | |
447 | test_tokenizer("{\"foo\" : \"bar\"}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_STRING, "foo", JSON_TOKEN_COLON, JSON_TOKEN_STRING, "bar", JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END); | |
448 | test_tokenizer("{\"foo\" : [true, false]}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_STRING, "foo", JSON_TOKEN_COLON, JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_BOOLEAN, true, JSON_TOKEN_COMMA, JSON_TOKEN_BOOLEAN, false, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END); | |
449 | test_tokenizer("\"\xef\xbf\xbd\"", JSON_TOKEN_STRING, "\xef\xbf\xbd", JSON_TOKEN_END); | |
450 | test_tokenizer("\"\\ufffd\"", JSON_TOKEN_STRING, "\xef\xbf\xbd", JSON_TOKEN_END); | |
451 | test_tokenizer("\"\\uf\"", -EINVAL); | |
452 | test_tokenizer("\"\\ud800a\"", -EINVAL); | |
453 | test_tokenizer("\"\\udc00\\udc00\"", -EINVAL); | |
454 | test_tokenizer("\"\\ud801\\udc37\"", JSON_TOKEN_STRING, "\xf0\x90\x90\xb7", JSON_TOKEN_END); | |
455 | ||
456 | test_tokenizer("[1, 2, -3]", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_UNSIGNED, (uintmax_t) 1, JSON_TOKEN_COMMA, JSON_TOKEN_UNSIGNED, (uintmax_t) 2, JSON_TOKEN_COMMA, JSON_TOKEN_INTEGER, (intmax_t) -3, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END); | |
457 | ||
458 | test_variant("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1); | |
459 | test_variant("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"thisisaverylongproperty\": 1.27}", test_2); | |
460 | test_variant("{\"foo\" : \"\\uDBFF\\uDFFF\\\"\\uD9FF\\uDFFFFFF\\\"\\uDBFF\\uDFFF\\\"\\uD9FF\\uDFFF\\uDBFF\\uDFFFF\\uDBFF\\uDFFF\\uDBFF\\uDFFF\\uDBFF\\uDFFF\\uDBFF\\uDFFF\\\"\\uD9FF\\uDFFFFF\\\"\\uDBFF\\uDFFF\\\"\\uD9FF\\uDFFF\\uDBFF\\uDFFF\"}", NULL); | |
461 | ||
462 | test_variant("[ 0, -0, 0.0, -0.0, 0.000, -0.000, 0e0, -0e0, 0e+0, -0e-0, 0e-0, -0e000, 0e+000 ]", test_zeroes); | |
463 | ||
464 | test_build(); | |
465 | ||
466 | test_source(); | |
467 | ||
b2fa0d4f LP |
468 | test_depth(); |
469 | ||
788c34be LP |
470 | return 0; |
471 | } |