]>
git.proxmox.com Git - mirror_qemu.git/blob - tests/check-qjson.c
2 * Copyright IBM, Corp. 2009
3 * Copyright (c) 2013, 2015 Red Hat Inc.
6 * Anthony Liguori <aliguori@us.ibm.com>
7 * Markus Armbruster <armbru@redhat.com>
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include "qapi/error.h"
17 #include "qapi/qmp/qbool.h"
18 #include "qapi/qmp/qjson.h"
19 #include "qapi/qmp/qlit.h"
20 #include "qapi/qmp/qnull.h"
21 #include "qapi/qmp/qnum.h"
22 #include "qapi/qmp/qstring.h"
23 #include "qemu/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 "quadruple byte utf-8 \xF0\x9D\x84\x9E" },
73 { "\\u12345", "\341\210\2645" },
74 { "\\u0000x", "\xC0\x80x" },
75 { "unpaired leading surrogate \\uD800", NULL
},
76 { "unpaired leading surrogate \\uD800\\uCAFE", NULL
},
77 { "unpaired leading surrogate \\uD800\\uD801\\uDC02", NULL
},
78 { "unpaired trailing surrogate \\uDC00", NULL
},
79 { "backward surrogate pair \\uDC00\\uD800", NULL
},
80 { "noncharacter U+FDD0 \\uFDD0", NULL
},
81 { "noncharacter U+FDEF \\uFDEF", NULL
},
82 { "noncharacter U+1FFFE \\uD87F\\uDFFE", NULL
},
83 { "noncharacter U+10FFFF \\uDC3F\\uDFFF", NULL
},
90 for (i
= 0; test_cases
[i
].json_in
; i
++) {
91 for (j
= 0; j
< 2; j
++) {
92 if (test_cases
[i
].utf8_out
) {
93 cstr
= from_json_str(test_cases
[i
].json_in
, j
, &error_abort
);
94 g_assert_cmpstr(qstring_get_try_str(cstr
),
95 ==, test_cases
[i
].utf8_out
);
96 if (!test_cases
[i
].skip
) {
97 jstr
= to_json_str(cstr
);
98 g_assert_cmpstr(jstr
, ==, test_cases
[i
].json_in
);
103 cstr
= from_json_str(test_cases
[i
].json_in
, j
, NULL
);
110 static void string_with_quotes(void)
112 const char *test_cases
[] = {
113 "\"the bee's knees\"",
121 for (i
= 0; test_cases
[i
]; i
++) {
122 str
= qobject_to(QString
,
123 qobject_from_json(test_cases
[i
], &error_abort
));
125 cstr
= g_strndup(test_cases
[i
] + 1, strlen(test_cases
[i
]) - 2);
126 g_assert_cmpstr(qstring_get_str(str
), ==, cstr
);
132 static void utf8_string(void)
135 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
136 * capability and stress test at
137 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
139 static const struct {
140 /* Content of JSON string to parse with qobject_from_json() */
142 /* Expected parse output */
143 const char *utf8_out
;
144 /* Expected unparse output, defaults to @json_in */
145 const char *json_out
;
147 /* 0 Control characters */
150 * Note: \x00 is impossible, other representations of
151 * U+0000 are covered under 4.3
153 "\x01\x02\x03\x04\x05\x06\x07"
154 "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
155 "\x10\x11\x12\x13\x14\x15\x16\x17"
156 "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
158 "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007"
159 "\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F"
160 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017"
161 "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F",
163 /* 1 Some correct UTF-8 text */
165 /* a bit of German */
166 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
167 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
168 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
169 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
170 "Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
171 " jeden gr\\u00F6\\u00DFeren Zwerg.",
175 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
176 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
177 "\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
179 /* 2 Boundary condition test cases */
180 /* 2.1 First possible sequence of a certain length */
182 * 2.1.1 1 byte U+0020
183 * Control characters are already covered by their own test
184 * case under 0. Test the first 1 byte non-control character
191 /* 2.1.2 2 bytes U+0080 */
197 /* 2.1.3 3 bytes U+0800 */
203 /* 2.1.4 4 bytes U+10000 */
209 /* 2.1.5 5 bytes U+200000 */
211 "\xF8\x88\x80\x80\x80",
215 /* 2.1.6 6 bytes U+4000000 */
217 "\xFC\x84\x80\x80\x80\x80",
221 /* 2.2 Last possible sequence of a certain length */
222 /* 2.2.1 1 byte U+007F */
228 /* 2.2.2 2 bytes U+07FF */
235 * 2.2.3 3 bytes U+FFFC
236 * The last possible sequence is actually U+FFFF. But that's
237 * a noncharacter, and already covered by its own test case
238 * under 5.3. Same for U+FFFE. U+FFFD is the last character
239 * in the BMP, and covered under 2.3. Because of U+FFFD's
240 * special role as replacement character, it's worth testing
248 /* 2.2.4 4 bytes U+1FFFFF */
254 /* 2.2.5 5 bytes U+3FFFFFF */
256 "\xFB\xBF\xBF\xBF\xBF",
260 /* 2.2.6 6 bytes U+7FFFFFFF */
262 "\xFD\xBF\xBF\xBF\xBF\xBF",
266 /* 2.3 Other boundary conditions */
268 /* last one before surrogate range: U+D7FF */
274 /* first one after surrogate range: U+E000 */
280 /* last one in BMP: U+FFFD */
286 /* last one in last plane: U+10FFFD */
292 /* first one beyond Unicode range: U+110000 */
297 /* 3 Malformed sequences */
298 /* 3.1 Unexpected continuation bytes */
299 /* 3.1.1 First continuation byte */
305 /* 3.1.2 Last continuation byte */
311 /* 3.1.3 2 continuation bytes */
317 /* 3.1.4 3 continuation bytes */
321 "\\uFFFD\\uFFFD\\uFFFD",
323 /* 3.1.5 4 continuation bytes */
327 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
329 /* 3.1.6 5 continuation bytes */
331 "\x80\xBF\x80\xBF\x80",
333 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
335 /* 3.1.7 6 continuation bytes */
337 "\x80\xBF\x80\xBF\x80\xBF",
339 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
341 /* 3.1.8 7 continuation bytes */
343 "\x80\xBF\x80\xBF\x80\xBF\x80",
345 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
347 /* 3.1.9 Sequence of all 64 possible continuation bytes */
349 "\x80\x81\x82\x83\x84\x85\x86\x87"
350 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
351 "\x90\x91\x92\x93\x94\x95\x96\x97"
352 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
353 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
354 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
355 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
356 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
358 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
359 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
360 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
361 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
362 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
363 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
364 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
365 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
367 /* 3.2 Lonely start characters */
368 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
370 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
371 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
372 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
373 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
375 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
376 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
377 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
378 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
380 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
382 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
383 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
385 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
386 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
388 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
390 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
392 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
394 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
396 "\xF8 \xF9 \xFA \xFB ",
398 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
400 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
406 /* 3.3 Sequences with last continuation byte missing */
407 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
413 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
419 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
425 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
431 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
433 "\xFC\x80\x80\x80\x80",
437 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
443 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
449 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
455 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
461 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
463 "\xFD\xBF\xBF\xBF\xBF",
467 /* 3.4 Concatenation of incomplete sequences */
469 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
470 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
472 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
473 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
475 /* 3.5 Impossible bytes */
489 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
491 /* 4 Overlong sequences */
492 /* 4.1 Overlong '/' */
509 "\xF8\x80\x80\x80\xAF",
514 "\xFC\x80\x80\x80\x80\xAF",
519 * 4.2 Maximum overlong sequences
520 * Highest Unicode value that is still resulting in an
521 * overlong sequence if represented with the given number of
522 * bytes. This is a boundary test for safe UTF-8 decoders.
539 * The actual maximum would be U+FFFF, but that's a
540 * noncharacter. Testing U+FFFC seems more useful. See
549 "\xF8\x87\xBF\xBF\xBF",
555 "\xFC\x83\xBF\xBF\xBF\xBF",
559 /* 4.3 Overlong representation of the NUL character */
580 "\xF8\x80\x80\x80\x80",
586 "\xFC\x80\x80\x80\x80\x80",
590 /* 5 Illegal code positions */
591 /* 5.1 Single UTF-16 surrogates */
634 /* 5.2 Paired UTF-16 surrogates */
637 "\xED\xA0\x80\xED\xB0\x80",
643 "\xED\xA0\x80\xED\xBF\xBF",
649 "\xED\xAD\xBF\xED\xB0\x80",
655 "\xED\xAD\xBF\xED\xBF\xBF",
661 "\xED\xAE\x80\xED\xB0\x80",
667 "\xED\xAE\x80\xED\xBF\xBF",
673 "\xED\xAF\xBF\xED\xB0\x80",
679 "\xED\xAF\xBF\xED\xBF\xBF",
683 /* 5.3 Other illegal code positions */
684 /* BMP noncharacters */
709 /* Plane 1 .. 16 noncharacters */
711 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
712 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
713 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
714 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
715 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
716 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
717 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
718 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
719 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
720 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
721 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
722 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
723 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
724 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
725 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
726 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
727 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
729 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
730 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
731 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
732 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
738 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
, *tail
;
739 char *end
, *in
, *jstr
;
741 for (i
= 0; test_cases
[i
].json_in
; i
++) {
742 for (j
= 0; j
< 2; j
++) {
743 json_in
= test_cases
[i
].json_in
;
744 utf8_out
= test_cases
[i
].utf8_out
;
745 utf8_in
= test_cases
[i
].utf8_out
?: test_cases
[i
].json_in
;
746 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
748 /* Parse @json_in, expect @utf8_out */
750 str
= from_json_str(json_in
, j
, &error_abort
);
751 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_out
);
754 str
= from_json_str(json_in
, j
, NULL
);
757 * Failure may be due to any sequence, but *all* sequences
758 * are expected to fail. Test each one in isolation.
760 for (tail
= json_in
; *tail
; tail
= end
) {
761 mod_utf8_codepoint(tail
, 6, &end
);
765 in
= strndup(tail
, end
- tail
);
766 str
= from_json_str(in
, j
, NULL
);
772 /* Unparse @utf8_in, expect @json_out */
773 str
= qstring_from_str(utf8_in
);
774 jstr
= to_json_str(str
);
775 g_assert_cmpstr(jstr
, ==, json_out
);
780 * Parse @json_out right back
781 * Disabled, because qobject_from_json() is buggy, and I can't
782 * be bothered to add the expected incorrect results.
783 * FIXME Enable once these bugs have been fixed.
785 if (0 && json_out
!= json_in
) {
786 str
= from_json_str(json_out
, j
, &error_abort
);
787 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_out
);
793 static void simple_number(void)
805 { "-0", 0, .skip
= 1 },
809 for (i
= 0; test_cases
[i
].encoded
; i
++) {
813 qnum
= qobject_to(QNum
,
814 qobject_from_json(test_cases
[i
].encoded
,
817 g_assert(qnum_get_try_int(qnum
, &val
));
818 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
819 if (test_cases
[i
].skip
== 0) {
822 str
= qobject_to_json(QOBJECT(qnum
));
823 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
831 static void large_number(void)
833 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
834 const char *gtu64
= "18446744073709551616"; /* 2^64 */
835 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
841 qnum
= qobject_to(QNum
, qobject_from_json(maxu64
, &error_abort
));
843 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
844 g_assert(!qnum_get_try_int(qnum
, &ival
));
846 str
= qobject_to_json(QOBJECT(qnum
));
847 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
851 qnum
= qobject_to(QNum
, qobject_from_json(gtu64
, &error_abort
));
853 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
854 g_assert(!qnum_get_try_uint(qnum
, &val
));
855 g_assert(!qnum_get_try_int(qnum
, &ival
));
857 str
= qobject_to_json(QOBJECT(qnum
));
858 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
862 qnum
= qobject_to(QNum
, qobject_from_json(lti64
, &error_abort
));
864 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
865 g_assert(!qnum_get_try_uint(qnum
, &val
));
866 g_assert(!qnum_get_try_int(qnum
, &ival
));
868 str
= qobject_to_json(QOBJECT(qnum
));
869 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
874 static void float_number(void)
884 { "-32.12313", -32.12313 },
885 { "-32.20e-10", -32.20e-10, .skip
= 1 },
889 for (i
= 0; test_cases
[i
].encoded
; i
++) {
893 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
894 qnum
= qobject_to(QNum
, obj
);
896 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
898 if (test_cases
[i
].skip
== 0) {
901 str
= qobject_to_json(obj
);
902 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
910 static void keyword_literal(void)
917 obj
= qobject_from_json("true", &error_abort
);
918 qbool
= qobject_to(QBool
, obj
);
920 g_assert(qbool_get_bool(qbool
) == true);
922 str
= qobject_to_json(obj
);
923 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
926 qobject_unref(qbool
);
928 obj
= qobject_from_json("false", &error_abort
);
929 qbool
= qobject_to(QBool
, obj
);
931 g_assert(qbool_get_bool(qbool
) == false);
933 str
= qobject_to_json(obj
);
934 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
937 qobject_unref(qbool
);
939 obj
= qobject_from_json("null", &error_abort
);
940 g_assert(obj
!= NULL
);
941 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
944 g_assert(QOBJECT(null
) == obj
);
950 static void interpolation_valid(void)
952 long long value_lld
= 0x123456789abcdefLL
;
953 long value_ld
= (long)value_lld
;
954 int value_d
= (int)value_lld
;
955 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
956 unsigned long value_lu
= (unsigned long)value_llu
;
957 unsigned value_u
= (unsigned)value_llu
;
958 double value_f
= 2.323423423;
959 const char *value_s
= "hello world";
960 QObject
*value_p
= QOBJECT(qnull());
968 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
970 g_assert(qbool_get_bool(qbool
) == false);
971 qobject_unref(qbool
);
973 /* Test that non-zero values other than 1 get collapsed to true */
974 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
976 g_assert(qbool_get_bool(qbool
) == true);
977 qobject_unref(qbool
);
981 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
982 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
985 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
986 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
989 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
990 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
993 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
994 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
997 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
998 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1001 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1002 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1003 qobject_unref(qnum
);
1005 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1006 g_assert(qnum_get_double(qnum
) == value_f
);
1007 qobject_unref(qnum
);
1011 qstr
= qobject_to(QString
,
1012 qobject_from_jsonf_nofail("%s", value_s
));
1013 g_assert_cmpstr(qstring_get_try_str(qstr
), ==, value_s
);
1014 qobject_unref(qstr
);
1018 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1019 g_assert(qobj
== value_p
);
1022 static void interpolation_unknown(void)
1024 if (g_test_subprocess()) {
1025 qobject_from_jsonf_nofail("%x", 666);
1027 g_test_trap_subprocess(NULL
, 0, 0);
1028 g_test_trap_assert_failed();
1031 static void interpolation_string(void)
1033 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1039 /* Dangerous misfeature: % is silently ignored in strings */
1040 qobj
= qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1041 g_assert(qlit_equal_qobject(&decoded
, qobj
));
1042 qobject_unref(qobj
);
1045 static void simple_dict(void)
1049 const char *encoded
;
1053 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1054 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1055 { "foo", QLIT_QNUM(42) },
1056 { "bar", QLIT_QSTR("hello world") },
1061 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1065 .encoded
= "{\"foo\": 43}",
1066 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1067 { "foo", QLIT_QNUM(43) },
1074 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1078 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1079 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1081 str
= qobject_to_json(obj
);
1084 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1085 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1092 * this generates json of the form:
1093 * a(0,m) = [0, 1, ..., m-1]
1098 * 'key(n-1)': a(n-1,m)
1101 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1107 if (nest_level_max
== 0) {
1108 g_string_append(gstr
, "[");
1109 for (i
= 0; i
< elem_count
; i
++) {
1110 g_string_append_printf(gstr
, "%d", i
);
1111 if (i
< elem_count
- 1) {
1112 g_string_append_printf(gstr
, ", ");
1115 g_string_append(gstr
, "]");
1119 g_string_append(gstr
, "{");
1120 for (i
= 0; i
< nest_level_max
; i
++) {
1121 g_string_append_printf(gstr
, "'key%d': ", i
);
1122 gen_test_json(gstr
, i
, elem_count
);
1123 if (i
< nest_level_max
- 1) {
1124 g_string_append(gstr
, ",");
1127 g_string_append(gstr
, "}");
1130 static void large_dict(void)
1132 GString
*gstr
= g_string_new("");
1135 gen_test_json(gstr
, 10, 100);
1136 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1137 g_assert(obj
!= NULL
);
1140 g_string_free(gstr
, true);
1143 static void simple_list(void)
1147 const char *encoded
;
1151 .encoded
= "[43,42]",
1152 .decoded
= QLIT_QLIST(((QLitObject
[]){
1160 .decoded
= QLIT_QLIST(((QLitObject
[]){
1167 .decoded
= QLIT_QLIST(((QLitObject
[]){
1173 .decoded
= QLIT_QLIST(((QLitObject
[]){
1174 QLIT_QDICT(((QLitDictEntry
[]){
1183 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1187 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1188 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1190 str
= qobject_to_json(obj
);
1193 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1194 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1200 static void simple_whitespace(void)
1204 const char *encoded
;
1208 .encoded
= " [ 43 , 42 ]",
1209 .decoded
= QLIT_QLIST(((QLitObject
[]){
1216 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1217 .decoded
= QLIT_QLIST(((QLitObject
[]){
1219 QLIT_QDICT(((QLitDictEntry
[]){
1220 { "h", QLIT_QSTR("b") },
1222 QLIT_QLIST(((QLitObject
[]){
1229 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1230 .decoded
= QLIT_QLIST(((QLitObject
[]){
1232 QLIT_QDICT(((QLitDictEntry
[]){
1233 { "h", QLIT_QSTR("b") },
1234 { "a", QLIT_QNUM(32) },
1236 QLIT_QLIST(((QLitObject
[]){
1245 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1249 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1250 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1252 str
= qobject_to_json(obj
);
1255 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1256 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1263 static void simple_interpolation(void)
1265 QObject
*embedded_obj
;
1267 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1270 QLIT_QLIST(((QLitObject
[]){
1276 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1277 g_assert(embedded_obj
!= NULL
);
1279 obj
= qobject_from_jsonf_nofail("[%d, 2, %p]", 1, embedded_obj
);
1280 g_assert(qlit_equal_qobject(&decoded
, obj
));
1285 static void empty_input(void)
1287 QObject
*obj
= qobject_from_json("", &error_abort
);
1288 g_assert(obj
== NULL
);
1291 static void blank_input(void)
1293 QObject
*obj
= qobject_from_json("\n ", &error_abort
);
1294 g_assert(obj
== NULL
);
1297 static void junk_input(void)
1299 /* Note: junk within strings is covered elsewhere */
1303 obj
= qobject_from_json("@", &err
);
1304 g_assert(!err
); /* BUG */
1305 g_assert(obj
== NULL
);
1307 obj
= qobject_from_json("{\x01", &err
);
1308 g_assert(!err
); /* BUG */
1309 g_assert(obj
== NULL
);
1311 obj
= qobject_from_json("[0\xFF]", &err
);
1312 error_free_or_abort(&err
);
1313 g_assert(obj
== NULL
);
1315 obj
= qobject_from_json("00", &err
);
1316 g_assert(!err
); /* BUG */
1317 g_assert(obj
== NULL
);
1319 obj
= qobject_from_json("[1e", &err
);
1320 g_assert(!err
); /* BUG */
1321 g_assert(obj
== NULL
);
1323 obj
= qobject_from_json("truer", &err
);
1324 error_free_or_abort(&err
);
1325 g_assert(obj
== NULL
);
1328 static void unterminated_string(void)
1331 QObject
*obj
= qobject_from_json("\"abc", &err
);
1332 g_assert(!err
); /* BUG */
1333 g_assert(obj
== NULL
);
1336 static void unterminated_sq_string(void)
1339 QObject
*obj
= qobject_from_json("'abc", &err
);
1340 g_assert(!err
); /* BUG */
1341 g_assert(obj
== NULL
);
1344 static void unterminated_escape(void)
1347 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1348 g_assert(!err
); /* BUG */
1349 g_assert(obj
== NULL
);
1352 static void unterminated_array(void)
1355 QObject
*obj
= qobject_from_json("[32", &err
);
1356 g_assert(!err
); /* BUG */
1357 g_assert(obj
== NULL
);
1360 static void unterminated_array_comma(void)
1363 QObject
*obj
= qobject_from_json("[32,", &err
);
1364 g_assert(!err
); /* BUG */
1365 g_assert(obj
== NULL
);
1368 static void invalid_array_comma(void)
1371 QObject
*obj
= qobject_from_json("[32,}", &err
);
1372 error_free_or_abort(&err
);
1373 g_assert(obj
== NULL
);
1376 static void unterminated_dict(void)
1379 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1380 g_assert(!err
); /* BUG */
1381 g_assert(obj
== NULL
);
1384 static void unterminated_dict_comma(void)
1387 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1388 g_assert(!err
); /* BUG */
1389 g_assert(obj
== NULL
);
1392 static void invalid_dict_comma(void)
1395 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1396 error_free_or_abort(&err
);
1397 g_assert(obj
== NULL
);
1400 static void unterminated_literal(void)
1403 QObject
*obj
= qobject_from_json("nul", &err
);
1404 error_free_or_abort(&err
);
1405 g_assert(obj
== NULL
);
1408 static char *make_nest(char *buf
, size_t cnt
)
1410 memset(buf
, '[', cnt
- 1);
1413 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1418 static void limits_nesting(void)
1421 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1422 char buf
[2 * (max_nesting
+ 1) + 1];
1425 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1426 g_assert(obj
!= NULL
);
1429 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1430 error_free_or_abort(&err
);
1431 g_assert(obj
== NULL
);
1434 static void multiple_values(void)
1439 /* BUG this leaks the syntax tree for "false" */
1440 obj
= qobject_from_json("false true", &err
);
1441 g_assert(qbool_get_bool(qobject_to(QBool
, obj
)));
1445 /* BUG simultaneously succeeds and fails */
1446 /* BUG calls json_parser_parse() with errp pointing to non-null */
1447 obj
= qobject_from_json("} true", &err
);
1448 g_assert(qbool_get_bool(qobject_to(QBool
, obj
)));
1449 error_free_or_abort(&err
);
1453 int main(int argc
, char **argv
)
1455 g_test_init(&argc
, &argv
, NULL
);
1457 g_test_add_func("/literals/string/escaped", escaped_string
);
1458 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1459 g_test_add_func("/literals/string/utf8", utf8_string
);
1461 g_test_add_func("/literals/number/simple", simple_number
);
1462 g_test_add_func("/literals/number/large", large_number
);
1463 g_test_add_func("/literals/number/float", float_number
);
1465 g_test_add_func("/literals/keyword", keyword_literal
);
1467 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1468 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1469 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1471 g_test_add_func("/dicts/simple_dict", simple_dict
);
1472 g_test_add_func("/dicts/large_dict", large_dict
);
1473 g_test_add_func("/lists/simple_list", simple_list
);
1475 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1476 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1478 g_test_add_func("/errors/empty", empty_input
);
1479 g_test_add_func("/errors/blank", blank_input
);
1480 g_test_add_func("/errors/junk", junk_input
);
1481 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1482 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1483 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1484 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1485 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1486 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1487 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1488 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1489 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1490 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1491 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1492 g_test_add_func("/errors/multiple_values", multiple_values
);
1494 return g_test_run();