]>
git.proxmox.com Git - mirror_qemu.git/blob - tests/check-qjson.c
2 * Copyright IBM, Corp. 2009
3 * Copyright (c) 2013, 2015 Red Hat Inc.
6 * Anthony Liguori <aliguori@us.ibm.com>
7 * Markus Armbruster <armbru@redhat.com>
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include "qapi/error.h"
17 #include "qapi/qmp/qbool.h"
18 #include "qapi/qmp/qjson.h"
19 #include "qapi/qmp/qlit.h"
20 #include "qapi/qmp/qnull.h"
21 #include "qapi/qmp/qnum.h"
22 #include "qapi/qmp/qstring.h"
23 #include "qemu-common.h"
25 static QString
*from_json_str(const char *jstr
, bool single
, Error
**errp
)
27 char quote
= single
? '\'' : '"';
28 char *qjstr
= g_strdup_printf("%c%s%c", quote
, jstr
, quote
);
29 QString
*ret
= qobject_to(QString
, qobject_from_json(qjstr
, errp
));
35 static char *to_json_str(QString
*str
)
37 QString
*json
= qobject_to_json(QOBJECT(str
));
43 /* peel off double quotes */
44 jstr
= g_strndup(qstring_get_str(json
) + 1,
45 qstring_get_length(json
) - 2);
50 static void escaped_string(void)
53 /* Content of JSON string to parse with qobject_from_json() */
55 /* Expected parse output; to unparse with qobject_to_json() */
59 { "\\b\\f\\n\\r\\t\\\\\\\"", "\b\f\n\r\t\\\"" },
60 { "\\/\\'", "/'", .skip
= 1 },
61 { "single byte utf-8 \\u0020", "single byte utf-8 ", .skip
= 1 },
62 { "double byte utf-8 \\u00A2", "double byte utf-8 \xc2\xa2" },
63 { "triple byte utf-8 \\u20AC", "triple byte utf-8 \xe2\x82\xac" },
64 { "quadruple byte utf-8 \\uD834\\uDD1E", /* U+1D11E */
65 /* bug: want \xF0\x9D\x84\x9E */
66 "quadruple byte utf-8 \xED\xA0\xB4\xED\xB4\x9E", .skip
= 1 },
73 { "\\u12345", "\341\210\2645" },
74 { "\\u0000x", "x", .skip
= 1}, /* bug: want \xC0\x80x */
75 { "unpaired leading surrogate \\uD800",
76 /* bug: not rejected */
77 "unpaired leading surrogate \355\240\200", .skip
= 1 },
78 { "unpaired leading surrogate \\uD800\\uCAFE",
79 /* bug: not rejected */
80 "unpaired leading surrogate \355\240\200\354\253\276", .skip
= 1 },
81 { "unpaired leading surrogate \\uD800\\uD801\\uDC02",
82 /* bug: not rejected */
83 "unpaired leading surrogate \355\240\200\355\240\201\355\260\202",
85 { "unpaired trailing surrogate \\uDC00",
86 /* bug: not rejected */
87 "unpaired trailing surrogate \355\260\200", .skip
= 1},
88 { "backward surrogate pair \\uDC00\\uD800",
89 /* bug: not rejected */
90 "backward surrogate pair \355\260\200\355\240\200", .skip
= 1},
91 { "noncharacter U+FDD0 \\uFDD0",
92 /* bug: not rejected */
93 "noncharacter U+FDD0 \xEF\xB7\x90", .skip
= 1},
94 { "noncharacter U+FDEF \\uFDEF",
95 /* bug: not rejected */
96 "noncharacter U+FDEF \xEF\xB7\xAF", .skip
= 1},
97 { "noncharacter U+1FFFE \\uD87F\\uDFFE",
98 /* bug: not rejected */
99 "noncharacter U+1FFFE \xED\xA1\xBF\xED\xBF\xBE", .skip
= 1},
100 { "noncharacter U+10FFFF \\uDC3F\\uDFFF",
101 /* bug: not rejected */
102 "noncharacter U+10FFFF \xED\xB0\xBF\xED\xBF\xBF", .skip
= 1},
109 for (i
= 0; test_cases
[i
].json_in
; i
++) {
110 for (j
= 0; j
< 2; j
++) {
111 if (test_cases
[i
].utf8_out
) {
112 cstr
= from_json_str(test_cases
[i
].json_in
, j
, &error_abort
);
113 g_assert_cmpstr(qstring_get_try_str(cstr
),
114 ==, test_cases
[i
].utf8_out
);
115 if (!test_cases
[i
].skip
) {
116 jstr
= to_json_str(cstr
);
117 g_assert_cmpstr(jstr
, ==, test_cases
[i
].json_in
);
122 cstr
= from_json_str(test_cases
[i
].json_in
, j
, NULL
);
129 static void simple_string(void)
136 { "\"hello world\"", "hello world" },
137 { "\"the quick brown fox jumped over the fence\"",
138 "the quick brown fox jumped over the fence" },
142 for (i
= 0; test_cases
[i
].encoded
; i
++) {
146 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
147 str
= qobject_to(QString
, obj
);
149 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
151 str
= qobject_to_json(obj
);
152 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
160 static void single_quote_string(void)
167 { "'hello world'", "hello world" },
168 { "'the quick brown fox \\' jumped over the fence'",
169 "the quick brown fox ' jumped over the fence" },
173 for (i
= 0; test_cases
[i
].encoded
; i
++) {
177 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
178 str
= qobject_to(QString
, obj
);
180 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
186 static void utf8_string(void)
189 * FIXME Current behavior for invalid UTF-8 sequences is
190 * incorrect. This test expects current, incorrect results.
191 * They're all marked "bug:" below, and are to be replaced by
192 * correct ones as the bugs get fixed.
194 * The JSON parser rejects some invalid sequences, but accepts
195 * others without correcting the problem.
197 * We should either reject all invalid sequences, or minimize
198 * overlong sequences and replace all other invalid sequences by a
199 * suitable replacement character. A common choice for
200 * replacement is U+FFFD.
202 * Problem: we can't easily deal with embedded U+0000. Parsing
203 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
204 * which gets misinterpreted as NUL-terminated "this ". We should
205 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
208 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
209 * capability and stress test at
210 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
212 static const struct {
214 const char *utf8_out
;
215 const char *json_out
; /* defaults to @json_in */
216 const char *utf8_in
; /* defaults to @utf8_out */
219 * Bug markers used here:
220 * - bug: not corrected
221 * JSON parser fails to correct invalid sequence(s)
223 * JSON parser rejects invalid sequence(s)
224 * We may choose to define this as feature
226 * JSON parser produces incorrect result, this is the
227 * correct one, assuming replacement character U+FFFF
228 * We may choose to reject instead of replace
231 /* 1 Some correct UTF-8 text */
233 /* a bit of German */
234 "\"Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
235 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.\"",
236 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
237 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
238 "\"Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
239 " jeden gr\\u00F6\\u00DFeren Zwerg.\"",
243 "\"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5\"",
244 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
245 "\"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5\"",
247 /* 2 Boundary condition test cases */
248 /* 2.1 First possible sequence of a certain length */
249 /* 2.1.1 1 byte U+0000 */
252 "", /* bug: want overlong "\xC0\x80" */
256 /* 2.1.2 2 bytes U+0080 */
262 /* 2.1.3 3 bytes U+0800 */
268 /* 2.1.4 4 bytes U+10000 */
270 "\"\xF0\x90\x80\x80\"",
272 "\"\\uD800\\uDC00\"",
274 /* 2.1.5 5 bytes U+200000 */
276 "\"\xF8\x88\x80\x80\x80\"",
277 NULL
, /* bug: rejected */
279 "\xF8\x88\x80\x80\x80",
281 /* 2.1.6 6 bytes U+4000000 */
283 "\"\xFC\x84\x80\x80\x80\x80\"",
284 NULL
, /* bug: rejected */
286 "\xFC\x84\x80\x80\x80\x80",
288 /* 2.2 Last possible sequence of a certain length */
289 /* 2.2.1 1 byte U+007F */
295 /* 2.2.2 2 bytes U+07FF */
302 * 2.2.3 3 bytes U+FFFC
303 * The last possible sequence is actually U+FFFF. But that's
304 * a noncharacter, and already covered by its own test case
305 * under 5.3. Same for U+FFFE. U+FFFD is the last character
306 * in the BMP, and covered under 2.3. Because of U+FFFD's
307 * special role as replacement character, it's worth testing
315 /* 2.2.4 4 bytes U+1FFFFF */
317 "\"\xF7\xBF\xBF\xBF\"",
318 NULL
, /* bug: rejected */
322 /* 2.2.5 5 bytes U+3FFFFFF */
324 "\"\xFB\xBF\xBF\xBF\xBF\"",
325 NULL
, /* bug: rejected */
327 "\xFB\xBF\xBF\xBF\xBF",
329 /* 2.2.6 6 bytes U+7FFFFFFF */
331 "\"\xFD\xBF\xBF\xBF\xBF\xBF\"",
332 NULL
, /* bug: rejected */
334 "\xFD\xBF\xBF\xBF\xBF\xBF",
336 /* 2.3 Other boundary conditions */
338 /* last one before surrogate range: U+D7FF */
344 /* first one after surrogate range: U+E000 */
350 /* last one in BMP: U+FFFD */
356 /* last one in last plane: U+10FFFD */
357 "\"\xF4\x8F\xBF\xBD\"",
362 /* first one beyond Unicode range: U+110000 */
363 "\"\xF4\x90\x80\x80\"",
367 /* 3 Malformed sequences */
368 /* 3.1 Unexpected continuation bytes */
369 /* 3.1.1 First continuation byte */
372 "\x80", /* bug: not corrected */
375 /* 3.1.2 Last continuation byte */
378 "\xBF", /* bug: not corrected */
381 /* 3.1.3 2 continuation bytes */
384 "\x80\xBF", /* bug: not corrected */
385 "\"\\uFFFD\\uFFFD\"",
387 /* 3.1.4 3 continuation bytes */
390 "\x80\xBF\x80", /* bug: not corrected */
391 "\"\\uFFFD\\uFFFD\\uFFFD\"",
393 /* 3.1.5 4 continuation bytes */
395 "\"\x80\xBF\x80\xBF\"",
396 "\x80\xBF\x80\xBF", /* bug: not corrected */
397 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
399 /* 3.1.6 5 continuation bytes */
401 "\"\x80\xBF\x80\xBF\x80\"",
402 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
403 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
405 /* 3.1.7 6 continuation bytes */
407 "\"\x80\xBF\x80\xBF\x80\xBF\"",
408 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
409 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
411 /* 3.1.8 7 continuation bytes */
413 "\"\x80\xBF\x80\xBF\x80\xBF\x80\"",
414 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
415 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
417 /* 3.1.9 Sequence of all 64 possible continuation bytes */
419 "\"\x80\x81\x82\x83\x84\x85\x86\x87"
420 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
421 "\x90\x91\x92\x93\x94\x95\x96\x97"
422 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
423 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
424 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
425 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
426 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\"",
427 /* bug: not corrected */
428 "\x80\x81\x82\x83\x84\x85\x86\x87"
429 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
430 "\x90\x91\x92\x93\x94\x95\x96\x97"
431 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
432 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
433 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
434 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
435 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
436 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
437 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
438 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
439 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
440 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
441 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
442 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
443 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\""
445 /* 3.2 Lonely start characters */
446 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
448 "\"\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
449 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
450 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
451 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF \"",
452 NULL
, /* bug: rejected */
453 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
454 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
455 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
456 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
457 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
458 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
459 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
460 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
462 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
464 "\"\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
465 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF \"",
466 /* bug: not corrected */
467 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
468 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
469 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
470 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
472 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
474 "\"\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 \"",
475 NULL
, /* bug: rejected */
476 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
477 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
479 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
481 "\"\xF8 \xF9 \xFA \xFB \"",
482 NULL
, /* bug: rejected */
483 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
484 "\xF8 \xF9 \xFA \xFB ",
486 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
489 NULL
, /* bug: rejected */
490 "\"\\uFFFD \\uFFFD \"",
493 /* 3.3 Sequences with last continuation byte missing */
494 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
497 NULL
, /* bug: rejected */
501 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
504 "\xE0\x80", /* bug: not corrected */
507 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
510 "\xF0\x80\x80", /* bug: not corrected */
513 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
515 "\"\xF8\x80\x80\x80\"",
516 NULL
, /* bug: rejected */
520 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
522 "\"\xFC\x80\x80\x80\x80\"",
523 NULL
, /* bug: rejected */
525 "\xFC\x80\x80\x80\x80",
527 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
530 "\xDF", /* bug: not corrected */
533 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
536 "\xEF\xBF", /* bug: not corrected */
539 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
542 NULL
, /* bug: rejected */
546 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
548 "\"\xFB\xBF\xBF\xBF\"",
549 NULL
, /* bug: rejected */
553 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
555 "\"\xFD\xBF\xBF\xBF\xBF\"",
556 NULL
, /* bug: rejected */
558 "\xFD\xBF\xBF\xBF\xBF",
560 /* 3.4 Concatenation of incomplete sequences */
562 "\"\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
563 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF\"",
564 NULL
, /* bug: rejected */
565 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
566 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
567 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
568 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
570 /* 3.5 Impossible bytes */
573 NULL
, /* bug: rejected */
579 NULL
, /* bug: rejected */
584 "\"\xFE\xFE\xFF\xFF\"",
585 NULL
, /* bug: rejected */
586 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
589 /* 4 Overlong sequences */
590 /* 4.1 Overlong '/' */
593 NULL
, /* bug: rejected */
599 "\xE0\x80\xAF", /* bug: not corrected */
603 "\"\xF0\x80\x80\xAF\"",
604 "\xF0\x80\x80\xAF", /* bug: not corrected */
608 "\"\xF8\x80\x80\x80\xAF\"",
609 NULL
, /* bug: rejected */
611 "\xF8\x80\x80\x80\xAF",
614 "\"\xFC\x80\x80\x80\x80\xAF\"",
615 NULL
, /* bug: rejected */
617 "\xFC\x80\x80\x80\x80\xAF",
620 * 4.2 Maximum overlong sequences
621 * Highest Unicode value that is still resulting in an
622 * overlong sequence if represented with the given number of
623 * bytes. This is a boundary test for safe UTF-8 decoders.
628 NULL
, /* bug: rejected */
635 "\xE0\x9F\xBF", /* bug: not corrected */
641 * The actual maximum would be U+FFFF, but that's a
642 * noncharacter. Testing U+FFFC seems more useful. See
645 "\"\xF0\x8F\xBF\xBC\"",
646 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
651 "\"\xF8\x87\xBF\xBF\xBF\"",
652 NULL
, /* bug: rejected */
654 "\xF8\x87\xBF\xBF\xBF",
658 "\"\xFC\x83\xBF\xBF\xBF\xBF\"",
659 NULL
, /* bug: rejected */
661 "\xFC\x83\xBF\xBF\xBF\xBF",
663 /* 4.3 Overlong representation of the NUL character */
667 NULL
, /* bug: rejected */
674 "\xE0\x80\x80", /* bug: not corrected */
679 "\"\xF0\x80\x80\x80\"",
680 "\xF0\x80\x80\x80", /* bug: not corrected */
685 "\"\xF8\x80\x80\x80\x80\"",
686 NULL
, /* bug: rejected */
688 "\xF8\x80\x80\x80\x80",
692 "\"\xFC\x80\x80\x80\x80\x80\"",
693 NULL
, /* bug: rejected */
695 "\xFC\x80\x80\x80\x80\x80",
697 /* 5 Illegal code positions */
698 /* 5.1 Single UTF-16 surrogates */
702 "\xED\xA0\x80", /* bug: not corrected */
708 "\xED\xAD\xBF", /* bug: not corrected */
714 "\xED\xAE\x80", /* bug: not corrected */
720 "\xED\xAF\xBF", /* bug: not corrected */
726 "\xED\xB0\x80", /* bug: not corrected */
732 "\xED\xBE\x80", /* bug: not corrected */
738 "\xED\xBF\xBF", /* bug: not corrected */
741 /* 5.2 Paired UTF-16 surrogates */
744 "\"\xED\xA0\x80\xED\xB0\x80\"",
745 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
746 "\"\\uFFFD\\uFFFD\"",
750 "\"\xED\xA0\x80\xED\xBF\xBF\"",
751 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
752 "\"\\uFFFD\\uFFFD\"",
756 "\"\xED\xAD\xBF\xED\xB0\x80\"",
757 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
758 "\"\\uFFFD\\uFFFD\"",
762 "\"\xED\xAD\xBF\xED\xBF\xBF\"",
763 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
764 "\"\\uFFFD\\uFFFD\"",
768 "\"\xED\xAE\x80\xED\xB0\x80\"",
769 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
770 "\"\\uFFFD\\uFFFD\"",
774 "\"\xED\xAE\x80\xED\xBF\xBF\"",
775 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
776 "\"\\uFFFD\\uFFFD\"",
780 "\"\xED\xAF\xBF\xED\xB0\x80\"",
781 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
782 "\"\\uFFFD\\uFFFD\"",
786 "\"\xED\xAF\xBF\xED\xBF\xBF\"",
787 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
788 "\"\\uFFFD\\uFFFD\"",
790 /* 5.3 Other illegal code positions */
791 /* BMP noncharacters */
795 "\xEF\xBF\xBE", /* bug: not corrected */
801 "\xEF\xBF\xBF", /* bug: not corrected */
807 "\xEF\xB7\x90", /* bug: not corrected */
813 "\xEF\xB7\xAF", /* bug: not corrected */
816 /* Plane 1 .. 16 noncharacters */
818 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
819 "\"\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
820 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
821 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
822 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
823 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
824 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
825 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
826 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
827 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
828 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
829 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
830 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
831 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
832 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
833 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
834 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF\"",
835 /* bug: not corrected */
836 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
837 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
838 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
839 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
840 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
841 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
842 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
843 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
844 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
845 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
846 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
847 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
848 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
849 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
850 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
851 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
852 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
853 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
854 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
855 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
862 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
;
864 for (i
= 0; test_cases
[i
].json_in
; i
++) {
865 json_in
= test_cases
[i
].json_in
;
866 utf8_out
= test_cases
[i
].utf8_out
;
867 utf8_in
= test_cases
[i
].utf8_in
?: test_cases
[i
].utf8_out
;
868 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
870 obj
= qobject_from_json(json_in
, utf8_out
? &error_abort
: NULL
);
872 str
= qobject_to(QString
, obj
);
874 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
880 obj
= QOBJECT(qstring_from_str(utf8_in
));
881 str
= qobject_to_json(obj
);
884 g_assert_cmpstr(qstring_get_str(str
), ==, json_out
);
892 * Disabled, because qobject_from_json() is buggy, and I can't
893 * be bothered to add the expected incorrect results.
894 * FIXME Enable once these bugs have been fixed.
896 if (0 && json_out
!= json_in
) {
897 obj
= qobject_from_json(json_out
, &error_abort
);
898 str
= qobject_to(QString
, obj
);
900 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
905 static void vararg_string(void)
912 { "the quick brown fox jumped over the fence" },
916 for (i
= 0; test_cases
[i
].decoded
; i
++) {
919 str
= qobject_to(QString
,
920 qobject_from_jsonf_nofail("%s",
921 test_cases
[i
].decoded
));
923 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
929 static void simple_number(void)
941 { "-0", 0, .skip
= 1 },
945 for (i
= 0; test_cases
[i
].encoded
; i
++) {
949 qnum
= qobject_to(QNum
,
950 qobject_from_json(test_cases
[i
].encoded
,
953 g_assert(qnum_get_try_int(qnum
, &val
));
954 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
955 if (test_cases
[i
].skip
== 0) {
958 str
= qobject_to_json(QOBJECT(qnum
));
959 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
967 static void large_number(void)
969 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
970 const char *gtu64
= "18446744073709551616"; /* 2^64 */
971 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
977 qnum
= qobject_to(QNum
, qobject_from_json(maxu64
, &error_abort
));
979 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
980 g_assert(!qnum_get_try_int(qnum
, &ival
));
982 str
= qobject_to_json(QOBJECT(qnum
));
983 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
987 qnum
= qobject_to(QNum
, qobject_from_json(gtu64
, &error_abort
));
989 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
990 g_assert(!qnum_get_try_uint(qnum
, &val
));
991 g_assert(!qnum_get_try_int(qnum
, &ival
));
993 str
= qobject_to_json(QOBJECT(qnum
));
994 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
998 qnum
= qobject_to(QNum
, qobject_from_json(lti64
, &error_abort
));
1000 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
1001 g_assert(!qnum_get_try_uint(qnum
, &val
));
1002 g_assert(!qnum_get_try_int(qnum
, &ival
));
1004 str
= qobject_to_json(QOBJECT(qnum
));
1005 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
1007 qobject_unref(qnum
);
1010 static void float_number(void)
1014 const char *encoded
;
1020 { "-32.12313", -32.12313 },
1021 { "-32.20e-10", -32.20e-10, .skip
= 1 },
1025 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1029 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1030 qnum
= qobject_to(QNum
, obj
);
1032 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
1034 if (test_cases
[i
].skip
== 0) {
1037 str
= qobject_to_json(obj
);
1038 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
1042 qobject_unref(qnum
);
1046 static void vararg_number(void)
1050 long long value_ll
= 0x2342342343LL
;
1051 double valuef
= 2.323423423;
1054 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value
));
1055 g_assert(qnum_get_try_int(qnum
, &val
));
1056 g_assert_cmpint(val
, ==, value
);
1057 qobject_unref(qnum
);
1059 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_ll
));
1060 g_assert(qnum_get_try_int(qnum
, &val
));
1061 g_assert_cmpint(val
, ==, value_ll
);
1062 qobject_unref(qnum
);
1064 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", valuef
));
1065 g_assert(qnum_get_double(qnum
) == valuef
);
1066 qobject_unref(qnum
);
1069 static void keyword_literal(void)
1076 obj
= qobject_from_json("true", &error_abort
);
1077 qbool
= qobject_to(QBool
, obj
);
1079 g_assert(qbool_get_bool(qbool
) == true);
1081 str
= qobject_to_json(obj
);
1082 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
1085 qobject_unref(qbool
);
1087 obj
= qobject_from_json("false", &error_abort
);
1088 qbool
= qobject_to(QBool
, obj
);
1090 g_assert(qbool_get_bool(qbool
) == false);
1092 str
= qobject_to_json(obj
);
1093 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
1096 qobject_unref(qbool
);
1098 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
1100 g_assert(qbool_get_bool(qbool
) == false);
1101 qobject_unref(qbool
);
1103 /* Test that non-zero values other than 1 get collapsed to true */
1104 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
1106 g_assert(qbool_get_bool(qbool
) == true);
1107 qobject_unref(qbool
);
1109 obj
= qobject_from_json("null", &error_abort
);
1110 g_assert(obj
!= NULL
);
1111 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
1114 g_assert(QOBJECT(null
) == obj
);
1117 qobject_unref(null
);
1120 static void simple_dict(void)
1124 const char *encoded
;
1128 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1129 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1130 { "foo", QLIT_QNUM(42) },
1131 { "bar", QLIT_QSTR("hello world") },
1136 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1140 .encoded
= "{\"foo\": 43}",
1141 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1142 { "foo", QLIT_QNUM(43) },
1149 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1153 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1154 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1156 str
= qobject_to_json(obj
);
1159 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1160 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1167 * this generates json of the form:
1168 * a(0,m) = [0, 1, ..., m-1]
1173 * 'key(n-1)': a(n-1,m)
1176 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1182 if (nest_level_max
== 0) {
1183 g_string_append(gstr
, "[");
1184 for (i
= 0; i
< elem_count
; i
++) {
1185 g_string_append_printf(gstr
, "%d", i
);
1186 if (i
< elem_count
- 1) {
1187 g_string_append_printf(gstr
, ", ");
1190 g_string_append(gstr
, "]");
1194 g_string_append(gstr
, "{");
1195 for (i
= 0; i
< nest_level_max
; i
++) {
1196 g_string_append_printf(gstr
, "'key%d': ", i
);
1197 gen_test_json(gstr
, i
, elem_count
);
1198 if (i
< nest_level_max
- 1) {
1199 g_string_append(gstr
, ",");
1202 g_string_append(gstr
, "}");
1205 static void large_dict(void)
1207 GString
*gstr
= g_string_new("");
1210 gen_test_json(gstr
, 10, 100);
1211 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1212 g_assert(obj
!= NULL
);
1215 g_string_free(gstr
, true);
1218 static void simple_list(void)
1222 const char *encoded
;
1226 .encoded
= "[43,42]",
1227 .decoded
= QLIT_QLIST(((QLitObject
[]){
1235 .decoded
= QLIT_QLIST(((QLitObject
[]){
1242 .decoded
= QLIT_QLIST(((QLitObject
[]){
1248 .decoded
= QLIT_QLIST(((QLitObject
[]){
1249 QLIT_QDICT(((QLitDictEntry
[]){
1258 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1262 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1263 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1265 str
= qobject_to_json(obj
);
1268 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1269 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1275 static void simple_whitespace(void)
1279 const char *encoded
;
1283 .encoded
= " [ 43 , 42 ]",
1284 .decoded
= QLIT_QLIST(((QLitObject
[]){
1291 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1292 .decoded
= QLIT_QLIST(((QLitObject
[]){
1294 QLIT_QDICT(((QLitDictEntry
[]){
1295 { "h", QLIT_QSTR("b") },
1297 QLIT_QLIST(((QLitObject
[]){
1304 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1305 .decoded
= QLIT_QLIST(((QLitObject
[]){
1307 QLIT_QDICT(((QLitDictEntry
[]){
1308 { "h", QLIT_QSTR("b") },
1309 { "a", QLIT_QNUM(32) },
1311 QLIT_QLIST(((QLitObject
[]){
1320 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1324 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1325 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1327 str
= qobject_to_json(obj
);
1330 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1331 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1338 static void simple_varargs(void)
1340 QObject
*embedded_obj
;
1342 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1345 QLIT_QLIST(((QLitObject
[]){
1351 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1352 g_assert(embedded_obj
!= NULL
);
1354 obj
= qobject_from_jsonf_nofail("[%d, 2, %p]", 1, embedded_obj
);
1355 g_assert(qlit_equal_qobject(&decoded
, obj
));
1360 static void empty_input(void)
1362 QObject
*obj
= qobject_from_json("", &error_abort
);
1363 g_assert(obj
== NULL
);
1366 static void blank_input(void)
1368 QObject
*obj
= qobject_from_json("\n ", &error_abort
);
1369 g_assert(obj
== NULL
);
1372 static void junk_input(void)
1374 /* Note: junk within strings is covered elsewhere */
1378 obj
= qobject_from_json("@", &err
);
1379 g_assert(!err
); /* BUG */
1380 g_assert(obj
== NULL
);
1382 obj
= qobject_from_json("[0\xFF]", &err
);
1383 error_free_or_abort(&err
);
1384 g_assert(obj
== NULL
);
1386 obj
= qobject_from_json("00", &err
);
1387 g_assert(!err
); /* BUG */
1388 g_assert(obj
== NULL
);
1390 obj
= qobject_from_json("[1e", &err
);
1391 g_assert(!err
); /* BUG */
1392 g_assert(obj
== NULL
);
1394 obj
= qobject_from_json("truer", &err
);
1395 error_free_or_abort(&err
);
1396 g_assert(obj
== NULL
);
1399 static void unterminated_string(void)
1402 QObject
*obj
= qobject_from_json("\"abc", &err
);
1403 g_assert(!err
); /* BUG */
1404 g_assert(obj
== NULL
);
1407 static void unterminated_sq_string(void)
1410 QObject
*obj
= qobject_from_json("'abc", &err
);
1411 g_assert(!err
); /* BUG */
1412 g_assert(obj
== NULL
);
1415 static void unterminated_escape(void)
1418 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1419 g_assert(!err
); /* BUG */
1420 g_assert(obj
== NULL
);
1423 static void unterminated_array(void)
1426 QObject
*obj
= qobject_from_json("[32", &err
);
1427 g_assert(!err
); /* BUG */
1428 g_assert(obj
== NULL
);
1431 static void unterminated_array_comma(void)
1434 QObject
*obj
= qobject_from_json("[32,", &err
);
1435 g_assert(!err
); /* BUG */
1436 g_assert(obj
== NULL
);
1439 static void invalid_array_comma(void)
1442 QObject
*obj
= qobject_from_json("[32,}", &err
);
1443 error_free_or_abort(&err
);
1444 g_assert(obj
== NULL
);
1447 static void unterminated_dict(void)
1450 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1451 g_assert(!err
); /* BUG */
1452 g_assert(obj
== NULL
);
1455 static void unterminated_dict_comma(void)
1458 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1459 g_assert(!err
); /* BUG */
1460 g_assert(obj
== NULL
);
1463 static void invalid_dict_comma(void)
1466 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1467 error_free_or_abort(&err
);
1468 g_assert(obj
== NULL
);
1471 static void unterminated_literal(void)
1474 QObject
*obj
= qobject_from_json("nul", &err
);
1475 error_free_or_abort(&err
);
1476 g_assert(obj
== NULL
);
1479 static char *make_nest(char *buf
, size_t cnt
)
1481 memset(buf
, '[', cnt
- 1);
1484 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1489 static void limits_nesting(void)
1492 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1493 char buf
[2 * (max_nesting
+ 1) + 1];
1496 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1497 g_assert(obj
!= NULL
);
1500 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1501 error_free_or_abort(&err
);
1502 g_assert(obj
== NULL
);
1505 static void multiple_values(void)
1510 /* BUG this leaks the syntax tree for "false" */
1511 obj
= qobject_from_json("false true", &err
);
1512 g_assert(qbool_get_bool(qobject_to(QBool
, obj
)));
1516 /* BUG simultaneously succeeds and fails */
1517 /* BUG calls json_parser_parse() with errp pointing to non-null */
1518 obj
= qobject_from_json("} true", &err
);
1519 g_assert(qbool_get_bool(qobject_to(QBool
, obj
)));
1520 error_free_or_abort(&err
);
1524 int main(int argc
, char **argv
)
1526 g_test_init(&argc
, &argv
, NULL
);
1528 g_test_add_func("/literals/string/simple", simple_string
);
1529 g_test_add_func("/literals/string/escaped", escaped_string
);
1530 g_test_add_func("/literals/string/utf8", utf8_string
);
1531 g_test_add_func("/literals/string/single_quote", single_quote_string
);
1532 g_test_add_func("/literals/string/vararg", vararg_string
);
1534 g_test_add_func("/literals/number/simple", simple_number
);
1535 g_test_add_func("/literals/number/large", large_number
);
1536 g_test_add_func("/literals/number/float", float_number
);
1537 g_test_add_func("/literals/number/vararg", vararg_number
);
1539 g_test_add_func("/literals/keyword", keyword_literal
);
1541 g_test_add_func("/dicts/simple_dict", simple_dict
);
1542 g_test_add_func("/dicts/large_dict", large_dict
);
1543 g_test_add_func("/lists/simple_list", simple_list
);
1545 g_test_add_func("/whitespace/simple_whitespace", simple_whitespace
);
1547 g_test_add_func("/varargs/simple_varargs", simple_varargs
);
1549 g_test_add_func("/errors/empty", empty_input
);
1550 g_test_add_func("/errors/blank", blank_input
);
1551 g_test_add_func("/errors/junk", junk_input
);
1552 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1553 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1554 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1555 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1556 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1557 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1558 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1559 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1560 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1561 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1562 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1563 g_test_add_func("/errors/multiple_values", multiple_values
);
1565 return g_test_run();