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 GString
*json
= qobject_to_json(QOBJECT(str
));
43 /* peel off double quotes */
44 g_string_truncate(json
, json
->len
- 1);
45 g_string_erase(json
, 0, 1);
46 return g_string_free(json
, false);
49 static void escaped_string(void)
52 /* Content of JSON string to parse with qobject_from_json() */
54 /* Expected parse output; to unparse with qobject_to_json() */
58 { "\\b\\f\\n\\r\\t\\\\\\\"", "\b\f\n\r\t\\\"" },
59 { "\\/\\'", "/'", .skip
= 1 },
60 { "single byte utf-8 \\u0020", "single byte utf-8 ", .skip
= 1 },
61 { "double byte utf-8 \\u00A2", "double byte utf-8 \xc2\xa2" },
62 { "triple byte utf-8 \\u20AC", "triple byte utf-8 \xe2\x82\xac" },
63 { "quadruple byte utf-8 \\uD834\\uDD1E", /* U+1D11E */
64 "quadruple byte utf-8 \xF0\x9D\x84\x9E" },
71 { "\\u12345", "\341\210\2645" },
72 { "\\u0000x", "\xC0\x80x" },
73 { "unpaired leading surrogate \\uD800", NULL
},
74 { "unpaired leading surrogate \\uD800\\uCAFE", NULL
},
75 { "unpaired leading surrogate \\uD800\\uD801\\uDC02", NULL
},
76 { "unpaired trailing surrogate \\uDC00", NULL
},
77 { "backward surrogate pair \\uDC00\\uD800", NULL
},
78 { "noncharacter U+FDD0 \\uFDD0", NULL
},
79 { "noncharacter U+FDEF \\uFDEF", NULL
},
80 { "noncharacter U+1FFFE \\uD87F\\uDFFE", NULL
},
81 { "noncharacter U+10FFFF \\uDC3F\\uDFFF", NULL
},
88 for (i
= 0; test_cases
[i
].json_in
; i
++) {
89 for (j
= 0; j
< 2; j
++) {
90 if (test_cases
[i
].utf8_out
) {
91 cstr
= from_json_str(test_cases
[i
].json_in
, j
, &error_abort
);
92 g_assert_cmpstr(qstring_get_str(cstr
),
93 ==, test_cases
[i
].utf8_out
);
94 if (!test_cases
[i
].skip
) {
95 jstr
= to_json_str(cstr
);
96 g_assert_cmpstr(jstr
, ==, test_cases
[i
].json_in
);
101 cstr
= from_json_str(test_cases
[i
].json_in
, j
, NULL
);
108 static void string_with_quotes(void)
110 const char *test_cases
[] = {
111 "\"the bee's knees\"",
119 for (i
= 0; test_cases
[i
]; i
++) {
120 str
= qobject_to(QString
,
121 qobject_from_json(test_cases
[i
], &error_abort
));
123 cstr
= g_strndup(test_cases
[i
] + 1, strlen(test_cases
[i
]) - 2);
124 g_assert_cmpstr(qstring_get_str(str
), ==, cstr
);
130 static void utf8_string(void)
133 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
134 * capability and stress test at
135 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
137 static const struct {
138 /* Content of JSON string to parse with qobject_from_json() */
140 /* Expected parse output */
141 const char *utf8_out
;
142 /* Expected unparse output, defaults to @json_in */
143 const char *json_out
;
145 /* 0 Control characters */
148 * Note: \x00 is impossible, other representations of
149 * U+0000 are covered under 4.3
151 "\x01\x02\x03\x04\x05\x06\x07"
152 "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
153 "\x10\x11\x12\x13\x14\x15\x16\x17"
154 "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
156 "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007"
157 "\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F"
158 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017"
159 "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F",
161 /* 1 Some correct UTF-8 text */
163 /* a bit of German */
164 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
165 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
166 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
167 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
168 "Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
169 " jeden gr\\u00F6\\u00DFeren Zwerg.",
173 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
174 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
175 "\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
177 /* '%' character when not interpolating */
182 /* 2 Boundary condition test cases */
183 /* 2.1 First possible sequence of a certain length */
185 * 2.1.1 1 byte U+0020
186 * Control characters are already covered by their own test
187 * case under 0. Test the first 1 byte non-control character
194 /* 2.1.2 2 bytes U+0080 */
200 /* 2.1.3 3 bytes U+0800 */
206 /* 2.1.4 4 bytes U+10000 */
212 /* 2.1.5 5 bytes U+200000 */
214 "\xF8\x88\x80\x80\x80",
218 /* 2.1.6 6 bytes U+4000000 */
220 "\xFC\x84\x80\x80\x80\x80",
224 /* 2.2 Last possible sequence of a certain length */
225 /* 2.2.1 1 byte U+007F */
231 /* 2.2.2 2 bytes U+07FF */
238 * 2.2.3 3 bytes U+FFFC
239 * The last possible sequence is actually U+FFFF. But that's
240 * a noncharacter, and already covered by its own test case
241 * under 5.3. Same for U+FFFE. U+FFFD is the last character
242 * in the BMP, and covered under 2.3. Because of U+FFFD's
243 * special role as replacement character, it's worth testing
251 /* 2.2.4 4 bytes U+1FFFFF */
257 /* 2.2.5 5 bytes U+3FFFFFF */
259 "\xFB\xBF\xBF\xBF\xBF",
263 /* 2.2.6 6 bytes U+7FFFFFFF */
265 "\xFD\xBF\xBF\xBF\xBF\xBF",
269 /* 2.3 Other boundary conditions */
271 /* last one before surrogate range: U+D7FF */
277 /* first one after surrogate range: U+E000 */
283 /* last one in BMP: U+FFFD */
289 /* last one in last plane: U+10FFFD */
295 /* first one beyond Unicode range: U+110000 */
300 /* 3 Malformed sequences */
301 /* 3.1 Unexpected continuation bytes */
302 /* 3.1.1 First continuation byte */
308 /* 3.1.2 Last continuation byte */
314 /* 3.1.3 2 continuation bytes */
320 /* 3.1.4 3 continuation bytes */
324 "\\uFFFD\\uFFFD\\uFFFD",
326 /* 3.1.5 4 continuation bytes */
330 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
332 /* 3.1.6 5 continuation bytes */
334 "\x80\xBF\x80\xBF\x80",
336 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
338 /* 3.1.7 6 continuation bytes */
340 "\x80\xBF\x80\xBF\x80\xBF",
342 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
344 /* 3.1.8 7 continuation bytes */
346 "\x80\xBF\x80\xBF\x80\xBF\x80",
348 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
350 /* 3.1.9 Sequence of all 64 possible continuation bytes */
352 "\x80\x81\x82\x83\x84\x85\x86\x87"
353 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
354 "\x90\x91\x92\x93\x94\x95\x96\x97"
355 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
356 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
357 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
358 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
359 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
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"
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",
370 /* 3.2 Lonely start characters */
371 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
373 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
374 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
375 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
376 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
378 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
379 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
380 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
381 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
383 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
385 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
386 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
388 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
389 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
391 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
393 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
395 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
397 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
399 "\xF8 \xF9 \xFA \xFB ",
401 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
403 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
409 /* 3.3 Sequences with last continuation byte missing */
410 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
416 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
422 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
428 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
434 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
436 "\xFC\x80\x80\x80\x80",
440 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
446 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
452 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
458 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
464 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
466 "\xFD\xBF\xBF\xBF\xBF",
470 /* 3.4 Concatenation of incomplete sequences */
472 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
473 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
475 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
476 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
478 /* 3.5 Impossible bytes */
492 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
494 /* 4 Overlong sequences */
495 /* 4.1 Overlong '/' */
512 "\xF8\x80\x80\x80\xAF",
517 "\xFC\x80\x80\x80\x80\xAF",
522 * 4.2 Maximum overlong sequences
523 * Highest Unicode value that is still resulting in an
524 * overlong sequence if represented with the given number of
525 * bytes. This is a boundary test for safe UTF-8 decoders.
542 * The actual maximum would be U+FFFF, but that's a
543 * noncharacter. Testing U+FFFC seems more useful. See
552 "\xF8\x87\xBF\xBF\xBF",
558 "\xFC\x83\xBF\xBF\xBF\xBF",
562 /* 4.3 Overlong representation of the NUL character */
583 "\xF8\x80\x80\x80\x80",
589 "\xFC\x80\x80\x80\x80\x80",
593 /* 5 Illegal code positions */
594 /* 5.1 Single UTF-16 surrogates */
637 /* 5.2 Paired UTF-16 surrogates */
640 "\xED\xA0\x80\xED\xB0\x80",
646 "\xED\xA0\x80\xED\xBF\xBF",
652 "\xED\xAD\xBF\xED\xB0\x80",
658 "\xED\xAD\xBF\xED\xBF\xBF",
664 "\xED\xAE\x80\xED\xB0\x80",
670 "\xED\xAE\x80\xED\xBF\xBF",
676 "\xED\xAF\xBF\xED\xB0\x80",
682 "\xED\xAF\xBF\xED\xBF\xBF",
686 /* 5.3 Other illegal code positions */
687 /* BMP noncharacters */
712 /* Plane 1 .. 16 noncharacters */
714 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
715 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
716 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
717 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
718 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
719 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
720 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
721 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
722 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
723 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
724 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
725 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
726 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
727 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
728 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
729 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
730 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
732 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
733 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
734 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
735 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
741 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
, *tail
;
742 char *end
, *in
, *jstr
;
744 for (i
= 0; test_cases
[i
].json_in
; i
++) {
745 for (j
= 0; j
< 2; j
++) {
746 json_in
= test_cases
[i
].json_in
;
747 utf8_out
= test_cases
[i
].utf8_out
;
748 utf8_in
= test_cases
[i
].utf8_out
?: test_cases
[i
].json_in
;
749 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
751 /* Parse @json_in, expect @utf8_out */
753 str
= from_json_str(json_in
, j
, &error_abort
);
754 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_out
);
757 str
= from_json_str(json_in
, j
, NULL
);
760 * Failure may be due to any sequence, but *all* sequences
761 * are expected to fail. Test each one in isolation.
763 for (tail
= json_in
; *tail
; tail
= end
) {
764 mod_utf8_codepoint(tail
, 6, &end
);
768 in
= g_strndup(tail
, end
- tail
);
769 str
= from_json_str(in
, j
, NULL
);
775 /* Unparse @utf8_in, expect @json_out */
776 str
= qstring_from_str(utf8_in
);
777 jstr
= to_json_str(str
);
778 g_assert_cmpstr(jstr
, ==, json_out
);
782 /* Parse @json_out right back, unless it has replacements */
783 if (!strstr(json_out
, "\\uFFFD")) {
784 str
= from_json_str(json_out
, j
, &error_abort
);
785 g_assert_cmpstr(qstring_get_str(str
), ==, utf8_in
);
792 static void int_number(void)
797 const char *reencoded
;
812 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
, &ival
));
818 g_assert_cmpint(ival
, ==, test_cases
[i
].decoded
);
819 if (test_cases
[i
].decoded
>= 0) {
820 g_assert(qnum_get_try_uint(qnum
, &uval
));
821 g_assert_cmpuint(uval
, ==, (uint64_t)test_cases
[i
].decoded
);
823 g_assert(!qnum_get_try_uint(qnum
, &uval
));
825 g_assert_cmpfloat(qnum_get_double(qnum
), ==,
826 (double)test_cases
[i
].decoded
);
828 str
= qobject_to_json(QOBJECT(qnum
));
829 g_assert_cmpstr(str
->str
, ==,
830 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
831 g_string_free(str
, true);
837 static void uint_number(void)
842 const char *reencoded
;
844 { "9223372036854775808", (uint64_t)1 << 63 },
845 { "18446744073709551615", UINT64_MAX
},
854 for (i
= 0; test_cases
[i
].encoded
; i
++) {
855 qnum
= qobject_to(QNum
,
856 qobject_from_json(test_cases
[i
].encoded
,
859 g_assert(qnum_get_try_uint(qnum
, &uval
));
860 g_assert_cmpuint(uval
, ==, test_cases
[i
].decoded
);
861 g_assert(!qnum_get_try_int(qnum
, &ival
));
862 g_assert_cmpfloat(qnum_get_double(qnum
), ==,
863 (double)test_cases
[i
].decoded
);
865 str
= qobject_to_json(QOBJECT(qnum
));
866 g_assert_cmpstr(str
->str
, ==,
867 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
868 g_string_free(str
, true);
874 static void float_number(void)
879 const char *reencoded
;
883 { "-32.12313", -32.12313, "-32.123130000000003" },
884 { "-32.20e-10", -32.20e-10, "-3.22e-09" },
885 { "18446744073709551616", 0x1p
64, "1.8446744073709552e+19" },
886 { "-9223372036854775809", -0x1p
63, "-9.2233720368547758e+18" },
895 for (i
= 0; test_cases
[i
].encoded
; i
++) {
896 qnum
= qobject_to(QNum
,
897 qobject_from_json(test_cases
[i
].encoded
,
900 g_assert_cmpfloat(qnum_get_double(qnum
), ==, test_cases
[i
].decoded
);
901 g_assert(!qnum_get_try_int(qnum
, &ival
));
902 g_assert(!qnum_get_try_uint(qnum
, &uval
));
904 str
= qobject_to_json(QOBJECT(qnum
));
905 g_assert_cmpstr(str
->str
, ==,
906 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
907 g_string_free(str
, true);
913 static void keyword_literal(void)
920 obj
= qobject_from_json("true", &error_abort
);
921 qbool
= qobject_to(QBool
, obj
);
923 g_assert(qbool_get_bool(qbool
) == true);
925 str
= qobject_to_json(obj
);
926 g_assert_cmpstr(str
->str
, ==, "true");
927 g_string_free(str
, true);
929 qobject_unref(qbool
);
931 obj
= qobject_from_json("false", &error_abort
);
932 qbool
= qobject_to(QBool
, obj
);
934 g_assert(qbool_get_bool(qbool
) == false);
936 str
= qobject_to_json(obj
);
937 g_assert_cmpstr(str
->str
, ==, "false");
938 g_string_free(str
, true);
940 qobject_unref(qbool
);
942 obj
= qobject_from_json("null", &error_abort
);
943 g_assert(obj
!= NULL
);
944 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
947 g_assert(QOBJECT(null
) == obj
);
953 static void interpolation_valid(void)
955 long long value_lld
= 0x123456789abcdefLL
;
956 int64_t value_d64
= value_lld
;
957 long value_ld
= (long)value_lld
;
958 int value_d
= (int)value_lld
;
959 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
960 uint64_t value_u64
= value_llu
;
961 unsigned long value_lu
= (unsigned long)value_llu
;
962 unsigned value_u
= (unsigned)value_llu
;
963 double value_f
= 2.323423423;
964 const char *value_s
= "hello world";
965 QObject
*value_p
= QOBJECT(qnull());
973 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
975 g_assert(qbool_get_bool(qbool
) == false);
976 qobject_unref(qbool
);
978 /* Test that non-zero values other than 1 get collapsed to true */
979 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
981 g_assert(qbool_get_bool(qbool
) == true);
982 qobject_unref(qbool
);
986 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
987 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
990 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
991 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
994 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
995 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
998 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRId64
, value_d64
));
999 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
1000 qobject_unref(qnum
);
1002 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
1003 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
1004 qobject_unref(qnum
);
1006 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
1007 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1008 qobject_unref(qnum
);
1010 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1011 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1012 qobject_unref(qnum
);
1014 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRIu64
, value_u64
));
1015 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1016 qobject_unref(qnum
);
1018 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1019 g_assert(qnum_get_double(qnum
) == value_f
);
1020 qobject_unref(qnum
);
1024 qstr
= qobject_to(QString
, qobject_from_jsonf_nofail("%s", value_s
));
1025 g_assert_cmpstr(qstring_get_str(qstr
), ==, value_s
);
1026 qobject_unref(qstr
);
1030 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1031 g_assert(qobj
== value_p
);
1034 static void interpolation_unknown(void)
1036 if (g_test_subprocess()) {
1037 qobject_from_jsonf_nofail("%x", 666);
1039 g_test_trap_subprocess(NULL
, 0, 0);
1040 g_test_trap_assert_failed();
1041 g_test_trap_assert_stderr("*Unexpected error*"
1042 "invalid interpolation '%x'*");
1045 static void interpolation_string(void)
1047 if (g_test_subprocess()) {
1048 qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1050 g_test_trap_subprocess(NULL
, 0, 0);
1051 g_test_trap_assert_failed();
1052 g_test_trap_assert_stderr("*Unexpected error*"
1053 "can't interpolate into string*");
1056 static void simple_dict(void)
1060 const char *encoded
;
1064 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1065 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1066 { "foo", QLIT_QNUM(42) },
1067 { "bar", QLIT_QSTR("hello world") },
1072 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1076 .encoded
= "{\"foo\": 43}",
1077 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1078 { "foo", QLIT_QNUM(43) },
1085 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1089 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1090 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1092 str
= qobject_to_json(obj
);
1095 obj
= qobject_from_json(str
->str
, &error_abort
);
1096 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1098 g_string_free(str
, true);
1103 * this generates json of the form:
1104 * a(0,m) = [0, 1, ..., m-1]
1109 * 'key(n-1)': a(n-1,m)
1112 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1118 if (nest_level_max
== 0) {
1119 g_string_append(gstr
, "[");
1120 for (i
= 0; i
< elem_count
; i
++) {
1121 g_string_append_printf(gstr
, "%d", i
);
1122 if (i
< elem_count
- 1) {
1123 g_string_append_printf(gstr
, ", ");
1126 g_string_append(gstr
, "]");
1130 g_string_append(gstr
, "{");
1131 for (i
= 0; i
< nest_level_max
; i
++) {
1132 g_string_append_printf(gstr
, "'key%d': ", i
);
1133 gen_test_json(gstr
, i
, elem_count
);
1134 if (i
< nest_level_max
- 1) {
1135 g_string_append(gstr
, ",");
1138 g_string_append(gstr
, "}");
1141 static void large_dict(void)
1143 GString
*gstr
= g_string_new("");
1146 gen_test_json(gstr
, 10, 100);
1147 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1148 g_assert(obj
!= NULL
);
1151 g_string_free(gstr
, true);
1154 static void simple_list(void)
1158 const char *encoded
;
1162 .encoded
= "[43,42]",
1163 .decoded
= QLIT_QLIST(((QLitObject
[]){
1171 .decoded
= QLIT_QLIST(((QLitObject
[]){
1178 .decoded
= QLIT_QLIST(((QLitObject
[]){
1184 .decoded
= QLIT_QLIST(((QLitObject
[]){
1185 QLIT_QDICT(((QLitDictEntry
[]){
1194 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1198 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1199 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1201 str
= qobject_to_json(obj
);
1204 obj
= qobject_from_json(str
->str
, &error_abort
);
1205 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1207 g_string_free(str
, true);
1211 static void simple_whitespace(void)
1215 const char *encoded
;
1219 .encoded
= " [ 43 , 42 ]",
1220 .decoded
= QLIT_QLIST(((QLitObject
[]){
1227 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1228 .decoded
= QLIT_QLIST(((QLitObject
[]){
1230 QLIT_QDICT(((QLitDictEntry
[]){
1231 { "h", QLIT_QSTR("b") },
1233 QLIT_QLIST(((QLitObject
[]){
1240 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1241 .decoded
= QLIT_QLIST(((QLitObject
[]){
1243 QLIT_QDICT(((QLitDictEntry
[]){
1244 { "h", QLIT_QSTR("b") },
1245 { "a", QLIT_QNUM(32) },
1247 QLIT_QLIST(((QLitObject
[]){
1256 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1260 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1261 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1263 str
= qobject_to_json(obj
);
1266 obj
= qobject_from_json(str
->str
, &error_abort
);
1267 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1270 g_string_free(str
, true);
1274 static void simple_interpolation(void)
1276 QObject
*embedded_obj
;
1278 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1281 QLIT_QLIST(((QLitObject
[]){
1287 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1288 g_assert(embedded_obj
!= NULL
);
1290 obj
= qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj
);
1291 g_assert(qlit_equal_qobject(&decoded
, obj
));
1296 static void empty_input(void)
1301 obj
= qobject_from_json("", &err
);
1302 error_free_or_abort(&err
);
1303 g_assert(obj
== NULL
);
1306 static void blank_input(void)
1311 obj
= qobject_from_json("\n ", &err
);
1312 error_free_or_abort(&err
);
1313 g_assert(obj
== NULL
);
1316 static void junk_input(void)
1318 /* Note: junk within strings is covered elsewhere */
1322 obj
= qobject_from_json("@", &err
);
1323 error_free_or_abort(&err
);
1324 g_assert(obj
== NULL
);
1326 obj
= qobject_from_json("{\x01", &err
);
1327 error_free_or_abort(&err
);
1328 g_assert(obj
== NULL
);
1330 obj
= qobject_from_json("[0\xFF]", &err
);
1331 error_free_or_abort(&err
);
1332 g_assert(obj
== NULL
);
1334 obj
= qobject_from_json("00", &err
);
1335 error_free_or_abort(&err
);
1336 g_assert(obj
== NULL
);
1338 obj
= qobject_from_json("[1e", &err
);
1339 error_free_or_abort(&err
);
1340 g_assert(obj
== NULL
);
1342 obj
= qobject_from_json("truer", &err
);
1343 error_free_or_abort(&err
);
1344 g_assert(obj
== NULL
);
1347 static void unterminated_string(void)
1350 QObject
*obj
= qobject_from_json("\"abc", &err
);
1351 error_free_or_abort(&err
);
1352 g_assert(obj
== NULL
);
1355 static void unterminated_sq_string(void)
1358 QObject
*obj
= qobject_from_json("'abc", &err
);
1359 error_free_or_abort(&err
);
1360 g_assert(obj
== NULL
);
1363 static void unterminated_escape(void)
1366 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1367 error_free_or_abort(&err
);
1368 g_assert(obj
== NULL
);
1371 static void unterminated_array(void)
1374 QObject
*obj
= qobject_from_json("[32", &err
);
1375 error_free_or_abort(&err
);
1376 g_assert(obj
== NULL
);
1379 static void unterminated_array_comma(void)
1382 QObject
*obj
= qobject_from_json("[32,", &err
);
1383 error_free_or_abort(&err
);
1384 g_assert(obj
== NULL
);
1387 static void invalid_array_comma(void)
1390 QObject
*obj
= qobject_from_json("[32,}", &err
);
1391 error_free_or_abort(&err
);
1392 g_assert(obj
== NULL
);
1395 static void unterminated_dict(void)
1398 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1399 error_free_or_abort(&err
);
1400 g_assert(obj
== NULL
);
1403 static void unterminated_dict_comma(void)
1406 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1407 error_free_or_abort(&err
);
1408 g_assert(obj
== NULL
);
1411 static void invalid_dict_comma(void)
1414 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1415 error_free_or_abort(&err
);
1416 g_assert(obj
== NULL
);
1419 static void invalid_dict_key(void)
1422 QObject
*obj
= qobject_from_json("{32:'abc'}", &err
);
1423 error_free_or_abort(&err
);
1424 g_assert(obj
== NULL
);
1427 static void unterminated_literal(void)
1430 QObject
*obj
= qobject_from_json("nul", &err
);
1431 error_free_or_abort(&err
);
1432 g_assert(obj
== NULL
);
1435 static char *make_nest(char *buf
, size_t cnt
)
1437 memset(buf
, '[', cnt
- 1);
1440 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1445 static void limits_nesting(void)
1448 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1449 char buf
[2 * (max_nesting
+ 1) + 1];
1452 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1453 g_assert(obj
!= NULL
);
1456 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1457 error_free_or_abort(&err
);
1458 g_assert(obj
== NULL
);
1461 static void multiple_values(void)
1466 obj
= qobject_from_json("false true", &err
);
1467 error_free_or_abort(&err
);
1468 g_assert(obj
== NULL
);
1470 obj
= qobject_from_json("} true", &err
);
1471 error_free_or_abort(&err
);
1472 g_assert(obj
== NULL
);
1475 int main(int argc
, char **argv
)
1477 g_test_init(&argc
, &argv
, NULL
);
1479 g_test_add_func("/literals/string/escaped", escaped_string
);
1480 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1481 g_test_add_func("/literals/string/utf8", utf8_string
);
1483 g_test_add_func("/literals/number/int", int_number
);
1484 g_test_add_func("/literals/number/uint", uint_number
);
1485 g_test_add_func("/literals/number/float", float_number
);
1487 g_test_add_func("/literals/keyword", keyword_literal
);
1489 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1490 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1491 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1493 g_test_add_func("/dicts/simple_dict", simple_dict
);
1494 g_test_add_func("/dicts/large_dict", large_dict
);
1495 g_test_add_func("/lists/simple_list", simple_list
);
1497 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1498 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1500 g_test_add_func("/errors/empty", empty_input
);
1501 g_test_add_func("/errors/blank", blank_input
);
1502 g_test_add_func("/errors/junk", junk_input
);
1503 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1504 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1505 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1506 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1507 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1508 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1509 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1510 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1511 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1512 g_test_add_func("/errors/invalid_dict_key", invalid_dict_key
);
1513 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1514 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1515 g_test_add_func("/errors/multiple_values", multiple_values
);
1517 return g_test_run();