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/types.h"
18 #include "qapi/qmp/qjson.h"
19 #include "qapi/qmp/qlit.h"
20 #include "qemu-common.h"
22 static void escaped_string(void)
36 { "\"\\/\"", "/", .skip
= 1 },
39 { "\"hello world \\\"embedded string\\\"\"",
40 "hello world \"embedded string\"" },
41 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
42 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip
= 1 },
43 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
44 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
45 { "'\\b'", "\b", .skip
= 1 },
46 { "'\\f'", "\f", .skip
= 1 },
47 { "'\\n'", "\n", .skip
= 1 },
48 { "'\\r'", "\r", .skip
= 1 },
49 { "'\\t'", "\t", .skip
= 1 },
50 { "'\\/'", "/", .skip
= 1 },
51 { "'\\\\'", "\\", .skip
= 1 },
55 for (i
= 0; test_cases
[i
].encoded
; i
++) {
59 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
60 str
= qobject_to_qstring(obj
);
62 g_assert_cmpstr(qstring_get_str(str
), ==, test_cases
[i
].decoded
);
64 if (test_cases
[i
].skip
== 0) {
65 str
= qobject_to_json(obj
);
66 g_assert_cmpstr(qstring_get_str(str
), ==, test_cases
[i
].encoded
);
74 static void simple_string(void)
81 { "\"hello world\"", "hello world" },
82 { "\"the quick brown fox jumped over the fence\"",
83 "the quick brown fox jumped over the fence" },
87 for (i
= 0; test_cases
[i
].encoded
; i
++) {
91 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
92 str
= qobject_to_qstring(obj
);
94 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
96 str
= qobject_to_json(obj
);
97 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
105 static void single_quote_string(void)
112 { "'hello world'", "hello world" },
113 { "'the quick brown fox \\' jumped over the fence'",
114 "the quick brown fox ' jumped over the fence" },
118 for (i
= 0; test_cases
[i
].encoded
; i
++) {
122 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
123 str
= qobject_to_qstring(obj
);
125 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
131 static void utf8_string(void)
134 * FIXME Current behavior for invalid UTF-8 sequences is
135 * incorrect. This test expects current, incorrect results.
136 * They're all marked "bug:" below, and are to be replaced by
137 * correct ones as the bugs get fixed.
139 * The JSON parser rejects some invalid sequences, but accepts
140 * others without correcting the problem.
142 * We should either reject all invalid sequences, or minimize
143 * overlong sequences and replace all other invalid sequences by a
144 * suitable replacement character. A common choice for
145 * replacement is U+FFFD.
147 * Problem: we can't easily deal with embedded U+0000. Parsing
148 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
149 * which gets misinterpreted as NUL-terminated "this ". We should
150 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
153 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
154 * capability and stress test at
155 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
157 static const struct {
159 const char *utf8_out
;
160 const char *json_out
; /* defaults to @json_in */
161 const char *utf8_in
; /* defaults to @utf8_out */
164 * Bug markers used here:
165 * - bug: not corrected
166 * JSON parser fails to correct invalid sequence(s)
168 * JSON parser rejects invalid sequence(s)
169 * We may choose to define this as feature
171 * JSON parser produces incorrect result, this is the
172 * correct one, assuming replacement character U+FFFF
173 * We may choose to reject instead of replace
176 /* 1 Some correct UTF-8 text */
178 /* a bit of German */
179 "\"Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
180 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.\"",
181 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
182 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
183 "\"Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
184 " jeden gr\\u00F6\\u00DFeren Zwerg.\"",
188 "\"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5\"",
189 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
190 "\"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5\"",
192 /* 2 Boundary condition test cases */
193 /* 2.1 First possible sequence of a certain length */
194 /* 2.1.1 1 byte U+0000 */
197 "", /* bug: want overlong "\xC0\x80" */
201 /* 2.1.2 2 bytes U+0080 */
207 /* 2.1.3 3 bytes U+0800 */
213 /* 2.1.4 4 bytes U+10000 */
215 "\"\xF0\x90\x80\x80\"",
217 "\"\\uD800\\uDC00\"",
219 /* 2.1.5 5 bytes U+200000 */
221 "\"\xF8\x88\x80\x80\x80\"",
222 NULL
, /* bug: rejected */
224 "\xF8\x88\x80\x80\x80",
226 /* 2.1.6 6 bytes U+4000000 */
228 "\"\xFC\x84\x80\x80\x80\x80\"",
229 NULL
, /* bug: rejected */
231 "\xFC\x84\x80\x80\x80\x80",
233 /* 2.2 Last possible sequence of a certain length */
234 /* 2.2.1 1 byte U+007F */
240 /* 2.2.2 2 bytes U+07FF */
247 * 2.2.3 3 bytes U+FFFC
248 * The last possible sequence is actually U+FFFF. But that's
249 * a noncharacter, and already covered by its own test case
250 * under 5.3. Same for U+FFFE. U+FFFD is the last character
251 * in the BMP, and covered under 2.3. Because of U+FFFD's
252 * special role as replacement character, it's worth testing
260 /* 2.2.4 4 bytes U+1FFFFF */
262 "\"\xF7\xBF\xBF\xBF\"",
263 NULL
, /* bug: rejected */
267 /* 2.2.5 5 bytes U+3FFFFFF */
269 "\"\xFB\xBF\xBF\xBF\xBF\"",
270 NULL
, /* bug: rejected */
272 "\xFB\xBF\xBF\xBF\xBF",
274 /* 2.2.6 6 bytes U+7FFFFFFF */
276 "\"\xFD\xBF\xBF\xBF\xBF\xBF\"",
277 NULL
, /* bug: rejected */
279 "\xFD\xBF\xBF\xBF\xBF\xBF",
281 /* 2.3 Other boundary conditions */
283 /* last one before surrogate range: U+D7FF */
289 /* first one after surrogate range: U+E000 */
295 /* last one in BMP: U+FFFD */
301 /* last one in last plane: U+10FFFD */
302 "\"\xF4\x8F\xBF\xBD\"",
307 /* first one beyond Unicode range: U+110000 */
308 "\"\xF4\x90\x80\x80\"",
312 /* 3 Malformed sequences */
313 /* 3.1 Unexpected continuation bytes */
314 /* 3.1.1 First continuation byte */
317 "\x80", /* bug: not corrected */
320 /* 3.1.2 Last continuation byte */
323 "\xBF", /* bug: not corrected */
326 /* 3.1.3 2 continuation bytes */
329 "\x80\xBF", /* bug: not corrected */
330 "\"\\uFFFD\\uFFFD\"",
332 /* 3.1.4 3 continuation bytes */
335 "\x80\xBF\x80", /* bug: not corrected */
336 "\"\\uFFFD\\uFFFD\\uFFFD\"",
338 /* 3.1.5 4 continuation bytes */
340 "\"\x80\xBF\x80\xBF\"",
341 "\x80\xBF\x80\xBF", /* bug: not corrected */
342 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
344 /* 3.1.6 5 continuation bytes */
346 "\"\x80\xBF\x80\xBF\x80\"",
347 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
348 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
350 /* 3.1.7 6 continuation bytes */
352 "\"\x80\xBF\x80\xBF\x80\xBF\"",
353 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
354 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
356 /* 3.1.8 7 continuation bytes */
358 "\"\x80\xBF\x80\xBF\x80\xBF\x80\"",
359 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
360 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
362 /* 3.1.9 Sequence of all 64 possible continuation bytes */
364 "\"\x80\x81\x82\x83\x84\x85\x86\x87"
365 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
366 "\x90\x91\x92\x93\x94\x95\x96\x97"
367 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
368 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
369 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
370 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
371 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\"",
372 /* bug: not corrected */
373 "\x80\x81\x82\x83\x84\x85\x86\x87"
374 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
375 "\x90\x91\x92\x93\x94\x95\x96\x97"
376 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
377 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
378 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
379 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
380 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
381 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
382 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
383 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
384 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
385 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
386 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
387 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
388 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\""
390 /* 3.2 Lonely start characters */
391 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
393 "\"\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
394 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
395 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
396 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF \"",
397 NULL
, /* bug: rejected */
398 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
399 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
400 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
401 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
402 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
403 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
404 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
405 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
407 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
409 "\"\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
410 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF \"",
411 /* bug: not corrected */
412 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
413 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
414 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
415 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
417 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
419 "\"\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 \"",
420 NULL
, /* bug: rejected */
421 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
422 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
424 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
426 "\"\xF8 \xF9 \xFA \xFB \"",
427 NULL
, /* bug: rejected */
428 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
429 "\xF8 \xF9 \xFA \xFB ",
431 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
434 NULL
, /* bug: rejected */
435 "\"\\uFFFD \\uFFFD \"",
438 /* 3.3 Sequences with last continuation byte missing */
439 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
442 NULL
, /* bug: rejected */
446 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
449 "\xE0\x80", /* bug: not corrected */
452 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
455 "\xF0\x80\x80", /* bug: not corrected */
458 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
460 "\"\xF8\x80\x80\x80\"",
461 NULL
, /* bug: rejected */
465 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
467 "\"\xFC\x80\x80\x80\x80\"",
468 NULL
, /* bug: rejected */
470 "\xFC\x80\x80\x80\x80",
472 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
475 "\xDF", /* bug: not corrected */
478 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
481 "\xEF\xBF", /* bug: not corrected */
484 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
487 NULL
, /* bug: rejected */
491 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
493 "\"\xFB\xBF\xBF\xBF\"",
494 NULL
, /* bug: rejected */
498 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
500 "\"\xFD\xBF\xBF\xBF\xBF\"",
501 NULL
, /* bug: rejected */
503 "\xFD\xBF\xBF\xBF\xBF",
505 /* 3.4 Concatenation of incomplete sequences */
507 "\"\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
508 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF\"",
509 NULL
, /* bug: rejected */
510 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
511 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
512 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
513 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
515 /* 3.5 Impossible bytes */
518 NULL
, /* bug: rejected */
524 NULL
, /* bug: rejected */
529 "\"\xFE\xFE\xFF\xFF\"",
530 NULL
, /* bug: rejected */
531 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
534 /* 4 Overlong sequences */
535 /* 4.1 Overlong '/' */
538 NULL
, /* bug: rejected */
544 "\xE0\x80\xAF", /* bug: not corrected */
548 "\"\xF0\x80\x80\xAF\"",
549 "\xF0\x80\x80\xAF", /* bug: not corrected */
553 "\"\xF8\x80\x80\x80\xAF\"",
554 NULL
, /* bug: rejected */
556 "\xF8\x80\x80\x80\xAF",
559 "\"\xFC\x80\x80\x80\x80\xAF\"",
560 NULL
, /* bug: rejected */
562 "\xFC\x80\x80\x80\x80\xAF",
565 * 4.2 Maximum overlong sequences
566 * Highest Unicode value that is still resulting in an
567 * overlong sequence if represented with the given number of
568 * bytes. This is a boundary test for safe UTF-8 decoders.
573 NULL
, /* bug: rejected */
580 "\xE0\x9F\xBF", /* bug: not corrected */
586 * The actual maximum would be U+FFFF, but that's a
587 * noncharacter. Testing U+FFFC seems more useful. See
590 "\"\xF0\x8F\xBF\xBC\"",
591 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
596 "\"\xF8\x87\xBF\xBF\xBF\"",
597 NULL
, /* bug: rejected */
599 "\xF8\x87\xBF\xBF\xBF",
603 "\"\xFC\x83\xBF\xBF\xBF\xBF\"",
604 NULL
, /* bug: rejected */
606 "\xFC\x83\xBF\xBF\xBF\xBF",
608 /* 4.3 Overlong representation of the NUL character */
612 NULL
, /* bug: rejected */
619 "\xE0\x80\x80", /* bug: not corrected */
624 "\"\xF0\x80\x80\x80\"",
625 "\xF0\x80\x80\x80", /* bug: not corrected */
630 "\"\xF8\x80\x80\x80\x80\"",
631 NULL
, /* bug: rejected */
633 "\xF8\x80\x80\x80\x80",
637 "\"\xFC\x80\x80\x80\x80\x80\"",
638 NULL
, /* bug: rejected */
640 "\xFC\x80\x80\x80\x80\x80",
642 /* 5 Illegal code positions */
643 /* 5.1 Single UTF-16 surrogates */
647 "\xED\xA0\x80", /* bug: not corrected */
653 "\xED\xAD\xBF", /* bug: not corrected */
659 "\xED\xAE\x80", /* bug: not corrected */
665 "\xED\xAF\xBF", /* bug: not corrected */
671 "\xED\xB0\x80", /* bug: not corrected */
677 "\xED\xBE\x80", /* bug: not corrected */
683 "\xED\xBF\xBF", /* bug: not corrected */
686 /* 5.2 Paired UTF-16 surrogates */
689 "\"\xED\xA0\x80\xED\xB0\x80\"",
690 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
691 "\"\\uFFFD\\uFFFD\"",
695 "\"\xED\xA0\x80\xED\xBF\xBF\"",
696 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
697 "\"\\uFFFD\\uFFFD\"",
701 "\"\xED\xAD\xBF\xED\xB0\x80\"",
702 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
703 "\"\\uFFFD\\uFFFD\"",
707 "\"\xED\xAD\xBF\xED\xBF\xBF\"",
708 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
709 "\"\\uFFFD\\uFFFD\"",
713 "\"\xED\xAE\x80\xED\xB0\x80\"",
714 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
715 "\"\\uFFFD\\uFFFD\"",
719 "\"\xED\xAE\x80\xED\xBF\xBF\"",
720 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
721 "\"\\uFFFD\\uFFFD\"",
725 "\"\xED\xAF\xBF\xED\xB0\x80\"",
726 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
727 "\"\\uFFFD\\uFFFD\"",
731 "\"\xED\xAF\xBF\xED\xBF\xBF\"",
732 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
733 "\"\\uFFFD\\uFFFD\"",
735 /* 5.3 Other illegal code positions */
736 /* BMP noncharacters */
740 "\xEF\xBF\xBE", /* bug: not corrected */
746 "\xEF\xBF\xBF", /* bug: not corrected */
752 "\xEF\xB7\x90", /* bug: not corrected */
758 "\xEF\xB7\xAF", /* bug: not corrected */
761 /* Plane 1 .. 16 noncharacters */
763 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
764 "\"\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
765 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
766 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
767 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
768 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
769 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
770 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
771 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
772 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
773 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
774 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
775 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
776 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
777 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
778 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
779 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF\"",
780 /* bug: not corrected */
781 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
782 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
783 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
784 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
785 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
786 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
787 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
788 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
789 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
790 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
791 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
792 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
793 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
794 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
795 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
796 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
797 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
798 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
799 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
800 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
807 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
;
809 for (i
= 0; test_cases
[i
].json_in
; i
++) {
810 json_in
= test_cases
[i
].json_in
;
811 utf8_out
= test_cases
[i
].utf8_out
;
812 utf8_in
= test_cases
[i
].utf8_in
?: test_cases
[i
].utf8_out
;
813 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
815 obj
= qobject_from_json(json_in
, utf8_out
? &error_abort
: NULL
);
817 str
= qobject_to_qstring(obj
);
819 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
825 obj
= QOBJECT(qstring_from_str(utf8_in
));
826 str
= qobject_to_json(obj
);
829 g_assert_cmpstr(qstring_get_str(str
), ==, json_out
);
837 * Disabled, because qobject_from_json() is buggy, and I can't
838 * be bothered to add the expected incorrect results.
839 * FIXME Enable once these bugs have been fixed.
841 if (0 && json_out
!= json_in
) {
842 obj
= qobject_from_json(json_out
, &error_abort
);
843 str
= qobject_to_qstring(obj
);
845 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
850 static void vararg_string(void)
857 { "the quick brown fox jumped over the fence" },
861 for (i
= 0; test_cases
[i
].decoded
; i
++) {
864 str
= qobject_to_qstring(qobject_from_jsonf("%s",
865 test_cases
[i
].decoded
));
867 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
873 static void simple_number(void)
885 { "-0", 0, .skip
= 1 },
889 for (i
= 0; test_cases
[i
].encoded
; i
++) {
893 qnum
= qobject_to_qnum(qobject_from_json(test_cases
[i
].encoded
,
896 g_assert(qnum_get_try_int(qnum
, &val
));
897 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
898 if (test_cases
[i
].skip
== 0) {
901 str
= qobject_to_json(QOBJECT(qnum
));
902 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
910 static void large_number(void)
912 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
913 const char *gtu64
= "18446744073709551616"; /* 2^64 */
914 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
920 qnum
= qobject_to_qnum(qobject_from_json(maxu64
, &error_abort
));
922 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
923 g_assert(!qnum_get_try_int(qnum
, &ival
));
925 str
= qobject_to_json(QOBJECT(qnum
));
926 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
930 qnum
= qobject_to_qnum(qobject_from_json(gtu64
, &error_abort
));
932 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
933 g_assert(!qnum_get_try_uint(qnum
, &val
));
934 g_assert(!qnum_get_try_int(qnum
, &ival
));
936 str
= qobject_to_json(QOBJECT(qnum
));
937 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
941 qnum
= qobject_to_qnum(qobject_from_json(lti64
, &error_abort
));
943 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
944 g_assert(!qnum_get_try_uint(qnum
, &val
));
945 g_assert(!qnum_get_try_int(qnum
, &ival
));
947 str
= qobject_to_json(QOBJECT(qnum
));
948 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
953 static void float_number(void)
963 { "-32.12313", -32.12313 },
964 { "-32.20e-10", -32.20e-10, .skip
= 1 },
968 for (i
= 0; test_cases
[i
].encoded
; i
++) {
972 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
973 qnum
= qobject_to_qnum(obj
);
975 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
977 if (test_cases
[i
].skip
== 0) {
980 str
= qobject_to_json(obj
);
981 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
989 static void vararg_number(void)
993 long long value_ll
= 0x2342342343LL
;
994 double valuef
= 2.323423423;
997 qnum
= qobject_to_qnum(qobject_from_jsonf("%d", value
));
998 g_assert(qnum_get_try_int(qnum
, &val
));
999 g_assert_cmpint(val
, ==, value
);
1002 qnum
= qobject_to_qnum(qobject_from_jsonf("%lld", value_ll
));
1003 g_assert(qnum_get_try_int(qnum
, &val
));
1004 g_assert_cmpint(val
, ==, value_ll
);
1007 qnum
= qobject_to_qnum(qobject_from_jsonf("%f", valuef
));
1008 g_assert(qnum_get_double(qnum
) == valuef
);
1012 static void keyword_literal(void)
1019 obj
= qobject_from_json("true", &error_abort
);
1020 qbool
= qobject_to_qbool(obj
);
1022 g_assert(qbool_get_bool(qbool
) == true);
1024 str
= qobject_to_json(obj
);
1025 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
1030 obj
= qobject_from_json("false", &error_abort
);
1031 qbool
= qobject_to_qbool(obj
);
1033 g_assert(qbool_get_bool(qbool
) == false);
1035 str
= qobject_to_json(obj
);
1036 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
1041 qbool
= qobject_to_qbool(qobject_from_jsonf("%i", false));
1043 g_assert(qbool_get_bool(qbool
) == false);
1046 /* Test that non-zero values other than 1 get collapsed to true */
1047 qbool
= qobject_to_qbool(qobject_from_jsonf("%i", 2));
1049 g_assert(qbool_get_bool(qbool
) == true);
1052 obj
= qobject_from_json("null", &error_abort
);
1053 g_assert(obj
!= NULL
);
1054 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
1057 g_assert(QOBJECT(null
) == obj
);
1059 qobject_decref(obj
);
1063 static void simple_dict(void)
1067 const char *encoded
;
1071 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1072 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1073 { "foo", QLIT_QNUM(42) },
1074 { "bar", QLIT_QSTR("hello world") },
1079 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1083 .encoded
= "{\"foo\": 43}",
1084 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1085 { "foo", QLIT_QNUM(43) },
1092 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1096 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1097 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1099 str
= qobject_to_json(obj
);
1100 qobject_decref(obj
);
1102 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1103 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1104 qobject_decref(obj
);
1110 * this generates json of the form:
1111 * a(0,m) = [0, 1, ..., m-1]
1116 * 'key(n-1)': a(n-1,m)
1119 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1125 if (nest_level_max
== 0) {
1126 g_string_append(gstr
, "[");
1127 for (i
= 0; i
< elem_count
; i
++) {
1128 g_string_append_printf(gstr
, "%d", i
);
1129 if (i
< elem_count
- 1) {
1130 g_string_append_printf(gstr
, ", ");
1133 g_string_append(gstr
, "]");
1137 g_string_append(gstr
, "{");
1138 for (i
= 0; i
< nest_level_max
; i
++) {
1139 g_string_append_printf(gstr
, "'key%d': ", i
);
1140 gen_test_json(gstr
, i
, elem_count
);
1141 if (i
< nest_level_max
- 1) {
1142 g_string_append(gstr
, ",");
1145 g_string_append(gstr
, "}");
1148 static void large_dict(void)
1150 GString
*gstr
= g_string_new("");
1153 gen_test_json(gstr
, 10, 100);
1154 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1155 g_assert(obj
!= NULL
);
1157 qobject_decref(obj
);
1158 g_string_free(gstr
, true);
1161 static void simple_list(void)
1165 const char *encoded
;
1169 .encoded
= "[43,42]",
1170 .decoded
= QLIT_QLIST(((QLitObject
[]){
1178 .decoded
= QLIT_QLIST(((QLitObject
[]){
1185 .decoded
= QLIT_QLIST(((QLitObject
[]){
1191 .decoded
= QLIT_QLIST(((QLitObject
[]){
1192 QLIT_QDICT(((QLitDictEntry
[]){
1201 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1205 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1206 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1208 str
= qobject_to_json(obj
);
1209 qobject_decref(obj
);
1211 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1212 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1213 qobject_decref(obj
);
1218 static void simple_whitespace(void)
1222 const char *encoded
;
1226 .encoded
= " [ 43 , 42 ]",
1227 .decoded
= QLIT_QLIST(((QLitObject
[]){
1234 .encoded
= " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
1235 .decoded
= QLIT_QLIST(((QLitObject
[]){
1237 QLIT_QDICT(((QLitDictEntry
[]){
1238 { "h", QLIT_QSTR("b") },
1240 QLIT_QLIST(((QLitObject
[]){
1247 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1248 .decoded
= QLIT_QLIST(((QLitObject
[]){
1250 QLIT_QDICT(((QLitDictEntry
[]){
1251 { "h", QLIT_QSTR("b") },
1252 { "a", QLIT_QNUM(32) },
1254 QLIT_QLIST(((QLitObject
[]){
1263 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1267 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1268 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1270 str
= qobject_to_json(obj
);
1271 qobject_decref(obj
);
1273 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1274 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1276 qobject_decref(obj
);
1281 static void simple_varargs(void)
1283 QObject
*embedded_obj
;
1285 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1288 QLIT_QLIST(((QLitObject
[]){
1294 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1295 g_assert(embedded_obj
!= NULL
);
1297 obj
= qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj
);
1298 g_assert(qlit_equal_qobject(&decoded
, obj
));
1300 qobject_decref(obj
);
1303 static void empty_input(void)
1305 const char *empty
= "";
1306 QObject
*obj
= qobject_from_json(empty
, &error_abort
);
1307 g_assert(obj
== NULL
);
1310 static void unterminated_string(void)
1313 QObject
*obj
= qobject_from_json("\"abc", &err
);
1314 g_assert(!err
); /* BUG */
1315 g_assert(obj
== NULL
);
1318 static void unterminated_sq_string(void)
1321 QObject
*obj
= qobject_from_json("'abc", &err
);
1322 g_assert(!err
); /* BUG */
1323 g_assert(obj
== NULL
);
1326 static void unterminated_escape(void)
1329 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1330 g_assert(!err
); /* BUG */
1331 g_assert(obj
== NULL
);
1334 static void unterminated_array(void)
1337 QObject
*obj
= qobject_from_json("[32", &err
);
1338 g_assert(!err
); /* BUG */
1339 g_assert(obj
== NULL
);
1342 static void unterminated_array_comma(void)
1345 QObject
*obj
= qobject_from_json("[32,", &err
);
1346 g_assert(!err
); /* BUG */
1347 g_assert(obj
== NULL
);
1350 static void invalid_array_comma(void)
1353 QObject
*obj
= qobject_from_json("[32,}", &err
);
1354 error_free_or_abort(&err
);
1355 g_assert(obj
== NULL
);
1358 static void unterminated_dict(void)
1361 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1362 g_assert(!err
); /* BUG */
1363 g_assert(obj
== NULL
);
1366 static void unterminated_dict_comma(void)
1369 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1370 g_assert(!err
); /* BUG */
1371 g_assert(obj
== NULL
);
1374 static void invalid_dict_comma(void)
1377 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1378 error_free_or_abort(&err
);
1379 g_assert(obj
== NULL
);
1382 static void unterminated_literal(void)
1385 QObject
*obj
= qobject_from_json("nul", &err
);
1386 error_free_or_abort(&err
);
1387 g_assert(obj
== NULL
);
1390 static char *make_nest(char *buf
, size_t cnt
)
1392 memset(buf
, '[', cnt
- 1);
1395 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1400 static void limits_nesting(void)
1403 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1404 char buf
[2 * (max_nesting
+ 1) + 1];
1407 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1408 g_assert(obj
!= NULL
);
1409 qobject_decref(obj
);
1411 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1412 error_free_or_abort(&err
);
1413 g_assert(obj
== NULL
);
1416 int main(int argc
, char **argv
)
1418 g_test_init(&argc
, &argv
, NULL
);
1420 g_test_add_func("/literals/string/simple", simple_string
);
1421 g_test_add_func("/literals/string/escaped", escaped_string
);
1422 g_test_add_func("/literals/string/utf8", utf8_string
);
1423 g_test_add_func("/literals/string/single_quote", single_quote_string
);
1424 g_test_add_func("/literals/string/vararg", vararg_string
);
1426 g_test_add_func("/literals/number/simple", simple_number
);
1427 g_test_add_func("/literals/number/large", large_number
);
1428 g_test_add_func("/literals/number/float", float_number
);
1429 g_test_add_func("/literals/number/vararg", vararg_number
);
1431 g_test_add_func("/literals/keyword", keyword_literal
);
1433 g_test_add_func("/dicts/simple_dict", simple_dict
);
1434 g_test_add_func("/dicts/large_dict", large_dict
);
1435 g_test_add_func("/lists/simple_list", simple_list
);
1437 g_test_add_func("/whitespace/simple_whitespace", simple_whitespace
);
1439 g_test_add_func("/varargs/simple_varargs", simple_varargs
);
1441 g_test_add_func("/errors/empty_input", empty_input
);
1442 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1443 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1444 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1445 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1446 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1447 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1448 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1449 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1450 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1451 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1452 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1454 return g_test_run();