]>
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); | |
92 | ||
93 | log_info("formatted normally: %s\n", s); | |
94 | ||
95 | r = json_parse(data, &w, NULL, NULL); | |
96 | assert_se(r == 0); | |
97 | assert_se(w); | |
98 | assert_se(json_variant_has_type(v, json_variant_type(w))); | |
99 | assert_se(json_variant_has_type(w, json_variant_type(v))); | |
100 | assert_se(json_variant_equal(v, w)); | |
101 | ||
102 | s = mfree(s); | |
103 | w = json_variant_unref(w); | |
104 | ||
105 | r = json_variant_format(v, JSON_FORMAT_PRETTY, &s); | |
106 | assert_se(r >= 0); | |
107 | assert_se(s); | |
108 | ||
109 | log_info("formatted prettily:\n%s", s); | |
110 | ||
111 | r = json_parse(data, &w, NULL, NULL); | |
112 | assert_se(r == 0); | |
113 | assert_se(w); | |
114 | ||
115 | assert_se(json_variant_has_type(v, json_variant_type(w))); | |
116 | assert_se(json_variant_has_type(w, json_variant_type(v))); | |
117 | assert_se(json_variant_equal(v, w)); | |
118 | ||
119 | s = mfree(s); | |
120 | r = json_variant_format(v, JSON_FORMAT_COLOR, &s); | |
121 | assert_se(r >= 0); | |
122 | assert_se(s); | |
123 | printf("Normal with color: %s\n", s); | |
124 | ||
125 | s = mfree(s); | |
126 | r = json_variant_format(v, JSON_FORMAT_COLOR|JSON_FORMAT_PRETTY, &s); | |
127 | assert_se(r >= 0); | |
128 | assert_se(s); | |
129 | printf("Pretty with color:\n%s\n", s); | |
130 | ||
131 | if (test) | |
132 | test(v); | |
133 | } | |
134 | ||
135 | static void test_1(JsonVariant *v) { | |
136 | JsonVariant *p, *q; | |
137 | unsigned i; | |
138 | ||
139 | /* 3 keys + 3 values */ | |
140 | assert_se(json_variant_elements(v) == 6); | |
141 | ||
142 | /* has k */ | |
143 | p = json_variant_by_key(v, "k"); | |
144 | assert_se(p && json_variant_type(p) == JSON_VARIANT_STRING); | |
145 | ||
146 | /* k equals v */ | |
147 | assert_se(streq(json_variant_string(p), "v")); | |
148 | ||
149 | /* has foo */ | |
150 | p = json_variant_by_key(v, "foo"); | |
151 | assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 3); | |
152 | ||
153 | /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */ | |
154 | for (i = 0; i < 3; ++i) { | |
155 | q = json_variant_by_index(p, i); | |
156 | assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == (i+1)); | |
157 | assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == (i+1)); | |
158 | } | |
159 | ||
160 | /* has bar */ | |
161 | p = json_variant_by_key(v, "bar"); | |
162 | assert_se(p && json_variant_type(p) == JSON_VARIANT_OBJECT && json_variant_elements(p) == 2); | |
163 | ||
164 | /* zap is null */ | |
165 | q = json_variant_by_key(p, "zap"); | |
166 | assert_se(q && json_variant_type(q) == JSON_VARIANT_NULL); | |
167 | } | |
168 | ||
169 | static void test_2(JsonVariant *v) { | |
170 | JsonVariant *p, *q; | |
171 | ||
172 | /* 2 keys + 2 values */ | |
173 | assert_se(json_variant_elements(v) == 4); | |
174 | ||
175 | /* has mutant */ | |
176 | p = json_variant_by_key(v, "mutant"); | |
177 | assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 4); | |
178 | ||
179 | /* mutant[0] == 1 */ | |
180 | q = json_variant_by_index(p, 0); | |
181 | assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == 1); | |
182 | assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == 1); | |
183 | ||
184 | /* mutant[1] == null */ | |
185 | q = json_variant_by_index(p, 1); | |
186 | assert_se(q && json_variant_type(q) == JSON_VARIANT_NULL); | |
187 | ||
188 | /* mutant[2] == "1" */ | |
189 | q = json_variant_by_index(p, 2); | |
190 | assert_se(q && json_variant_type(q) == JSON_VARIANT_STRING && streq(json_variant_string(q), "1")); | |
191 | ||
192 | /* mutant[3] == JSON_VARIANT_OBJECT */ | |
193 | q = json_variant_by_index(p, 3); | |
194 | assert_se(q && json_variant_type(q) == JSON_VARIANT_OBJECT && json_variant_elements(q) == 2); | |
195 | ||
196 | /* has 1 */ | |
197 | p = json_variant_by_key(q, "1"); | |
198 | assert_se(p && json_variant_type(p) == JSON_VARIANT_ARRAY && json_variant_elements(p) == 2); | |
199 | ||
200 | /* "1"[0] == 1 */ | |
201 | q = json_variant_by_index(p, 0); | |
202 | assert_se(q && json_variant_type(q) == JSON_VARIANT_UNSIGNED && json_variant_unsigned(q) == 1); | |
203 | assert_se(q && json_variant_has_type(q, JSON_VARIANT_INTEGER) && json_variant_integer(q) == 1); | |
204 | ||
205 | /* "1"[1] == "1" */ | |
206 | q = json_variant_by_index(p, 1); | |
207 | assert_se(q && json_variant_type(q) == JSON_VARIANT_STRING && streq(json_variant_string(q), "1")); | |
208 | ||
209 | /* has thisisaverylongproperty */ | |
210 | p = json_variant_by_key(v, "thisisaverylongproperty"); | |
40990eac | 211 | assert_se(p && json_variant_type(p) == JSON_VARIANT_REAL && fabsl(json_variant_real(p) - 1.27) < 0.001); |
788c34be LP |
212 | } |
213 | ||
788c34be LP |
214 | static void test_zeroes(JsonVariant *v) { |
215 | size_t i; | |
216 | ||
217 | /* Make sure zero is how we expect it. */ | |
218 | ||
219 | assert_se(json_variant_elements(v) == 13); | |
220 | ||
221 | for (i = 0; i < json_variant_elements(v); i++) { | |
222 | JsonVariant *w; | |
223 | size_t j; | |
224 | ||
225 | assert_se(w = json_variant_by_index(v, i)); | |
226 | ||
227 | assert_se(json_variant_integer(w) == 0); | |
228 | assert_se(json_variant_unsigned(w) == 0U); | |
229 | ||
230 | #pragma GCC diagnostic push | |
231 | #pragma GCC diagnostic ignored "-Wfloat-equal" | |
232 | assert_se(json_variant_real(w) == 0.0L); | |
233 | #pragma GCC diagnostic pop | |
234 | ||
235 | assert_se(json_variant_is_integer(w)); | |
236 | assert_se(json_variant_is_unsigned(w)); | |
237 | assert_se(json_variant_is_real(w)); | |
238 | assert_se(json_variant_is_number(w)); | |
239 | ||
240 | assert_se(!json_variant_is_negative(w)); | |
241 | ||
242 | assert_se(IN_SET(json_variant_type(w), JSON_VARIANT_INTEGER, JSON_VARIANT_UNSIGNED, JSON_VARIANT_REAL)); | |
243 | ||
244 | for (j = 0; j < json_variant_elements(v); j++) { | |
245 | JsonVariant *q; | |
246 | ||
247 | assert_se(q = json_variant_by_index(v, j)); | |
248 | ||
249 | assert_se(json_variant_equal(w, q)); | |
250 | } | |
251 | } | |
252 | } | |
253 | ||
254 | static void test_build(void) { | |
255 | _cleanup_(json_variant_unrefp) JsonVariant *a = NULL, *b = NULL; | |
256 | _cleanup_free_ char *s = NULL, *t = NULL; | |
257 | ||
258 | assert_se(json_build(&a, JSON_BUILD_STRING("hallo")) >= 0); | |
259 | assert_se(json_build(&b, JSON_BUILD_LITERAL(" \"hallo\" ")) >= 0); | |
260 | assert_se(json_variant_equal(a, b)); | |
261 | ||
262 | b = json_variant_unref(b); | |
263 | ||
264 | assert_se(json_build(&b, JSON_BUILD_VARIANT(a)) >= 0); | |
265 | assert_se(json_variant_equal(a, b)); | |
266 | ||
267 | b = json_variant_unref(b); | |
268 | assert_se(json_build(&b, JSON_BUILD_STRING("pief")) >= 0); | |
269 | assert_se(!json_variant_equal(a, b)); | |
270 | ||
271 | a = json_variant_unref(a); | |
272 | b = json_variant_unref(b); | |
273 | ||
274 | assert_se(json_build(&a, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("one", JSON_BUILD_INTEGER(7)), | |
275 | JSON_BUILD_PAIR("two", JSON_BUILD_REAL(2.0)), | |
276 | JSON_BUILD_PAIR("three", JSON_BUILD_INTEGER(0)))) >= 0); | |
277 | ||
278 | assert_se(json_build(&b, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("two", JSON_BUILD_INTEGER(2)), | |
279 | JSON_BUILD_PAIR("three", JSON_BUILD_REAL(0)), | |
280 | JSON_BUILD_PAIR("one", JSON_BUILD_REAL(7)))) >= 0); | |
281 | ||
282 | assert_se(json_variant_equal(a, b)); | |
283 | ||
284 | a = json_variant_unref(a); | |
285 | b = json_variant_unref(b); | |
286 | ||
14648b76 | 287 | const char* arr_1234[] = {"one", "two", "three", "four", NULL}; |
788c34be LP |
288 | assert_se(json_build(&a, JSON_BUILD_ARRAY(JSON_BUILD_OBJECT(JSON_BUILD_PAIR("x", JSON_BUILD_BOOLEAN(true)), |
289 | JSON_BUILD_PAIR("y", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("this", JSON_BUILD_NULL)))), | |
290 | JSON_BUILD_VARIANT(NULL), | |
291 | JSON_BUILD_LITERAL(NULL), | |
292 | JSON_BUILD_STRING(NULL), | |
293 | JSON_BUILD_NULL, | |
294 | JSON_BUILD_INTEGER(77), | |
14648b76 ZJS |
295 | JSON_BUILD_ARRAY(JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("foobar")), |
296 | JSON_BUILD_VARIANT(JSON_VARIANT_STRING_CONST("zzz"))), | |
297 | JSON_BUILD_STRV((char**) arr_1234))) >= 0); | |
788c34be LP |
298 | |
299 | assert_se(json_variant_format(a, 0, &s) >= 0); | |
300 | log_info("GOT: %s\n", s); | |
301 | assert_se(json_parse(s, &b, NULL, NULL) >= 0); | |
302 | assert_se(json_variant_equal(a, b)); | |
303 | ||
304 | a = json_variant_unref(a); | |
305 | b = json_variant_unref(b); | |
306 | ||
307 | assert_se(json_build(&a, JSON_BUILD_REAL(M_PIl)) >= 0); | |
308 | ||
309 | s = mfree(s); | |
310 | assert_se(json_variant_format(a, 0, &s) >= 0); | |
311 | log_info("GOT: %s\n", s); | |
312 | assert_se(json_parse(s, &b, NULL, NULL) >= 0); | |
313 | assert_se(json_variant_format(b, 0, &t) >= 0); | |
314 | log_info("GOT: %s\n", t); | |
315 | ||
316 | assert_se(streq(s, t)); | |
317 | ||
318 | a = json_variant_unref(a); | |
319 | b = json_variant_unref(b); | |
319a4f27 LP |
320 | |
321 | assert_se(json_build(&a, JSON_BUILD_OBJECT( | |
322 | JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")), | |
323 | JSON_BUILD_PAIR("z", JSON_BUILD_STRING("a")), | |
324 | JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c")) | |
325 | )) >= 0); | |
326 | ||
327 | assert_se(json_build(&b, JSON_BUILD_OBJECT( | |
328 | JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")), | |
329 | JSON_BUILD_PAIR_CONDITION(false, "p", JSON_BUILD_STRING("q")), | |
330 | JSON_BUILD_PAIR_CONDITION(true, "z", JSON_BUILD_STRING("a")), | |
331 | JSON_BUILD_PAIR_CONDITION(false, "j", JSON_BUILD_ARRAY(JSON_BUILD_STRING("k"), JSON_BUILD_STRING("u"), JSON_BUILD_STRING("i"))), | |
332 | JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c")) | |
333 | )) >= 0); | |
334 | ||
335 | assert_se(json_variant_equal(a, b)); | |
788c34be LP |
336 | } |
337 | ||
338 | static void test_source(void) { | |
339 | static const char data[] = | |
340 | "\n" | |
341 | "\n" | |
342 | "{\n" | |
343 | "\"foo\" : \"bar\", \n" | |
344 | "\"qüüx\" : [ 1, 2, 3,\n" | |
345 | "4,\n" | |
346 | "5 ],\n" | |
347 | "\"miep\" : { \"hallo\" : 1 },\n" | |
348 | "\n" | |
349 | "\"zzzzzz\" \n" | |
350 | ":\n" | |
351 | "[ true, \n" | |
352 | "false, 7.5, {} ]\n" | |
353 | "}\n"; | |
354 | ||
355 | _cleanup_fclose_ FILE *f = NULL; | |
356 | _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; | |
357 | ||
358 | printf("--- original begin ---\n" | |
359 | "%s" | |
360 | "--- original end ---\n", data); | |
361 | ||
673a1e6f | 362 | assert_se(f = fmemopen_unlocked((void*) data, strlen(data), "r")); |
788c34be LP |
363 | |
364 | assert_se(json_parse_file(f, "waldo", &v, NULL, NULL) >= 0); | |
365 | ||
366 | printf("--- non-pretty begin ---\n"); | |
367 | json_variant_dump(v, 0, stdout, NULL); | |
368 | printf("\n--- non-pretty end ---\n"); | |
369 | ||
370 | printf("--- pretty begin ---\n"); | |
371 | json_variant_dump(v, JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR|JSON_FORMAT_SOURCE, stdout, NULL); | |
372 | printf("--- pretty end ---\n"); | |
373 | } | |
374 | ||
b2fa0d4f | 375 | static void test_depth(void) { |
d520d519 | 376 | _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; |
b2fa0d4f LP |
377 | unsigned i; |
378 | int r; | |
379 | ||
d520d519 | 380 | v = JSON_VARIANT_STRING_CONST("start"); |
b2fa0d4f LP |
381 | |
382 | /* Let's verify that the maximum depth checks work */ | |
383 | ||
384 | for (i = 0;; i++) { | |
385 | _cleanup_(json_variant_unrefp) JsonVariant *w = NULL; | |
386 | ||
387 | assert_se(i <= UINT16_MAX); | |
388 | if (i & 1) | |
389 | r = json_variant_new_array(&w, &v, 1); | |
390 | else | |
d520d519 | 391 | r = json_variant_new_object(&w, (JsonVariant*[]) { JSON_VARIANT_STRING_CONST("key"), v }, 2); |
b2fa0d4f LP |
392 | if (r == -ELNRNG) { |
393 | log_info("max depth at %u", i); | |
394 | break; | |
395 | } | |
b6cda3ec ZJS |
396 | #if HAS_FEATURE_MEMORY_SANITIZER |
397 | /* msan doesn't like the stack nesting to be too deep. Let's quit early. */ | |
398 | if (i >= 128) { | |
399 | log_info("quitting early at depth %u", i); | |
400 | break; | |
401 | } | |
402 | #endif | |
b2fa0d4f LP |
403 | |
404 | assert_se(r >= 0); | |
405 | ||
406 | json_variant_unref(v); | |
407 | v = TAKE_PTR(w); | |
408 | } | |
409 | ||
410 | json_variant_dump(v, 0, stdout, NULL); | |
d520d519 | 411 | fputs("\n", stdout); |
b2fa0d4f LP |
412 | } |
413 | ||
788c34be | 414 | int main(int argc, char *argv[]) { |
adbdcfbe | 415 | test_setup_logging(LOG_DEBUG); |
788c34be LP |
416 | |
417 | test_tokenizer("x", -EINVAL); | |
418 | test_tokenizer("", JSON_TOKEN_END); | |
419 | test_tokenizer(" ", JSON_TOKEN_END); | |
420 | test_tokenizer("0", JSON_TOKEN_UNSIGNED, (uintmax_t) 0, JSON_TOKEN_END); | |
421 | test_tokenizer("-0", JSON_TOKEN_INTEGER, (intmax_t) 0, JSON_TOKEN_END); | |
422 | test_tokenizer("1234", JSON_TOKEN_UNSIGNED, (uintmax_t) 1234, JSON_TOKEN_END); | |
423 | test_tokenizer("-1234", JSON_TOKEN_INTEGER, (intmax_t) -1234, JSON_TOKEN_END); | |
424 | test_tokenizer("18446744073709551615", JSON_TOKEN_UNSIGNED, (uintmax_t) UINT64_MAX, JSON_TOKEN_END); | |
425 | test_tokenizer("-9223372036854775808", JSON_TOKEN_INTEGER, (intmax_t) INT64_MIN, JSON_TOKEN_END); | |
426 | test_tokenizer("18446744073709551616", JSON_TOKEN_REAL, (long double) 18446744073709551616.0L, JSON_TOKEN_END); | |
427 | test_tokenizer("-9223372036854775809", JSON_TOKEN_REAL, (long double) -9223372036854775809.0L, JSON_TOKEN_END); | |
428 | test_tokenizer("-1234", JSON_TOKEN_INTEGER, (intmax_t) -1234, JSON_TOKEN_END); | |
429 | test_tokenizer("3.141", JSON_TOKEN_REAL, (long double) 3.141, JSON_TOKEN_END); | |
430 | test_tokenizer("0.0", JSON_TOKEN_REAL, (long double) 0.0, JSON_TOKEN_END); | |
431 | test_tokenizer("7e3", JSON_TOKEN_REAL, (long double) 7e3, JSON_TOKEN_END); | |
432 | test_tokenizer("-7e-3", JSON_TOKEN_REAL, (long double) -7e-3, JSON_TOKEN_END); | |
433 | test_tokenizer("true", JSON_TOKEN_BOOLEAN, true, JSON_TOKEN_END); | |
434 | test_tokenizer("false", JSON_TOKEN_BOOLEAN, false, JSON_TOKEN_END); | |
435 | test_tokenizer("null", JSON_TOKEN_NULL, JSON_TOKEN_END); | |
436 | test_tokenizer("{}", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END); | |
437 | test_tokenizer("\t {\n} \n", JSON_TOKEN_OBJECT_OPEN, JSON_TOKEN_OBJECT_CLOSE, JSON_TOKEN_END); | |
438 | test_tokenizer("[]", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END); | |
439 | test_tokenizer("\t [] \n\n", JSON_TOKEN_ARRAY_OPEN, JSON_TOKEN_ARRAY_CLOSE, JSON_TOKEN_END); | |
440 | test_tokenizer("\"\"", JSON_TOKEN_STRING, "", JSON_TOKEN_END); | |
441 | test_tokenizer("\"foo\"", JSON_TOKEN_STRING, "foo", JSON_TOKEN_END); | |
442 | test_tokenizer("\"foo\\nfoo\"", JSON_TOKEN_STRING, "foo\nfoo", JSON_TOKEN_END); | |
443 | 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); | |
444 | 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); | |
445 | test_tokenizer("\"\xef\xbf\xbd\"", JSON_TOKEN_STRING, "\xef\xbf\xbd", JSON_TOKEN_END); | |
446 | test_tokenizer("\"\\ufffd\"", JSON_TOKEN_STRING, "\xef\xbf\xbd", JSON_TOKEN_END); | |
447 | test_tokenizer("\"\\uf\"", -EINVAL); | |
448 | test_tokenizer("\"\\ud800a\"", -EINVAL); | |
449 | test_tokenizer("\"\\udc00\\udc00\"", -EINVAL); | |
450 | test_tokenizer("\"\\ud801\\udc37\"", JSON_TOKEN_STRING, "\xf0\x90\x90\xb7", JSON_TOKEN_END); | |
451 | ||
452 | 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); | |
453 | ||
454 | test_variant("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1); | |
455 | test_variant("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"thisisaverylongproperty\": 1.27}", test_2); | |
456 | 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); | |
457 | ||
458 | 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); | |
459 | ||
460 | test_build(); | |
461 | ||
462 | test_source(); | |
463 | ||
b2fa0d4f LP |
464 | test_depth(); |
465 | ||
788c34be LP |
466 | return 0; |
467 | } |