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