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 "qemu-common.h"
21 static void escaped_string(void)
35 { "\"\\/\"", "/", .skip
= 1 },
38 { "\"hello world \\\"embedded string\\\"\"",
39 "hello world \"embedded string\"" },
40 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
41 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip
= 1 },
42 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
43 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
44 { "'\\b'", "\b", .skip
= 1 },
45 { "'\\f'", "\f", .skip
= 1 },
46 { "'\\n'", "\n", .skip
= 1 },
47 { "'\\r'", "\r", .skip
= 1 },
48 { "'\\t'", "\t", .skip
= 1 },
49 { "'\\/'", "/", .skip
= 1 },
50 { "'\\\\'", "\\", .skip
= 1 },
54 for (i
= 0; test_cases
[i
].encoded
; i
++) {
58 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
59 str
= qobject_to_qstring(obj
);
61 g_assert_cmpstr(qstring_get_str(str
), ==, test_cases
[i
].decoded
);
63 if (test_cases
[i
].skip
== 0) {
64 str
= qobject_to_json(obj
);
65 g_assert_cmpstr(qstring_get_str(str
), ==, test_cases
[i
].encoded
);
73 static void simple_string(void)
80 { "\"hello world\"", "hello world" },
81 { "\"the quick brown fox jumped over the fence\"",
82 "the quick brown fox jumped over the fence" },
86 for (i
= 0; test_cases
[i
].encoded
; i
++) {
90 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
91 str
= qobject_to_qstring(obj
);
93 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
95 str
= qobject_to_json(obj
);
96 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
104 static void single_quote_string(void)
111 { "'hello world'", "hello world" },
112 { "'the quick brown fox \\' jumped over the fence'",
113 "the quick brown fox ' jumped over the fence" },
117 for (i
= 0; test_cases
[i
].encoded
; i
++) {
121 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
122 str
= qobject_to_qstring(obj
);
124 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
130 static void utf8_string(void)
133 * FIXME Current behavior for invalid UTF-8 sequences is
134 * incorrect. This test expects current, incorrect results.
135 * They're all marked "bug:" below, and are to be replaced by
136 * correct ones as the bugs get fixed.
138 * The JSON parser rejects some invalid sequences, but accepts
139 * others without correcting the problem.
141 * We should either reject all invalid sequences, or minimize
142 * overlong sequences and replace all other invalid sequences by a
143 * suitable replacement character. A common choice for
144 * replacement is U+FFFD.
146 * Problem: we can't easily deal with embedded U+0000. Parsing
147 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
148 * which gets misinterpreted as NUL-terminated "this ". We should
149 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
152 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
153 * capability and stress test at
154 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
156 static const struct {
158 const char *utf8_out
;
159 const char *json_out
; /* defaults to @json_in */
160 const char *utf8_in
; /* defaults to @utf8_out */
163 * Bug markers used here:
164 * - bug: not corrected
165 * JSON parser fails to correct invalid sequence(s)
167 * JSON parser rejects invalid sequence(s)
168 * We may choose to define this as feature
170 * JSON parser produces incorrect result, this is the
171 * correct one, assuming replacement character U+FFFF
172 * We may choose to reject instead of replace
175 /* 1 Some correct UTF-8 text */
177 /* a bit of German */
178 "\"Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
179 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.\"",
180 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
181 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
182 "\"Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
183 " jeden gr\\u00F6\\u00DFeren Zwerg.\"",
187 "\"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5\"",
188 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
189 "\"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5\"",
191 /* 2 Boundary condition test cases */
192 /* 2.1 First possible sequence of a certain length */
193 /* 2.1.1 1 byte U+0000 */
196 "", /* bug: want overlong "\xC0\x80" */
200 /* 2.1.2 2 bytes U+0080 */
206 /* 2.1.3 3 bytes U+0800 */
212 /* 2.1.4 4 bytes U+10000 */
214 "\"\xF0\x90\x80\x80\"",
216 "\"\\uD800\\uDC00\"",
218 /* 2.1.5 5 bytes U+200000 */
220 "\"\xF8\x88\x80\x80\x80\"",
221 NULL
, /* bug: rejected */
223 "\xF8\x88\x80\x80\x80",
225 /* 2.1.6 6 bytes U+4000000 */
227 "\"\xFC\x84\x80\x80\x80\x80\"",
228 NULL
, /* bug: rejected */
230 "\xFC\x84\x80\x80\x80\x80",
232 /* 2.2 Last possible sequence of a certain length */
233 /* 2.2.1 1 byte U+007F */
239 /* 2.2.2 2 bytes U+07FF */
246 * 2.2.3 3 bytes U+FFFC
247 * The last possible sequence is actually U+FFFF. But that's
248 * a noncharacter, and already covered by its own test case
249 * under 5.3. Same for U+FFFE. U+FFFD is the last character
250 * in the BMP, and covered under 2.3. Because of U+FFFD's
251 * special role as replacement character, it's worth testing
259 /* 2.2.4 4 bytes U+1FFFFF */
261 "\"\xF7\xBF\xBF\xBF\"",
262 NULL
, /* bug: rejected */
266 /* 2.2.5 5 bytes U+3FFFFFF */
268 "\"\xFB\xBF\xBF\xBF\xBF\"",
269 NULL
, /* bug: rejected */
271 "\xFB\xBF\xBF\xBF\xBF",
273 /* 2.2.6 6 bytes U+7FFFFFFF */
275 "\"\xFD\xBF\xBF\xBF\xBF\xBF\"",
276 NULL
, /* bug: rejected */
278 "\xFD\xBF\xBF\xBF\xBF\xBF",
280 /* 2.3 Other boundary conditions */
282 /* last one before surrogate range: U+D7FF */
288 /* first one after surrogate range: U+E000 */
294 /* last one in BMP: U+FFFD */
300 /* last one in last plane: U+10FFFD */
301 "\"\xF4\x8F\xBF\xBD\"",
306 /* first one beyond Unicode range: U+110000 */
307 "\"\xF4\x90\x80\x80\"",
311 /* 3 Malformed sequences */
312 /* 3.1 Unexpected continuation bytes */
313 /* 3.1.1 First continuation byte */
316 "\x80", /* bug: not corrected */
319 /* 3.1.2 Last continuation byte */
322 "\xBF", /* bug: not corrected */
325 /* 3.1.3 2 continuation bytes */
328 "\x80\xBF", /* bug: not corrected */
329 "\"\\uFFFD\\uFFFD\"",
331 /* 3.1.4 3 continuation bytes */
334 "\x80\xBF\x80", /* bug: not corrected */
335 "\"\\uFFFD\\uFFFD\\uFFFD\"",
337 /* 3.1.5 4 continuation bytes */
339 "\"\x80\xBF\x80\xBF\"",
340 "\x80\xBF\x80\xBF", /* bug: not corrected */
341 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
343 /* 3.1.6 5 continuation bytes */
345 "\"\x80\xBF\x80\xBF\x80\"",
346 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
347 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
349 /* 3.1.7 6 continuation bytes */
351 "\"\x80\xBF\x80\xBF\x80\xBF\"",
352 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
353 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
355 /* 3.1.8 7 continuation bytes */
357 "\"\x80\xBF\x80\xBF\x80\xBF\x80\"",
358 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
359 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
361 /* 3.1.9 Sequence of all 64 possible continuation bytes */
363 "\"\x80\x81\x82\x83\x84\x85\x86\x87"
364 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
365 "\x90\x91\x92\x93\x94\x95\x96\x97"
366 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
367 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
368 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
369 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
370 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\"",
371 /* bug: not corrected */
372 "\x80\x81\x82\x83\x84\x85\x86\x87"
373 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
374 "\x90\x91\x92\x93\x94\x95\x96\x97"
375 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
376 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
377 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
378 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
379 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
380 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
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\""
389 /* 3.2 Lonely start characters */
390 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
392 "\"\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
393 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
394 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
395 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF \"",
396 NULL
, /* bug: rejected */
397 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
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 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
402 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
403 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
404 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
406 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
408 "\"\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
409 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF \"",
410 /* bug: not corrected */
411 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
412 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
413 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
414 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
416 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
418 "\"\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 \"",
419 NULL
, /* bug: rejected */
420 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
421 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
423 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
425 "\"\xF8 \xF9 \xFA \xFB \"",
426 NULL
, /* bug: rejected */
427 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
428 "\xF8 \xF9 \xFA \xFB ",
430 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
433 NULL
, /* bug: rejected */
434 "\"\\uFFFD \\uFFFD \"",
437 /* 3.3 Sequences with last continuation byte missing */
438 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
441 NULL
, /* bug: rejected */
445 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
448 "\xE0\x80", /* bug: not corrected */
451 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
454 "\xF0\x80\x80", /* bug: not corrected */
457 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
459 "\"\xF8\x80\x80\x80\"",
460 NULL
, /* bug: rejected */
464 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
466 "\"\xFC\x80\x80\x80\x80\"",
467 NULL
, /* bug: rejected */
469 "\xFC\x80\x80\x80\x80",
471 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
474 "\xDF", /* bug: not corrected */
477 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
480 "\xEF\xBF", /* bug: not corrected */
483 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
486 NULL
, /* bug: rejected */
490 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
492 "\"\xFB\xBF\xBF\xBF\"",
493 NULL
, /* bug: rejected */
497 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
499 "\"\xFD\xBF\xBF\xBF\xBF\"",
500 NULL
, /* bug: rejected */
502 "\xFD\xBF\xBF\xBF\xBF",
504 /* 3.4 Concatenation of incomplete sequences */
506 "\"\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
507 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF\"",
508 NULL
, /* bug: rejected */
509 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
510 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
511 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
512 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
514 /* 3.5 Impossible bytes */
517 NULL
, /* bug: rejected */
523 NULL
, /* bug: rejected */
528 "\"\xFE\xFE\xFF\xFF\"",
529 NULL
, /* bug: rejected */
530 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
533 /* 4 Overlong sequences */
534 /* 4.1 Overlong '/' */
537 NULL
, /* bug: rejected */
543 "\xE0\x80\xAF", /* bug: not corrected */
547 "\"\xF0\x80\x80\xAF\"",
548 "\xF0\x80\x80\xAF", /* bug: not corrected */
552 "\"\xF8\x80\x80\x80\xAF\"",
553 NULL
, /* bug: rejected */
555 "\xF8\x80\x80\x80\xAF",
558 "\"\xFC\x80\x80\x80\x80\xAF\"",
559 NULL
, /* bug: rejected */
561 "\xFC\x80\x80\x80\x80\xAF",
564 * 4.2 Maximum overlong sequences
565 * Highest Unicode value that is still resulting in an
566 * overlong sequence if represented with the given number of
567 * bytes. This is a boundary test for safe UTF-8 decoders.
572 NULL
, /* bug: rejected */
579 "\xE0\x9F\xBF", /* bug: not corrected */
585 * The actual maximum would be U+FFFF, but that's a
586 * noncharacter. Testing U+FFFC seems more useful. See
589 "\"\xF0\x8F\xBF\xBC\"",
590 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
595 "\"\xF8\x87\xBF\xBF\xBF\"",
596 NULL
, /* bug: rejected */
598 "\xF8\x87\xBF\xBF\xBF",
602 "\"\xFC\x83\xBF\xBF\xBF\xBF\"",
603 NULL
, /* bug: rejected */
605 "\xFC\x83\xBF\xBF\xBF\xBF",
607 /* 4.3 Overlong representation of the NUL character */
611 NULL
, /* bug: rejected */
618 "\xE0\x80\x80", /* bug: not corrected */
623 "\"\xF0\x80\x80\x80\"",
624 "\xF0\x80\x80\x80", /* bug: not corrected */
629 "\"\xF8\x80\x80\x80\x80\"",
630 NULL
, /* bug: rejected */
632 "\xF8\x80\x80\x80\x80",
636 "\"\xFC\x80\x80\x80\x80\x80\"",
637 NULL
, /* bug: rejected */
639 "\xFC\x80\x80\x80\x80\x80",
641 /* 5 Illegal code positions */
642 /* 5.1 Single UTF-16 surrogates */
646 "\xED\xA0\x80", /* bug: not corrected */
652 "\xED\xAD\xBF", /* bug: not corrected */
658 "\xED\xAE\x80", /* bug: not corrected */
664 "\xED\xAF\xBF", /* bug: not corrected */
670 "\xED\xB0\x80", /* bug: not corrected */
676 "\xED\xBE\x80", /* bug: not corrected */
682 "\xED\xBF\xBF", /* bug: not corrected */
685 /* 5.2 Paired UTF-16 surrogates */
688 "\"\xED\xA0\x80\xED\xB0\x80\"",
689 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
690 "\"\\uFFFD\\uFFFD\"",
694 "\"\xED\xA0\x80\xED\xBF\xBF\"",
695 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
696 "\"\\uFFFD\\uFFFD\"",
700 "\"\xED\xAD\xBF\xED\xB0\x80\"",
701 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
702 "\"\\uFFFD\\uFFFD\"",
706 "\"\xED\xAD\xBF\xED\xBF\xBF\"",
707 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
708 "\"\\uFFFD\\uFFFD\"",
712 "\"\xED\xAE\x80\xED\xB0\x80\"",
713 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
714 "\"\\uFFFD\\uFFFD\"",
718 "\"\xED\xAE\x80\xED\xBF\xBF\"",
719 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
720 "\"\\uFFFD\\uFFFD\"",
724 "\"\xED\xAF\xBF\xED\xB0\x80\"",
725 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
726 "\"\\uFFFD\\uFFFD\"",
730 "\"\xED\xAF\xBF\xED\xBF\xBF\"",
731 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
732 "\"\\uFFFD\\uFFFD\"",
734 /* 5.3 Other illegal code positions */
735 /* BMP noncharacters */
739 "\xEF\xBF\xBE", /* bug: not corrected */
745 "\xEF\xBF\xBF", /* bug: not corrected */
751 "\xEF\xB7\x90", /* bug: not corrected */
757 "\xEF\xB7\xAF", /* bug: not corrected */
760 /* Plane 1 .. 16 noncharacters */
762 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
763 "\"\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
764 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
765 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
766 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
767 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
768 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
769 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
770 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
771 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
772 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
773 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
774 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
775 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
776 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
777 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
778 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF\"",
779 /* bug: not corrected */
780 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
781 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
782 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
783 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
784 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
785 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
786 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
787 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
788 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
789 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
790 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
791 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
792 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
793 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
794 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
795 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
796 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
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\"",
806 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
;
808 for (i
= 0; test_cases
[i
].json_in
; i
++) {
809 json_in
= test_cases
[i
].json_in
;
810 utf8_out
= test_cases
[i
].utf8_out
;
811 utf8_in
= test_cases
[i
].utf8_in
?: test_cases
[i
].utf8_out
;
812 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
814 obj
= qobject_from_json(json_in
, utf8_out
? &error_abort
: NULL
);
816 str
= qobject_to_qstring(obj
);
818 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
824 obj
= QOBJECT(qstring_from_str(utf8_in
));
825 str
= qobject_to_json(obj
);
828 g_assert_cmpstr(qstring_get_str(str
), ==, json_out
);
836 * Disabled, because qobject_from_json() is buggy, and I can't
837 * be bothered to add the expected incorrect results.
838 * FIXME Enable once these bugs have been fixed.
840 if (0 && json_out
!= json_in
) {
841 obj
= qobject_from_json(json_out
, &error_abort
);
842 str
= qobject_to_qstring(obj
);
844 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
849 static void vararg_string(void)
856 { "the quick brown fox jumped over the fence" },
860 for (i
= 0; test_cases
[i
].decoded
; i
++) {
863 str
= qobject_to_qstring(qobject_from_jsonf("%s",
864 test_cases
[i
].decoded
));
866 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].decoded
) == 0);
872 static void simple_number(void)
884 { "-0", 0, .skip
= 1 },
888 for (i
= 0; test_cases
[i
].encoded
; i
++) {
892 qnum
= qobject_to_qnum(qobject_from_json(test_cases
[i
].encoded
,
895 g_assert(qnum_get_try_int(qnum
, &val
));
896 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
897 if (test_cases
[i
].skip
== 0) {
900 str
= qobject_to_json(QOBJECT(qnum
));
901 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
909 static void large_number(void)
911 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
912 const char *gtu64
= "18446744073709551616"; /* 2^64 */
913 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
919 qnum
= qobject_to_qnum(qobject_from_json(maxu64
, &error_abort
));
921 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
922 g_assert(!qnum_get_try_int(qnum
, &ival
));
924 str
= qobject_to_json(QOBJECT(qnum
));
925 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
929 qnum
= qobject_to_qnum(qobject_from_json(gtu64
, &error_abort
));
931 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
932 g_assert(!qnum_get_try_uint(qnum
, &val
));
933 g_assert(!qnum_get_try_int(qnum
, &ival
));
935 str
= qobject_to_json(QOBJECT(qnum
));
936 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
940 qnum
= qobject_to_qnum(qobject_from_json(lti64
, &error_abort
));
942 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
943 g_assert(!qnum_get_try_uint(qnum
, &val
));
944 g_assert(!qnum_get_try_int(qnum
, &ival
));
946 str
= qobject_to_json(QOBJECT(qnum
));
947 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
952 static void float_number(void)
962 { "-32.12313", -32.12313 },
963 { "-32.20e-10", -32.20e-10, .skip
= 1 },
967 for (i
= 0; test_cases
[i
].encoded
; i
++) {
971 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
972 qnum
= qobject_to_qnum(obj
);
974 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
976 if (test_cases
[i
].skip
== 0) {
979 str
= qobject_to_json(obj
);
980 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
988 static void vararg_number(void)
992 long long value_ll
= 0x2342342343LL
;
993 double valuef
= 2.323423423;
996 qnum
= qobject_to_qnum(qobject_from_jsonf("%d", value
));
997 g_assert(qnum_get_try_int(qnum
, &val
));
998 g_assert_cmpint(val
, ==, value
);
1001 qnum
= qobject_to_qnum(qobject_from_jsonf("%lld", value_ll
));
1002 g_assert(qnum_get_try_int(qnum
, &val
));
1003 g_assert_cmpint(val
, ==, value_ll
);
1006 qnum
= qobject_to_qnum(qobject_from_jsonf("%f", valuef
));
1007 g_assert(qnum_get_double(qnum
) == valuef
);
1011 static void keyword_literal(void)
1018 obj
= qobject_from_json("true", &error_abort
);
1019 qbool
= qobject_to_qbool(obj
);
1021 g_assert(qbool_get_bool(qbool
) == true);
1023 str
= qobject_to_json(obj
);
1024 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
1029 obj
= qobject_from_json("false", &error_abort
);
1030 qbool
= qobject_to_qbool(obj
);
1032 g_assert(qbool_get_bool(qbool
) == false);
1034 str
= qobject_to_json(obj
);
1035 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
1040 qbool
= qobject_to_qbool(qobject_from_jsonf("%i", false));
1042 g_assert(qbool_get_bool(qbool
) == false);
1045 /* Test that non-zero values other than 1 get collapsed to true */
1046 qbool
= qobject_to_qbool(qobject_from_jsonf("%i", 2));
1048 g_assert(qbool_get_bool(qbool
) == true);
1051 obj
= qobject_from_json("null", &error_abort
);
1052 g_assert(obj
!= NULL
);
1053 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
1056 g_assert(null
== obj
);
1058 qobject_decref(obj
);
1059 qobject_decref(null
);
1062 typedef struct LiteralQDictEntry LiteralQDictEntry
;
1063 typedef struct LiteralQObject LiteralQObject
;
1065 struct LiteralQObject
1071 LiteralQDictEntry
*qdict
;
1072 LiteralQObject
*qlist
;
1076 struct LiteralQDictEntry
1079 LiteralQObject value
;
1082 #define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
1083 #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
1084 #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
1085 #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
1087 typedef struct QListCompareHelper
1090 LiteralQObject
*objs
;
1092 } QListCompareHelper
;
1094 static int compare_litqobj_to_qobj(LiteralQObject
*lhs
, QObject
*rhs
);
1096 static void compare_helper(QObject
*obj
, void *opaque
)
1098 QListCompareHelper
*helper
= opaque
;
1100 if (helper
->result
== 0) {
1104 if (helper
->objs
[helper
->index
].type
== QTYPE_NONE
) {
1109 helper
->result
= compare_litqobj_to_qobj(&helper
->objs
[helper
->index
++], obj
);
1112 static int compare_litqobj_to_qobj(LiteralQObject
*lhs
, QObject
*rhs
)
1116 if (!rhs
|| lhs
->type
!= qobject_type(rhs
)) {
1120 switch (lhs
->type
) {
1122 g_assert(qnum_get_try_int(qobject_to_qnum(rhs
), &val
));
1123 return lhs
->value
.qnum
== val
;
1125 return (strcmp(lhs
->value
.qstr
, qstring_get_str(qobject_to_qstring(rhs
))) == 0);
1129 for (i
= 0; lhs
->value
.qdict
[i
].key
; i
++) {
1130 QObject
*obj
= qdict_get(qobject_to_qdict(rhs
), lhs
->value
.qdict
[i
].key
);
1132 if (!compare_litqobj_to_qobj(&lhs
->value
.qdict
[i
].value
, obj
)) {
1140 QListCompareHelper helper
;
1143 helper
.objs
= lhs
->value
.qlist
;
1146 qlist_iter(qobject_to_qlist(rhs
), compare_helper
, &helper
);
1148 return helper
.result
;
1157 static void simple_dict(void)
1161 const char *encoded
;
1162 LiteralQObject decoded
;
1165 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1166 .decoded
= QLIT_QDICT(((LiteralQDictEntry
[]){
1167 { "foo", QLIT_QNUM(42) },
1168 { "bar", QLIT_QSTR("hello world") },
1173 .decoded
= QLIT_QDICT(((LiteralQDictEntry
[]){
1177 .encoded
= "{\"foo\": 43}",
1178 .decoded
= QLIT_QDICT(((LiteralQDictEntry
[]){
1179 { "foo", QLIT_QNUM(43) },
1186 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1190 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1191 g_assert(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
1193 str
= qobject_to_json(obj
);
1194 qobject_decref(obj
);
1196 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1197 g_assert(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
1198 qobject_decref(obj
);
1204 * this generates json of the form:
1205 * a(0,m) = [0, 1, ..., m-1]
1210 * 'key(n-1)': a(n-1,m)
1213 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1219 if (nest_level_max
== 0) {
1220 g_string_append(gstr
, "[");
1221 for (i
= 0; i
< elem_count
; i
++) {
1222 g_string_append_printf(gstr
, "%d", i
);
1223 if (i
< elem_count
- 1) {
1224 g_string_append_printf(gstr
, ", ");
1227 g_string_append(gstr
, "]");
1231 g_string_append(gstr
, "{");
1232 for (i
= 0; i
< nest_level_max
; i
++) {
1233 g_string_append_printf(gstr
, "'key%d': ", i
);
1234 gen_test_json(gstr
, i
, elem_count
);
1235 if (i
< nest_level_max
- 1) {
1236 g_string_append(gstr
, ",");
1239 g_string_append(gstr
, "}");
1242 static void large_dict(void)
1244 GString
*gstr
= g_string_new("");
1247 gen_test_json(gstr
, 10, 100);
1248 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1249 g_assert(obj
!= NULL
);
1251 qobject_decref(obj
);
1252 g_string_free(gstr
, true);
1255 static void simple_list(void)
1259 const char *encoded
;
1260 LiteralQObject decoded
;
1263 .encoded
= "[43,42]",
1264 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1272 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1279 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1285 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1286 QLIT_QDICT(((LiteralQDictEntry
[]){
1295 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1299 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1300 g_assert(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
1302 str
= qobject_to_json(obj
);
1303 qobject_decref(obj
);
1305 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1306 g_assert(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
1307 qobject_decref(obj
);
1312 static void simple_whitespace(void)
1316 const char *encoded
;
1317 LiteralQObject decoded
;
1320 .encoded
= " [ 43 , 42 ]",
1321 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1328 .encoded
= " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
1329 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1331 QLIT_QDICT(((LiteralQDictEntry
[]){
1332 { "h", QLIT_QSTR("b") },
1334 QLIT_QLIST(((LiteralQObject
[]){
1341 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1342 .decoded
= QLIT_QLIST(((LiteralQObject
[]){
1344 QLIT_QDICT(((LiteralQDictEntry
[]){
1345 { "h", QLIT_QSTR("b") },
1346 { "a", QLIT_QNUM(32) },
1348 QLIT_QLIST(((LiteralQObject
[]){
1357 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1361 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1362 g_assert(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
1364 str
= qobject_to_json(obj
);
1365 qobject_decref(obj
);
1367 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1368 g_assert(compare_litqobj_to_qobj(&test_cases
[i
].decoded
, obj
) == 1);
1370 qobject_decref(obj
);
1375 static void simple_varargs(void)
1377 QObject
*embedded_obj
;
1379 LiteralQObject decoded
= QLIT_QLIST(((LiteralQObject
[]){
1382 QLIT_QLIST(((LiteralQObject
[]){
1388 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1389 g_assert(embedded_obj
!= NULL
);
1391 obj
= qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj
);
1392 g_assert(compare_litqobj_to_qobj(&decoded
, obj
) == 1);
1394 qobject_decref(obj
);
1397 static void empty_input(void)
1399 const char *empty
= "";
1400 QObject
*obj
= qobject_from_json(empty
, &error_abort
);
1401 g_assert(obj
== NULL
);
1404 static void unterminated_string(void)
1407 QObject
*obj
= qobject_from_json("\"abc", &err
);
1408 g_assert(!err
); /* BUG */
1409 g_assert(obj
== NULL
);
1412 static void unterminated_sq_string(void)
1415 QObject
*obj
= qobject_from_json("'abc", &err
);
1416 g_assert(!err
); /* BUG */
1417 g_assert(obj
== NULL
);
1420 static void unterminated_escape(void)
1423 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1424 g_assert(!err
); /* BUG */
1425 g_assert(obj
== NULL
);
1428 static void unterminated_array(void)
1431 QObject
*obj
= qobject_from_json("[32", &err
);
1432 g_assert(!err
); /* BUG */
1433 g_assert(obj
== NULL
);
1436 static void unterminated_array_comma(void)
1439 QObject
*obj
= qobject_from_json("[32,", &err
);
1440 g_assert(!err
); /* BUG */
1441 g_assert(obj
== NULL
);
1444 static void invalid_array_comma(void)
1447 QObject
*obj
= qobject_from_json("[32,}", &err
);
1448 error_free_or_abort(&err
);
1449 g_assert(obj
== NULL
);
1452 static void unterminated_dict(void)
1455 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1456 g_assert(!err
); /* BUG */
1457 g_assert(obj
== NULL
);
1460 static void unterminated_dict_comma(void)
1463 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1464 g_assert(!err
); /* BUG */
1465 g_assert(obj
== NULL
);
1468 static void invalid_dict_comma(void)
1471 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1472 error_free_or_abort(&err
);
1473 g_assert(obj
== NULL
);
1476 static void unterminated_literal(void)
1479 QObject
*obj
= qobject_from_json("nul", &err
);
1480 error_free_or_abort(&err
);
1481 g_assert(obj
== NULL
);
1484 static char *make_nest(char *buf
, size_t cnt
)
1486 memset(buf
, '[', cnt
- 1);
1489 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1494 static void limits_nesting(void)
1497 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1498 char buf
[2 * (max_nesting
+ 1) + 1];
1501 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1502 g_assert(obj
!= NULL
);
1503 qobject_decref(obj
);
1505 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1506 error_free_or_abort(&err
);
1507 g_assert(obj
== NULL
);
1510 int main(int argc
, char **argv
)
1512 g_test_init(&argc
, &argv
, NULL
);
1514 g_test_add_func("/literals/string/simple", simple_string
);
1515 g_test_add_func("/literals/string/escaped", escaped_string
);
1516 g_test_add_func("/literals/string/utf8", utf8_string
);
1517 g_test_add_func("/literals/string/single_quote", single_quote_string
);
1518 g_test_add_func("/literals/string/vararg", vararg_string
);
1520 g_test_add_func("/literals/number/simple", simple_number
);
1521 g_test_add_func("/literals/number/large", large_number
);
1522 g_test_add_func("/literals/number/float", float_number
);
1523 g_test_add_func("/literals/number/vararg", vararg_number
);
1525 g_test_add_func("/literals/keyword", keyword_literal
);
1527 g_test_add_func("/dicts/simple_dict", simple_dict
);
1528 g_test_add_func("/dicts/large_dict", large_dict
);
1529 g_test_add_func("/lists/simple_list", simple_list
);
1531 g_test_add_func("/whitespace/simple_whitespace", simple_whitespace
);
1533 g_test_add_func("/varargs/simple_varargs", simple_varargs
);
1535 g_test_add_func("/errors/empty_input", empty_input
);
1536 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1537 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1538 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1539 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1540 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1541 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1542 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1543 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1544 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1545 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1546 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1548 return g_test_run();