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/unicode.h"
24 #include "qemu-common.h"
26 static QString
*from_json_str(const char *jstr
, bool single
, Error
**errp
)
28 char quote
= single
? '\'' : '"';
29 char *qjstr
= g_strdup_printf("%c%s%c", quote
, jstr
, quote
);
30 QString
*ret
= qobject_to(QString
, qobject_from_json(qjstr
, errp
));
36 static char *to_json_str(QString
*str
)
38 QString
*json
= qobject_to_json(QOBJECT(str
));
44 /* peel off double quotes */
45 jstr
= g_strndup(qstring_get_str(json
) + 1,
46 qstring_get_length(json
) - 2);
51 static void escaped_string(void)
54 /* Content of JSON string to parse with qobject_from_json() */
56 /* Expected parse output; to unparse with qobject_to_json() */
60 { "\\b\\f\\n\\r\\t\\\\\\\"", "\b\f\n\r\t\\\"" },
61 { "\\/\\'", "/'", .skip
= 1 },
62 { "single byte utf-8 \\u0020", "single byte utf-8 ", .skip
= 1 },
63 { "double byte utf-8 \\u00A2", "double byte utf-8 \xc2\xa2" },
64 { "triple byte utf-8 \\u20AC", "triple byte utf-8 \xe2\x82\xac" },
65 { "quadruple byte utf-8 \\uD834\\uDD1E", /* U+1D11E */
66 /* bug: want \xF0\x9D\x84\x9E */
67 "quadruple byte utf-8 \xED\xA0\xB4\xED\xB4\x9E", .skip
= 1 },
74 { "\\u12345", "\341\210\2645" },
75 { "\\u0000x", "x", .skip
= 1}, /* bug: want \xC0\x80x */
76 { "unpaired leading surrogate \\uD800",
77 /* bug: not rejected */
78 "unpaired leading surrogate \355\240\200", .skip
= 1 },
79 { "unpaired leading surrogate \\uD800\\uCAFE",
80 /* bug: not rejected */
81 "unpaired leading surrogate \355\240\200\354\253\276", .skip
= 1 },
82 { "unpaired leading surrogate \\uD800\\uD801\\uDC02",
83 /* bug: not rejected */
84 "unpaired leading surrogate \355\240\200\355\240\201\355\260\202",
86 { "unpaired trailing surrogate \\uDC00",
87 /* bug: not rejected */
88 "unpaired trailing surrogate \355\260\200", .skip
= 1},
89 { "backward surrogate pair \\uDC00\\uD800",
90 /* bug: not rejected */
91 "backward surrogate pair \355\260\200\355\240\200", .skip
= 1},
92 { "noncharacter U+FDD0 \\uFDD0",
93 /* bug: not rejected */
94 "noncharacter U+FDD0 \xEF\xB7\x90", .skip
= 1},
95 { "noncharacter U+FDEF \\uFDEF",
96 /* bug: not rejected */
97 "noncharacter U+FDEF \xEF\xB7\xAF", .skip
= 1},
98 { "noncharacter U+1FFFE \\uD87F\\uDFFE",
99 /* bug: not rejected */
100 "noncharacter U+1FFFE \xED\xA1\xBF\xED\xBF\xBE", .skip
= 1},
101 { "noncharacter U+10FFFF \\uDC3F\\uDFFF",
102 /* bug: not rejected */
103 "noncharacter U+10FFFF \xED\xB0\xBF\xED\xBF\xBF", .skip
= 1},
110 for (i
= 0; test_cases
[i
].json_in
; i
++) {
111 for (j
= 0; j
< 2; j
++) {
112 if (test_cases
[i
].utf8_out
) {
113 cstr
= from_json_str(test_cases
[i
].json_in
, j
, &error_abort
);
114 g_assert_cmpstr(qstring_get_try_str(cstr
),
115 ==, test_cases
[i
].utf8_out
);
116 if (!test_cases
[i
].skip
) {
117 jstr
= to_json_str(cstr
);
118 g_assert_cmpstr(jstr
, ==, test_cases
[i
].json_in
);
123 cstr
= from_json_str(test_cases
[i
].json_in
, j
, NULL
);
130 static void string_with_quotes(void)
132 const char *test_cases
[] = {
133 "\"the bee's knees\"",
141 for (i
= 0; test_cases
[i
]; i
++) {
142 str
= qobject_to(QString
,
143 qobject_from_json(test_cases
[i
], &error_abort
));
145 cstr
= g_strndup(test_cases
[i
] + 1, strlen(test_cases
[i
]) - 2);
146 g_assert_cmpstr(qstring_get_str(str
), ==, cstr
);
152 static void utf8_string(void)
155 * FIXME Current behavior for invalid UTF-8 sequences is
156 * incorrect. This test expects current, incorrect results.
157 * They're all marked "bug:" below, and are to be replaced by
158 * correct ones as the bugs get fixed.
160 * The JSON parser rejects some invalid sequences, but accepts
161 * others without correcting the problem.
163 * We should either reject all invalid sequences, or minimize
164 * overlong sequences and replace all other invalid sequences by a
165 * suitable replacement character. A common choice for
166 * replacement is U+FFFD.
168 * Problem: we can't easily deal with embedded U+0000. Parsing
169 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
170 * which gets misinterpreted as NUL-terminated "this ". We should
171 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
174 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
175 * capability and stress test at
176 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
178 static const struct {
179 /* Content of JSON string to parse with qobject_from_json() */
181 /* Expected parse output */
182 const char *utf8_out
;
183 /* Expected unparse output, defaults to @json_in */
184 const char *json_out
;
187 * Bug markers used here:
188 * - bug: not corrected
189 * JSON parser fails to correct invalid sequence(s)
191 * JSON parser rejects invalid sequence(s)
192 * We may choose to define this as feature
195 /* 0 Control characters */
198 * Note: \x00 is impossible, other representations of
199 * U+0000 are covered under 4.3
201 "\x01\x02\x03\x04\x05\x06\x07"
202 "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
203 "\x10\x11\x12\x13\x14\x15\x16\x17"
204 "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
206 "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007"
207 "\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F"
208 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017"
209 "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F",
211 /* 1 Some correct UTF-8 text */
213 /* a bit of German */
214 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
215 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
216 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
217 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
218 "Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
219 " jeden gr\\u00F6\\u00DFeren Zwerg.",
223 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
224 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
225 "\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
227 /* 2 Boundary condition test cases */
228 /* 2.1 First possible sequence of a certain length */
230 * 2.1.1 1 byte U+0020
231 * Control characters are already covered by their own test
232 * case under 0. Test the first 1 byte non-control character
239 /* 2.1.2 2 bytes U+0080 */
245 /* 2.1.3 3 bytes U+0800 */
251 /* 2.1.4 4 bytes U+10000 */
257 /* 2.1.5 5 bytes U+200000 */
259 "\xF8\x88\x80\x80\x80",
260 NULL
, /* bug: rejected */
263 /* 2.1.6 6 bytes U+4000000 */
265 "\xFC\x84\x80\x80\x80\x80",
266 NULL
, /* bug: rejected */
269 /* 2.2 Last possible sequence of a certain length */
270 /* 2.2.1 1 byte U+007F */
276 /* 2.2.2 2 bytes U+07FF */
283 * 2.2.3 3 bytes U+FFFC
284 * The last possible sequence is actually U+FFFF. But that's
285 * a noncharacter, and already covered by its own test case
286 * under 5.3. Same for U+FFFE. U+FFFD is the last character
287 * in the BMP, and covered under 2.3. Because of U+FFFD's
288 * special role as replacement character, it's worth testing
296 /* 2.2.4 4 bytes U+1FFFFF */
299 NULL
, /* bug: rejected */
302 /* 2.2.5 5 bytes U+3FFFFFF */
304 "\xFB\xBF\xBF\xBF\xBF",
305 NULL
, /* bug: rejected */
308 /* 2.2.6 6 bytes U+7FFFFFFF */
310 "\xFD\xBF\xBF\xBF\xBF\xBF",
311 NULL
, /* bug: rejected */
314 /* 2.3 Other boundary conditions */
316 /* last one before surrogate range: U+D7FF */
322 /* first one after surrogate range: U+E000 */
328 /* last one in BMP: U+FFFD */
334 /* last one in last plane: U+10FFFD */
340 /* first one beyond Unicode range: U+110000 */
345 /* 3 Malformed sequences */
346 /* 3.1 Unexpected continuation bytes */
347 /* 3.1.1 First continuation byte */
350 "\x80", /* bug: not corrected */
353 /* 3.1.2 Last continuation byte */
356 "\xBF", /* bug: not corrected */
359 /* 3.1.3 2 continuation bytes */
362 "\x80\xBF", /* bug: not corrected */
365 /* 3.1.4 3 continuation bytes */
368 "\x80\xBF\x80", /* bug: not corrected */
369 "\\uFFFD\\uFFFD\\uFFFD",
371 /* 3.1.5 4 continuation bytes */
374 "\x80\xBF\x80\xBF", /* bug: not corrected */
375 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
377 /* 3.1.6 5 continuation bytes */
379 "\x80\xBF\x80\xBF\x80",
380 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
381 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
383 /* 3.1.7 6 continuation bytes */
385 "\x80\xBF\x80\xBF\x80\xBF",
386 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
387 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
389 /* 3.1.8 7 continuation bytes */
391 "\x80\xBF\x80\xBF\x80\xBF\x80",
392 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
393 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
395 /* 3.1.9 Sequence of all 64 possible continuation bytes */
397 "\x80\x81\x82\x83\x84\x85\x86\x87"
398 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
399 "\x90\x91\x92\x93\x94\x95\x96\x97"
400 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
401 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
402 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
403 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
404 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
405 /* bug: not corrected */
406 "\x80\x81\x82\x83\x84\x85\x86\x87"
407 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
408 "\x90\x91\x92\x93\x94\x95\x96\x97"
409 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
410 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
411 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
412 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
413 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
414 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
415 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
416 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
417 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
418 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
419 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
420 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
421 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
423 /* 3.2 Lonely start characters */
424 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
426 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
427 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
428 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
429 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
430 NULL
, /* bug: rejected (partly, see FIXME below) */
431 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
432 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
433 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
434 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
436 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
438 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
439 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
440 /* bug: not corrected */
441 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
442 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
443 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
444 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
446 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
448 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
449 NULL
, /* bug: rejected (partly, see FIXME below) */
450 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
452 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
454 "\xF8 \xF9 \xFA \xFB ",
455 NULL
, /* bug: rejected */
456 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
458 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
461 NULL
, /* bug: rejected */
464 /* 3.3 Sequences with last continuation byte missing */
465 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
468 NULL
, /* bug: rejected */
471 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
474 "\xE0\x80", /* bug: not corrected */
477 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
480 "\xF0\x80\x80", /* bug: not corrected */
483 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
486 NULL
, /* bug: rejected */
489 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
491 "\xFC\x80\x80\x80\x80",
492 NULL
, /* bug: rejected */
495 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
498 "\xDF", /* bug: not corrected */
501 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
504 "\xEF\xBF", /* bug: not corrected */
507 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
510 NULL
, /* bug: rejected */
513 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
516 NULL
, /* bug: rejected */
519 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
521 "\xFD\xBF\xBF\xBF\xBF",
522 NULL
, /* bug: rejected */
525 /* 3.4 Concatenation of incomplete sequences */
527 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
528 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
529 NULL
, /* bug: rejected (partly, see FIXME below) */
530 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
531 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
533 /* 3.5 Impossible bytes */
536 NULL
, /* bug: rejected */
541 NULL
, /* bug: rejected */
546 NULL
, /* bug: rejected */
547 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
549 /* 4 Overlong sequences */
550 /* 4.1 Overlong '/' */
553 NULL
, /* bug: rejected */
558 "\xE0\x80\xAF", /* bug: not corrected */
563 "\xF0\x80\x80\xAF", /* bug: not corrected */
567 "\xF8\x80\x80\x80\xAF",
568 NULL
, /* bug: rejected */
572 "\xFC\x80\x80\x80\x80\xAF",
573 NULL
, /* bug: rejected */
577 * 4.2 Maximum overlong sequences
578 * Highest Unicode value that is still resulting in an
579 * overlong sequence if represented with the given number of
580 * bytes. This is a boundary test for safe UTF-8 decoders.
585 NULL
, /* bug: rejected */
591 "\xE0\x9F\xBF", /* bug: not corrected */
597 * The actual maximum would be U+FFFF, but that's a
598 * noncharacter. Testing U+FFFC seems more useful. See
602 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
607 "\xF8\x87\xBF\xBF\xBF",
608 NULL
, /* bug: rejected */
613 "\xFC\x83\xBF\xBF\xBF\xBF",
614 NULL
, /* bug: rejected */
617 /* 4.3 Overlong representation of the NUL character */
621 NULL
, /* bug: rejected */
627 "\xE0\x80\x80", /* bug: not corrected */
633 "\xF0\x80\x80\x80", /* bug: not corrected */
638 "\xF8\x80\x80\x80\x80",
639 NULL
, /* bug: rejected */
644 "\xFC\x80\x80\x80\x80\x80",
645 NULL
, /* bug: rejected */
648 /* 5 Illegal code positions */
649 /* 5.1 Single UTF-16 surrogates */
653 "\xED\xA0\x80", /* bug: not corrected */
659 "\xED\xAD\xBF", /* bug: not corrected */
665 "\xED\xAE\x80", /* bug: not corrected */
671 "\xED\xAF\xBF", /* bug: not corrected */
677 "\xED\xB0\x80", /* bug: not corrected */
683 "\xED\xBE\x80", /* bug: not corrected */
689 "\xED\xBF\xBF", /* bug: not corrected */
692 /* 5.2 Paired UTF-16 surrogates */
695 "\xED\xA0\x80\xED\xB0\x80",
696 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
701 "\xED\xA0\x80\xED\xBF\xBF",
702 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
707 "\xED\xAD\xBF\xED\xB0\x80",
708 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
713 "\xED\xAD\xBF\xED\xBF\xBF",
714 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
719 "\xED\xAE\x80\xED\xB0\x80",
720 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
725 "\xED\xAE\x80\xED\xBF\xBF",
726 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
731 "\xED\xAF\xBF\xED\xB0\x80",
732 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
737 "\xED\xAF\xBF\xED\xBF\xBF",
738 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
741 /* 5.3 Other illegal code positions */
742 /* BMP noncharacters */
746 "\xEF\xBF\xBE", /* bug: not corrected */
752 "\xEF\xBF\xBF", /* bug: not corrected */
758 "\xEF\xB7\x90", /* bug: not corrected */
764 "\xEF\xB7\xAF", /* bug: not corrected */
767 /* Plane 1 .. 16 noncharacters */
769 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
770 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
771 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
772 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
773 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
774 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
775 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
776 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
777 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
778 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
779 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
780 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
781 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
782 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
783 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
784 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
785 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
786 /* bug: not corrected */
787 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
788 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
789 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
790 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
791 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
792 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
793 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
794 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
795 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
796 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
797 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
798 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
799 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
800 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
801 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
802 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
803 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
804 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
805 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
806 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
812 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
, *tail
;
813 char *end
, *in
, *jstr
;
815 for (i
= 0; test_cases
[i
].json_in
; i
++) {
816 for (j
= 0; j
< 2; j
++) {
817 json_in
= test_cases
[i
].json_in
;
818 utf8_out
= test_cases
[i
].utf8_out
;
819 utf8_in
= test_cases
[i
].utf8_out
?: test_cases
[i
].json_in
;
820 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
822 /* Parse @json_in, expect @utf8_out */
824 str
= from_json_str(json_in
, j
, &error_abort
);
825 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_out
);
828 str
= from_json_str(json_in
, j
, NULL
);
831 * Failure may be due to any sequence, but *all* sequences
832 * are expected to fail. Test each one in isolation.
834 for (tail
= json_in
; *tail
; tail
= end
) {
835 mod_utf8_codepoint(tail
, 6, &end
);
839 in
= strndup(tail
, end
- tail
);
840 str
= from_json_str(in
, j
, NULL
);
842 * FIXME JSON parser accepts invalid sequence
843 * starting with \xC2..\xF4
845 if (*in
>= '\xC2' && *in
<= '\xF4') {
854 /* Unparse @utf8_in, expect @json_out */
855 str
= qstring_from_str(utf8_in
);
856 jstr
= to_json_str(str
);
857 g_assert_cmpstr(jstr
, ==, json_out
);
862 * Parse @json_out right back
863 * Disabled, because qobject_from_json() is buggy, and I can't
864 * be bothered to add the expected incorrect results.
865 * FIXME Enable once these bugs have been fixed.
867 if (0 && json_out
!= json_in
) {
868 str
= from_json_str(json_out
, j
, &error_abort
);
869 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_out
);
875 static void simple_number(void)
887 { "-0", 0, .skip
= 1 },
891 for (i
= 0; test_cases
[i
].encoded
; i
++) {
895 qnum
= qobject_to(QNum
,
896 qobject_from_json(test_cases
[i
].encoded
,
899 g_assert(qnum_get_try_int(qnum
, &val
));
900 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
901 if (test_cases
[i
].skip
== 0) {
904 str
= qobject_to_json(QOBJECT(qnum
));
905 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
913 static void large_number(void)
915 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
916 const char *gtu64
= "18446744073709551616"; /* 2^64 */
917 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
923 qnum
= qobject_to(QNum
, qobject_from_json(maxu64
, &error_abort
));
925 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
926 g_assert(!qnum_get_try_int(qnum
, &ival
));
928 str
= qobject_to_json(QOBJECT(qnum
));
929 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
933 qnum
= qobject_to(QNum
, qobject_from_json(gtu64
, &error_abort
));
935 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
936 g_assert(!qnum_get_try_uint(qnum
, &val
));
937 g_assert(!qnum_get_try_int(qnum
, &ival
));
939 str
= qobject_to_json(QOBJECT(qnum
));
940 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
944 qnum
= qobject_to(QNum
, qobject_from_json(lti64
, &error_abort
));
946 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
947 g_assert(!qnum_get_try_uint(qnum
, &val
));
948 g_assert(!qnum_get_try_int(qnum
, &ival
));
950 str
= qobject_to_json(QOBJECT(qnum
));
951 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
956 static void float_number(void)
966 { "-32.12313", -32.12313 },
967 { "-32.20e-10", -32.20e-10, .skip
= 1 },
971 for (i
= 0; test_cases
[i
].encoded
; i
++) {
975 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
976 qnum
= qobject_to(QNum
, obj
);
978 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
980 if (test_cases
[i
].skip
== 0) {
983 str
= qobject_to_json(obj
);
984 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
992 static void keyword_literal(void)
999 obj
= qobject_from_json("true", &error_abort
);
1000 qbool
= qobject_to(QBool
, obj
);
1002 g_assert(qbool_get_bool(qbool
) == true);
1004 str
= qobject_to_json(obj
);
1005 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
1008 qobject_unref(qbool
);
1010 obj
= qobject_from_json("false", &error_abort
);
1011 qbool
= qobject_to(QBool
, obj
);
1013 g_assert(qbool_get_bool(qbool
) == false);
1015 str
= qobject_to_json(obj
);
1016 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
1019 qobject_unref(qbool
);
1021 obj
= qobject_from_json("null", &error_abort
);
1022 g_assert(obj
!= NULL
);
1023 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
1026 g_assert(QOBJECT(null
) == obj
);
1029 qobject_unref(null
);
1032 static void interpolation_valid(void)
1034 long long value_lld
= 0x123456789abcdefLL
;
1035 long value_ld
= (long)value_lld
;
1036 int value_d
= (int)value_lld
;
1037 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
1038 unsigned long value_lu
= (unsigned long)value_llu
;
1039 unsigned value_u
= (unsigned)value_llu
;
1040 double value_f
= 2.323423423;
1041 const char *value_s
= "hello world";
1042 QObject
*value_p
= QOBJECT(qnull());
1050 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
1052 g_assert(qbool_get_bool(qbool
) == false);
1053 qobject_unref(qbool
);
1055 /* Test that non-zero values other than 1 get collapsed to true */
1056 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
1058 g_assert(qbool_get_bool(qbool
) == true);
1059 qobject_unref(qbool
);
1063 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
1064 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
1065 qobject_unref(qnum
);
1067 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
1068 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
1069 qobject_unref(qnum
);
1071 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
1072 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
1073 qobject_unref(qnum
);
1075 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
1076 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
1077 qobject_unref(qnum
);
1079 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
1080 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1081 qobject_unref(qnum
);
1083 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1084 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1085 qobject_unref(qnum
);
1087 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1088 g_assert(qnum_get_double(qnum
) == value_f
);
1089 qobject_unref(qnum
);
1093 qstr
= qobject_to(QString
,
1094 qobject_from_jsonf_nofail("%s", value_s
));
1095 g_assert_cmpstr(qstring_get_try_str(qstr
), ==, value_s
);
1096 qobject_unref(qstr
);
1100 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1101 g_assert(qobj
== value_p
);
1104 static void interpolation_unknown(void)
1106 if (g_test_subprocess()) {
1107 qobject_from_jsonf_nofail("%x", 666);
1109 g_test_trap_subprocess(NULL
, 0, 0);
1110 g_test_trap_assert_failed();
1113 static void interpolation_string(void)
1115 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1121 /* Dangerous misfeature: % is silently ignored in strings */
1122 qobj
= qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1123 g_assert(qlit_equal_qobject(&decoded
, qobj
));
1124 qobject_unref(qobj
);
1127 static void simple_dict(void)
1131 const char *encoded
;
1135 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1136 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1137 { "foo", QLIT_QNUM(42) },
1138 { "bar", QLIT_QSTR("hello world") },
1143 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1147 .encoded
= "{\"foo\": 43}",
1148 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1149 { "foo", QLIT_QNUM(43) },
1156 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1160 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1161 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1163 str
= qobject_to_json(obj
);
1166 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1167 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1174 * this generates json of the form:
1175 * a(0,m) = [0, 1, ..., m-1]
1180 * 'key(n-1)': a(n-1,m)
1183 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1189 if (nest_level_max
== 0) {
1190 g_string_append(gstr
, "[");
1191 for (i
= 0; i
< elem_count
; i
++) {
1192 g_string_append_printf(gstr
, "%d", i
);
1193 if (i
< elem_count
- 1) {
1194 g_string_append_printf(gstr
, ", ");
1197 g_string_append(gstr
, "]");
1201 g_string_append(gstr
, "{");
1202 for (i
= 0; i
< nest_level_max
; i
++) {
1203 g_string_append_printf(gstr
, "'key%d': ", i
);
1204 gen_test_json(gstr
, i
, elem_count
);
1205 if (i
< nest_level_max
- 1) {
1206 g_string_append(gstr
, ",");
1209 g_string_append(gstr
, "}");
1212 static void large_dict(void)
1214 GString
*gstr
= g_string_new("");
1217 gen_test_json(gstr
, 10, 100);
1218 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1219 g_assert(obj
!= NULL
);
1222 g_string_free(gstr
, true);
1225 static void simple_list(void)
1229 const char *encoded
;
1233 .encoded
= "[43,42]",
1234 .decoded
= QLIT_QLIST(((QLitObject
[]){
1242 .decoded
= QLIT_QLIST(((QLitObject
[]){
1249 .decoded
= QLIT_QLIST(((QLitObject
[]){
1255 .decoded
= QLIT_QLIST(((QLitObject
[]){
1256 QLIT_QDICT(((QLitDictEntry
[]){
1265 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1269 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1270 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1272 str
= qobject_to_json(obj
);
1275 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1276 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1282 static void simple_whitespace(void)
1286 const char *encoded
;
1290 .encoded
= " [ 43 , 42 ]",
1291 .decoded
= QLIT_QLIST(((QLitObject
[]){
1298 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1299 .decoded
= QLIT_QLIST(((QLitObject
[]){
1301 QLIT_QDICT(((QLitDictEntry
[]){
1302 { "h", QLIT_QSTR("b") },
1304 QLIT_QLIST(((QLitObject
[]){
1311 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1312 .decoded
= QLIT_QLIST(((QLitObject
[]){
1314 QLIT_QDICT(((QLitDictEntry
[]){
1315 { "h", QLIT_QSTR("b") },
1316 { "a", QLIT_QNUM(32) },
1318 QLIT_QLIST(((QLitObject
[]){
1327 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1331 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1332 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1334 str
= qobject_to_json(obj
);
1337 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1338 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1345 static void simple_interpolation(void)
1347 QObject
*embedded_obj
;
1349 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1352 QLIT_QLIST(((QLitObject
[]){
1358 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1359 g_assert(embedded_obj
!= NULL
);
1361 obj
= qobject_from_jsonf_nofail("[%d, 2, %p]", 1, embedded_obj
);
1362 g_assert(qlit_equal_qobject(&decoded
, obj
));
1367 static void empty_input(void)
1369 QObject
*obj
= qobject_from_json("", &error_abort
);
1370 g_assert(obj
== NULL
);
1373 static void blank_input(void)
1375 QObject
*obj
= qobject_from_json("\n ", &error_abort
);
1376 g_assert(obj
== NULL
);
1379 static void junk_input(void)
1381 /* Note: junk within strings is covered elsewhere */
1385 obj
= qobject_from_json("@", &err
);
1386 g_assert(!err
); /* BUG */
1387 g_assert(obj
== NULL
);
1389 obj
= qobject_from_json("{\x01", &err
);
1390 g_assert(!err
); /* BUG */
1391 g_assert(obj
== NULL
);
1393 obj
= qobject_from_json("[0\xFF]", &err
);
1394 error_free_or_abort(&err
);
1395 g_assert(obj
== NULL
);
1397 obj
= qobject_from_json("00", &err
);
1398 g_assert(!err
); /* BUG */
1399 g_assert(obj
== NULL
);
1401 obj
= qobject_from_json("[1e", &err
);
1402 g_assert(!err
); /* BUG */
1403 g_assert(obj
== NULL
);
1405 obj
= qobject_from_json("truer", &err
);
1406 error_free_or_abort(&err
);
1407 g_assert(obj
== NULL
);
1410 static void unterminated_string(void)
1413 QObject
*obj
= qobject_from_json("\"abc", &err
);
1414 g_assert(!err
); /* BUG */
1415 g_assert(obj
== NULL
);
1418 static void unterminated_sq_string(void)
1421 QObject
*obj
= qobject_from_json("'abc", &err
);
1422 g_assert(!err
); /* BUG */
1423 g_assert(obj
== NULL
);
1426 static void unterminated_escape(void)
1429 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1430 g_assert(!err
); /* BUG */
1431 g_assert(obj
== NULL
);
1434 static void unterminated_array(void)
1437 QObject
*obj
= qobject_from_json("[32", &err
);
1438 g_assert(!err
); /* BUG */
1439 g_assert(obj
== NULL
);
1442 static void unterminated_array_comma(void)
1445 QObject
*obj
= qobject_from_json("[32,", &err
);
1446 g_assert(!err
); /* BUG */
1447 g_assert(obj
== NULL
);
1450 static void invalid_array_comma(void)
1453 QObject
*obj
= qobject_from_json("[32,}", &err
);
1454 error_free_or_abort(&err
);
1455 g_assert(obj
== NULL
);
1458 static void unterminated_dict(void)
1461 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1462 g_assert(!err
); /* BUG */
1463 g_assert(obj
== NULL
);
1466 static void unterminated_dict_comma(void)
1469 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1470 g_assert(!err
); /* BUG */
1471 g_assert(obj
== NULL
);
1474 static void invalid_dict_comma(void)
1477 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1478 error_free_or_abort(&err
);
1479 g_assert(obj
== NULL
);
1482 static void unterminated_literal(void)
1485 QObject
*obj
= qobject_from_json("nul", &err
);
1486 error_free_or_abort(&err
);
1487 g_assert(obj
== NULL
);
1490 static char *make_nest(char *buf
, size_t cnt
)
1492 memset(buf
, '[', cnt
- 1);
1495 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1500 static void limits_nesting(void)
1503 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1504 char buf
[2 * (max_nesting
+ 1) + 1];
1507 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1508 g_assert(obj
!= NULL
);
1511 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1512 error_free_or_abort(&err
);
1513 g_assert(obj
== NULL
);
1516 static void multiple_values(void)
1521 /* BUG this leaks the syntax tree for "false" */
1522 obj
= qobject_from_json("false true", &err
);
1523 g_assert(qbool_get_bool(qobject_to(QBool
, obj
)));
1527 /* BUG simultaneously succeeds and fails */
1528 /* BUG calls json_parser_parse() with errp pointing to non-null */
1529 obj
= qobject_from_json("} true", &err
);
1530 g_assert(qbool_get_bool(qobject_to(QBool
, obj
)));
1531 error_free_or_abort(&err
);
1535 int main(int argc
, char **argv
)
1537 g_test_init(&argc
, &argv
, NULL
);
1539 g_test_add_func("/literals/string/escaped", escaped_string
);
1540 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1541 g_test_add_func("/literals/string/utf8", utf8_string
);
1543 g_test_add_func("/literals/number/simple", simple_number
);
1544 g_test_add_func("/literals/number/large", large_number
);
1545 g_test_add_func("/literals/number/float", float_number
);
1547 g_test_add_func("/literals/keyword", keyword_literal
);
1549 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1550 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1551 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1553 g_test_add_func("/dicts/simple_dict", simple_dict
);
1554 g_test_add_func("/dicts/large_dict", large_dict
);
1555 g_test_add_func("/lists/simple_list", simple_list
);
1557 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1558 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1560 g_test_add_func("/errors/empty", empty_input
);
1561 g_test_add_func("/errors/blank", blank_input
);
1562 g_test_add_func("/errors/junk", junk_input
);
1563 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1564 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1565 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1566 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1567 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1568 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1569 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1570 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1571 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1572 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1573 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1574 g_test_add_func("/errors/multiple_values", multiple_values
);
1576 return g_test_run();