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 /* '%' character when not interpolating */
184 /* 2 Boundary condition test cases */
185 /* 2.1 First possible sequence of a certain length */
187 * 2.1.1 1 byte U+0020
188 * Control characters are already covered by their own test
189 * case under 0. Test the first 1 byte non-control character
196 /* 2.1.2 2 bytes U+0080 */
202 /* 2.1.3 3 bytes U+0800 */
208 /* 2.1.4 4 bytes U+10000 */
214 /* 2.1.5 5 bytes U+200000 */
216 "\xF8\x88\x80\x80\x80",
220 /* 2.1.6 6 bytes U+4000000 */
222 "\xFC\x84\x80\x80\x80\x80",
226 /* 2.2 Last possible sequence of a certain length */
227 /* 2.2.1 1 byte U+007F */
233 /* 2.2.2 2 bytes U+07FF */
240 * 2.2.3 3 bytes U+FFFC
241 * The last possible sequence is actually U+FFFF. But that's
242 * a noncharacter, and already covered by its own test case
243 * under 5.3. Same for U+FFFE. U+FFFD is the last character
244 * in the BMP, and covered under 2.3. Because of U+FFFD's
245 * special role as replacement character, it's worth testing
253 /* 2.2.4 4 bytes U+1FFFFF */
259 /* 2.2.5 5 bytes U+3FFFFFF */
261 "\xFB\xBF\xBF\xBF\xBF",
265 /* 2.2.6 6 bytes U+7FFFFFFF */
267 "\xFD\xBF\xBF\xBF\xBF\xBF",
271 /* 2.3 Other boundary conditions */
273 /* last one before surrogate range: U+D7FF */
279 /* first one after surrogate range: U+E000 */
285 /* last one in BMP: U+FFFD */
291 /* last one in last plane: U+10FFFD */
297 /* first one beyond Unicode range: U+110000 */
302 /* 3 Malformed sequences */
303 /* 3.1 Unexpected continuation bytes */
304 /* 3.1.1 First continuation byte */
310 /* 3.1.2 Last continuation byte */
316 /* 3.1.3 2 continuation bytes */
322 /* 3.1.4 3 continuation bytes */
326 "\\uFFFD\\uFFFD\\uFFFD",
328 /* 3.1.5 4 continuation bytes */
332 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
334 /* 3.1.6 5 continuation bytes */
336 "\x80\xBF\x80\xBF\x80",
338 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
340 /* 3.1.7 6 continuation bytes */
342 "\x80\xBF\x80\xBF\x80\xBF",
344 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
346 /* 3.1.8 7 continuation bytes */
348 "\x80\xBF\x80\xBF\x80\xBF\x80",
350 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
352 /* 3.1.9 Sequence of all 64 possible continuation bytes */
354 "\x80\x81\x82\x83\x84\x85\x86\x87"
355 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
356 "\x90\x91\x92\x93\x94\x95\x96\x97"
357 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
358 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
359 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
360 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
361 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
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"
366 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
367 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
368 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
369 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
370 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
372 /* 3.2 Lonely start characters */
373 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
375 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
376 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
377 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
378 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
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 ",
385 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
387 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
388 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
390 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
391 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
393 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
395 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
397 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
399 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
401 "\xF8 \xF9 \xFA \xFB ",
403 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
405 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
411 /* 3.3 Sequences with last continuation byte missing */
412 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
418 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
424 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
430 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
436 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
438 "\xFC\x80\x80\x80\x80",
442 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
448 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
454 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
460 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
466 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
468 "\xFD\xBF\xBF\xBF\xBF",
472 /* 3.4 Concatenation of incomplete sequences */
474 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
475 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
477 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
478 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
480 /* 3.5 Impossible bytes */
494 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
496 /* 4 Overlong sequences */
497 /* 4.1 Overlong '/' */
514 "\xF8\x80\x80\x80\xAF",
519 "\xFC\x80\x80\x80\x80\xAF",
524 * 4.2 Maximum overlong sequences
525 * Highest Unicode value that is still resulting in an
526 * overlong sequence if represented with the given number of
527 * bytes. This is a boundary test for safe UTF-8 decoders.
544 * The actual maximum would be U+FFFF, but that's a
545 * noncharacter. Testing U+FFFC seems more useful. See
554 "\xF8\x87\xBF\xBF\xBF",
560 "\xFC\x83\xBF\xBF\xBF\xBF",
564 /* 4.3 Overlong representation of the NUL character */
585 "\xF8\x80\x80\x80\x80",
591 "\xFC\x80\x80\x80\x80\x80",
595 /* 5 Illegal code positions */
596 /* 5.1 Single UTF-16 surrogates */
639 /* 5.2 Paired UTF-16 surrogates */
642 "\xED\xA0\x80\xED\xB0\x80",
648 "\xED\xA0\x80\xED\xBF\xBF",
654 "\xED\xAD\xBF\xED\xB0\x80",
660 "\xED\xAD\xBF\xED\xBF\xBF",
666 "\xED\xAE\x80\xED\xB0\x80",
672 "\xED\xAE\x80\xED\xBF\xBF",
678 "\xED\xAF\xBF\xED\xB0\x80",
684 "\xED\xAF\xBF\xED\xBF\xBF",
688 /* 5.3 Other illegal code positions */
689 /* BMP noncharacters */
714 /* Plane 1 .. 16 noncharacters */
716 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
717 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
718 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
719 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
720 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
721 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
722 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
723 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
724 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
725 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
726 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
727 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
728 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
729 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
730 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
731 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
732 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
734 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
735 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
736 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
737 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
743 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
, *tail
;
744 char *end
, *in
, *jstr
;
746 for (i
= 0; test_cases
[i
].json_in
; i
++) {
747 for (j
= 0; j
< 2; j
++) {
748 json_in
= test_cases
[i
].json_in
;
749 utf8_out
= test_cases
[i
].utf8_out
;
750 utf8_in
= test_cases
[i
].utf8_out
?: test_cases
[i
].json_in
;
751 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
753 /* Parse @json_in, expect @utf8_out */
755 str
= from_json_str(json_in
, j
, &error_abort
);
756 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_out
);
759 str
= from_json_str(json_in
, j
, NULL
);
762 * Failure may be due to any sequence, but *all* sequences
763 * are expected to fail. Test each one in isolation.
765 for (tail
= json_in
; *tail
; tail
= end
) {
766 mod_utf8_codepoint(tail
, 6, &end
);
770 in
= g_strndup(tail
, end
- tail
);
771 str
= from_json_str(in
, j
, NULL
);
777 /* Unparse @utf8_in, expect @json_out */
778 str
= qstring_from_str(utf8_in
);
779 jstr
= to_json_str(str
);
780 g_assert_cmpstr(jstr
, ==, json_out
);
784 /* Parse @json_out right back, unless it has replacements */
785 if (!strstr(json_out
, "\\uFFFD")) {
786 str
= from_json_str(json_out
, j
, &error_abort
);
787 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_in
);
794 static void int_number(void)
799 const char *reencoded
;
814 for (i
= 0; test_cases
[i
].encoded
; i
++) {
815 qnum
= qobject_to(QNum
,
816 qobject_from_json(test_cases
[i
].encoded
,
819 g_assert(qnum_get_try_int(qnum
, &ival
));
820 g_assert_cmpint(ival
, ==, test_cases
[i
].decoded
);
821 if (test_cases
[i
].decoded
>= 0) {
822 g_assert(qnum_get_try_uint(qnum
, &uval
));
823 g_assert_cmpuint(uval
, ==, (uint64_t)test_cases
[i
].decoded
);
825 g_assert(!qnum_get_try_uint(qnum
, &uval
));
827 g_assert_cmpfloat(qnum_get_double(qnum
), ==,
828 (double)test_cases
[i
].decoded
);
830 str
= qobject_to_json(QOBJECT(qnum
));
831 g_assert_cmpstr(qstring_get_str(str
), ==,
832 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
839 static void uint_number(void)
844 const char *reencoded
;
846 { "9223372036854775808", (uint64_t)1 << 63 },
847 { "18446744073709551615", UINT64_MAX
},
856 for (i
= 0; test_cases
[i
].encoded
; i
++) {
857 qnum
= qobject_to(QNum
,
858 qobject_from_json(test_cases
[i
].encoded
,
861 g_assert(qnum_get_try_uint(qnum
, &uval
));
862 g_assert_cmpuint(uval
, ==, test_cases
[i
].decoded
);
863 g_assert(!qnum_get_try_int(qnum
, &ival
));
864 g_assert_cmpfloat(qnum_get_double(qnum
), ==,
865 (double)test_cases
[i
].decoded
);
867 str
= qobject_to_json(QOBJECT(qnum
));
868 g_assert_cmpstr(qstring_get_str(str
), ==,
869 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
876 static void float_number(void)
881 const char *reencoded
;
885 { "-32.12313", -32.12313, "-32.123130000000003" },
886 { "-32.20e-10", -32.20e-10, "-3.22e-09" },
887 { "18446744073709551616", 0x1p
64, "1.8446744073709552e+19" },
888 { "-9223372036854775809", -0x1p
63, "-9.2233720368547758e+18" },
897 for (i
= 0; test_cases
[i
].encoded
; i
++) {
898 qnum
= qobject_to(QNum
,
899 qobject_from_json(test_cases
[i
].encoded
,
902 g_assert_cmpfloat(qnum_get_double(qnum
), ==, test_cases
[i
].decoded
);
903 g_assert(!qnum_get_try_int(qnum
, &ival
));
904 g_assert(!qnum_get_try_uint(qnum
, &uval
));
906 str
= qobject_to_json(QOBJECT(qnum
));
907 g_assert_cmpstr(qstring_get_str(str
), ==,
908 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
915 static void keyword_literal(void)
922 obj
= qobject_from_json("true", &error_abort
);
923 qbool
= qobject_to(QBool
, obj
);
925 g_assert(qbool_get_bool(qbool
) == true);
927 str
= qobject_to_json(obj
);
928 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
931 qobject_unref(qbool
);
933 obj
= qobject_from_json("false", &error_abort
);
934 qbool
= qobject_to(QBool
, obj
);
936 g_assert(qbool_get_bool(qbool
) == false);
938 str
= qobject_to_json(obj
);
939 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
942 qobject_unref(qbool
);
944 obj
= qobject_from_json("null", &error_abort
);
945 g_assert(obj
!= NULL
);
946 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
949 g_assert(QOBJECT(null
) == obj
);
955 static void interpolation_valid(void)
957 long long value_lld
= 0x123456789abcdefLL
;
958 int64_t value_d64
= value_lld
;
959 long value_ld
= (long)value_lld
;
960 int value_d
= (int)value_lld
;
961 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
962 uint64_t value_u64
= value_llu
;
963 unsigned long value_lu
= (unsigned long)value_llu
;
964 unsigned value_u
= (unsigned)value_llu
;
965 double value_f
= 2.323423423;
966 const char *value_s
= "hello world";
967 QObject
*value_p
= QOBJECT(qnull());
975 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
977 g_assert(qbool_get_bool(qbool
) == false);
978 qobject_unref(qbool
);
980 /* Test that non-zero values other than 1 get collapsed to true */
981 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
983 g_assert(qbool_get_bool(qbool
) == true);
984 qobject_unref(qbool
);
988 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
989 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
992 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
993 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
996 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
997 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
1000 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRId64
, value_d64
));
1001 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
1002 qobject_unref(qnum
);
1004 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
1005 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
1006 qobject_unref(qnum
);
1008 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
1009 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1010 qobject_unref(qnum
);
1012 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1013 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1014 qobject_unref(qnum
);
1016 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRIu64
, value_u64
));
1017 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1018 qobject_unref(qnum
);
1020 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1021 g_assert(qnum_get_double(qnum
) == value_f
);
1022 qobject_unref(qnum
);
1026 qstr
= qobject_to(QString
,
1027 qobject_from_jsonf_nofail("%s", value_s
));
1028 g_assert_cmpstr(qstring_get_try_str(qstr
), ==, value_s
);
1029 qobject_unref(qstr
);
1033 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1034 g_assert(qobj
== value_p
);
1037 static void interpolation_unknown(void)
1039 if (g_test_subprocess()) {
1040 qobject_from_jsonf_nofail("%x", 666);
1042 g_test_trap_subprocess(NULL
, 0, 0);
1043 g_test_trap_assert_failed();
1044 g_test_trap_assert_stderr("*Unexpected error*"
1045 "invalid interpolation '%x'*");
1048 static void interpolation_string(void)
1050 if (g_test_subprocess()) {
1051 qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1053 g_test_trap_subprocess(NULL
, 0, 0);
1054 g_test_trap_assert_failed();
1055 g_test_trap_assert_stderr("*Unexpected error*"
1056 "can't interpolate into string*");
1059 static void simple_dict(void)
1063 const char *encoded
;
1067 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1068 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1069 { "foo", QLIT_QNUM(42) },
1070 { "bar", QLIT_QSTR("hello world") },
1075 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1079 .encoded
= "{\"foo\": 43}",
1080 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1081 { "foo", QLIT_QNUM(43) },
1088 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1092 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1093 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1095 str
= qobject_to_json(obj
);
1098 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1099 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1106 * this generates json of the form:
1107 * a(0,m) = [0, 1, ..., m-1]
1112 * 'key(n-1)': a(n-1,m)
1115 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1121 if (nest_level_max
== 0) {
1122 g_string_append(gstr
, "[");
1123 for (i
= 0; i
< elem_count
; i
++) {
1124 g_string_append_printf(gstr
, "%d", i
);
1125 if (i
< elem_count
- 1) {
1126 g_string_append_printf(gstr
, ", ");
1129 g_string_append(gstr
, "]");
1133 g_string_append(gstr
, "{");
1134 for (i
= 0; i
< nest_level_max
; i
++) {
1135 g_string_append_printf(gstr
, "'key%d': ", i
);
1136 gen_test_json(gstr
, i
, elem_count
);
1137 if (i
< nest_level_max
- 1) {
1138 g_string_append(gstr
, ",");
1141 g_string_append(gstr
, "}");
1144 static void large_dict(void)
1146 GString
*gstr
= g_string_new("");
1149 gen_test_json(gstr
, 10, 100);
1150 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1151 g_assert(obj
!= NULL
);
1154 g_string_free(gstr
, true);
1157 static void simple_list(void)
1161 const char *encoded
;
1165 .encoded
= "[43,42]",
1166 .decoded
= QLIT_QLIST(((QLitObject
[]){
1174 .decoded
= QLIT_QLIST(((QLitObject
[]){
1181 .decoded
= QLIT_QLIST(((QLitObject
[]){
1187 .decoded
= QLIT_QLIST(((QLitObject
[]){
1188 QLIT_QDICT(((QLitDictEntry
[]){
1197 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1201 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1202 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1204 str
= qobject_to_json(obj
);
1207 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1208 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1214 static void simple_whitespace(void)
1218 const char *encoded
;
1222 .encoded
= " [ 43 , 42 ]",
1223 .decoded
= QLIT_QLIST(((QLitObject
[]){
1230 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1231 .decoded
= QLIT_QLIST(((QLitObject
[]){
1233 QLIT_QDICT(((QLitDictEntry
[]){
1234 { "h", QLIT_QSTR("b") },
1236 QLIT_QLIST(((QLitObject
[]){
1243 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1244 .decoded
= QLIT_QLIST(((QLitObject
[]){
1246 QLIT_QDICT(((QLitDictEntry
[]){
1247 { "h", QLIT_QSTR("b") },
1248 { "a", QLIT_QNUM(32) },
1250 QLIT_QLIST(((QLitObject
[]){
1259 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1263 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1264 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1266 str
= qobject_to_json(obj
);
1269 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1270 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1277 static void simple_interpolation(void)
1279 QObject
*embedded_obj
;
1281 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1284 QLIT_QLIST(((QLitObject
[]){
1290 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1291 g_assert(embedded_obj
!= NULL
);
1293 obj
= qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj
);
1294 g_assert(qlit_equal_qobject(&decoded
, obj
));
1299 static void empty_input(void)
1304 obj
= qobject_from_json("", &err
);
1305 error_free_or_abort(&err
);
1306 g_assert(obj
== NULL
);
1309 static void blank_input(void)
1314 obj
= qobject_from_json("\n ", &err
);
1315 error_free_or_abort(&err
);
1316 g_assert(obj
== NULL
);
1319 static void junk_input(void)
1321 /* Note: junk within strings is covered elsewhere */
1325 obj
= qobject_from_json("@", &err
);
1326 error_free_or_abort(&err
);
1327 g_assert(obj
== NULL
);
1329 obj
= qobject_from_json("{\x01", &err
);
1330 error_free_or_abort(&err
);
1331 g_assert(obj
== NULL
);
1333 obj
= qobject_from_json("[0\xFF]", &err
);
1334 error_free_or_abort(&err
);
1335 g_assert(obj
== NULL
);
1337 obj
= qobject_from_json("00", &err
);
1338 error_free_or_abort(&err
);
1339 g_assert(obj
== NULL
);
1341 obj
= qobject_from_json("[1e", &err
);
1342 error_free_or_abort(&err
);
1343 g_assert(obj
== NULL
);
1345 obj
= qobject_from_json("truer", &err
);
1346 error_free_or_abort(&err
);
1347 g_assert(obj
== NULL
);
1350 static void unterminated_string(void)
1353 QObject
*obj
= qobject_from_json("\"abc", &err
);
1354 error_free_or_abort(&err
);
1355 g_assert(obj
== NULL
);
1358 static void unterminated_sq_string(void)
1361 QObject
*obj
= qobject_from_json("'abc", &err
);
1362 error_free_or_abort(&err
);
1363 g_assert(obj
== NULL
);
1366 static void unterminated_escape(void)
1369 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1370 error_free_or_abort(&err
);
1371 g_assert(obj
== NULL
);
1374 static void unterminated_array(void)
1377 QObject
*obj
= qobject_from_json("[32", &err
);
1378 error_free_or_abort(&err
);
1379 g_assert(obj
== NULL
);
1382 static void unterminated_array_comma(void)
1385 QObject
*obj
= qobject_from_json("[32,", &err
);
1386 error_free_or_abort(&err
);
1387 g_assert(obj
== NULL
);
1390 static void invalid_array_comma(void)
1393 QObject
*obj
= qobject_from_json("[32,}", &err
);
1394 error_free_or_abort(&err
);
1395 g_assert(obj
== NULL
);
1398 static void unterminated_dict(void)
1401 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1402 error_free_or_abort(&err
);
1403 g_assert(obj
== NULL
);
1406 static void unterminated_dict_comma(void)
1409 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1410 error_free_or_abort(&err
);
1411 g_assert(obj
== NULL
);
1414 static void invalid_dict_comma(void)
1417 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1418 error_free_or_abort(&err
);
1419 g_assert(obj
== NULL
);
1422 static void invalid_dict_key(void)
1425 QObject
*obj
= qobject_from_json("{32:'abc'}", &err
);
1426 error_free_or_abort(&err
);
1427 g_assert(obj
== NULL
);
1430 static void unterminated_literal(void)
1433 QObject
*obj
= qobject_from_json("nul", &err
);
1434 error_free_or_abort(&err
);
1435 g_assert(obj
== NULL
);
1438 static char *make_nest(char *buf
, size_t cnt
)
1440 memset(buf
, '[', cnt
- 1);
1443 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1448 static void limits_nesting(void)
1451 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1452 char buf
[2 * (max_nesting
+ 1) + 1];
1455 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1456 g_assert(obj
!= NULL
);
1459 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1460 error_free_or_abort(&err
);
1461 g_assert(obj
== NULL
);
1464 static void multiple_values(void)
1469 obj
= qobject_from_json("false true", &err
);
1470 error_free_or_abort(&err
);
1471 g_assert(obj
== NULL
);
1473 obj
= qobject_from_json("} true", &err
);
1474 error_free_or_abort(&err
);
1475 g_assert(obj
== NULL
);
1478 int main(int argc
, char **argv
)
1480 g_test_init(&argc
, &argv
, NULL
);
1482 g_test_add_func("/literals/string/escaped", escaped_string
);
1483 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1484 g_test_add_func("/literals/string/utf8", utf8_string
);
1486 g_test_add_func("/literals/number/int", int_number
);
1487 g_test_add_func("/literals/number/uint", uint_number
);
1488 g_test_add_func("/literals/number/float", float_number
);
1490 g_test_add_func("/literals/keyword", keyword_literal
);
1492 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1493 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1494 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1496 g_test_add_func("/dicts/simple_dict", simple_dict
);
1497 g_test_add_func("/dicts/large_dict", large_dict
);
1498 g_test_add_func("/lists/simple_list", simple_list
);
1500 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1501 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1503 g_test_add_func("/errors/empty", empty_input
);
1504 g_test_add_func("/errors/blank", blank_input
);
1505 g_test_add_func("/errors/junk", junk_input
);
1506 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1507 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1508 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1509 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1510 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1511 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1512 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1513 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1514 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1515 g_test_add_func("/errors/invalid_dict_key", invalid_dict_key
);
1516 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1517 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1518 g_test_add_func("/errors/multiple_values", multiple_values
);
1520 return g_test_run();