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 simple_number(void)
799 const char *reencoded
;
813 for (i
= 0; test_cases
[i
].encoded
; i
++) {
814 qnum
= qobject_to(QNum
,
815 qobject_from_json(test_cases
[i
].encoded
,
818 g_assert(qnum_get_try_int(qnum
, &val
));
819 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
821 str
= qobject_to_json(QOBJECT(qnum
));
822 g_assert_cmpstr(qstring_get_str(str
), ==,
823 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
830 static void large_number(void)
832 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
833 const char *gtu64
= "18446744073709551616"; /* 2^64 */
834 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
840 qnum
= qobject_to(QNum
, qobject_from_json(maxu64
, &error_abort
));
842 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
843 g_assert(!qnum_get_try_int(qnum
, &ival
));
845 str
= qobject_to_json(QOBJECT(qnum
));
846 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
850 qnum
= qobject_to(QNum
, qobject_from_json(gtu64
, &error_abort
));
852 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
853 g_assert(!qnum_get_try_uint(qnum
, &val
));
854 g_assert(!qnum_get_try_int(qnum
, &ival
));
856 str
= qobject_to_json(QOBJECT(qnum
));
857 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
861 qnum
= qobject_to(QNum
, qobject_from_json(lti64
, &error_abort
));
863 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
864 g_assert(!qnum_get_try_uint(qnum
, &val
));
865 g_assert(!qnum_get_try_int(qnum
, &ival
));
867 str
= qobject_to_json(QOBJECT(qnum
));
868 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
873 static void float_number(void)
878 const char *reencoded
;
882 { "-32.12313", -32.12313 },
883 { "-32.20e-10", -32.20e-10, "-0" /* BUG */ },
890 for (i
= 0; test_cases
[i
].encoded
; i
++) {
891 qnum
= qobject_to(QNum
,
892 qobject_from_json(test_cases
[i
].encoded
,
895 g_assert_cmpfloat(qnum_get_double(qnum
), ==, test_cases
[i
].decoded
);
897 str
= qobject_to_json(QOBJECT(qnum
));
898 g_assert_cmpstr(qstring_get_str(str
), ==,
899 test_cases
[i
].reencoded
?: test_cases
[i
].encoded
);
906 static void keyword_literal(void)
913 obj
= qobject_from_json("true", &error_abort
);
914 qbool
= qobject_to(QBool
, obj
);
916 g_assert(qbool_get_bool(qbool
) == true);
918 str
= qobject_to_json(obj
);
919 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
922 qobject_unref(qbool
);
924 obj
= qobject_from_json("false", &error_abort
);
925 qbool
= qobject_to(QBool
, obj
);
927 g_assert(qbool_get_bool(qbool
) == false);
929 str
= qobject_to_json(obj
);
930 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
933 qobject_unref(qbool
);
935 obj
= qobject_from_json("null", &error_abort
);
936 g_assert(obj
!= NULL
);
937 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
940 g_assert(QOBJECT(null
) == obj
);
946 static void interpolation_valid(void)
948 long long value_lld
= 0x123456789abcdefLL
;
949 int64_t value_d64
= value_lld
;
950 long value_ld
= (long)value_lld
;
951 int value_d
= (int)value_lld
;
952 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
953 uint64_t value_u64
= value_llu
;
954 unsigned long value_lu
= (unsigned long)value_llu
;
955 unsigned value_u
= (unsigned)value_llu
;
956 double value_f
= 2.323423423;
957 const char *value_s
= "hello world";
958 QObject
*value_p
= QOBJECT(qnull());
966 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
968 g_assert(qbool_get_bool(qbool
) == false);
969 qobject_unref(qbool
);
971 /* Test that non-zero values other than 1 get collapsed to true */
972 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
974 g_assert(qbool_get_bool(qbool
) == true);
975 qobject_unref(qbool
);
979 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
980 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
983 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
984 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
987 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
988 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
991 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRId64
, value_d64
));
992 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
995 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
996 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
999 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
1000 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1001 qobject_unref(qnum
);
1003 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1004 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1005 qobject_unref(qnum
);
1007 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRIu64
, value_u64
));
1008 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1009 qobject_unref(qnum
);
1011 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1012 g_assert(qnum_get_double(qnum
) == value_f
);
1013 qobject_unref(qnum
);
1017 qstr
= qobject_to(QString
,
1018 qobject_from_jsonf_nofail("%s", value_s
));
1019 g_assert_cmpstr(qstring_get_try_str(qstr
), ==, value_s
);
1020 qobject_unref(qstr
);
1024 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1025 g_assert(qobj
== value_p
);
1028 static void interpolation_unknown(void)
1030 if (g_test_subprocess()) {
1031 qobject_from_jsonf_nofail("%x", 666);
1033 g_test_trap_subprocess(NULL
, 0, 0);
1034 g_test_trap_assert_failed();
1035 g_test_trap_assert_stderr("*Unexpected error*"
1036 "invalid interpolation '%x'*");
1039 static void interpolation_string(void)
1041 if (g_test_subprocess()) {
1042 qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1044 g_test_trap_subprocess(NULL
, 0, 0);
1045 g_test_trap_assert_failed();
1046 g_test_trap_assert_stderr("*Unexpected error*"
1047 "can't interpolate into string*");
1050 static void simple_dict(void)
1054 const char *encoded
;
1058 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1059 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1060 { "foo", QLIT_QNUM(42) },
1061 { "bar", QLIT_QSTR("hello world") },
1066 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1070 .encoded
= "{\"foo\": 43}",
1071 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1072 { "foo", QLIT_QNUM(43) },
1079 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1083 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1084 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1086 str
= qobject_to_json(obj
);
1089 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1090 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1097 * this generates json of the form:
1098 * a(0,m) = [0, 1, ..., m-1]
1103 * 'key(n-1)': a(n-1,m)
1106 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1112 if (nest_level_max
== 0) {
1113 g_string_append(gstr
, "[");
1114 for (i
= 0; i
< elem_count
; i
++) {
1115 g_string_append_printf(gstr
, "%d", i
);
1116 if (i
< elem_count
- 1) {
1117 g_string_append_printf(gstr
, ", ");
1120 g_string_append(gstr
, "]");
1124 g_string_append(gstr
, "{");
1125 for (i
= 0; i
< nest_level_max
; i
++) {
1126 g_string_append_printf(gstr
, "'key%d': ", i
);
1127 gen_test_json(gstr
, i
, elem_count
);
1128 if (i
< nest_level_max
- 1) {
1129 g_string_append(gstr
, ",");
1132 g_string_append(gstr
, "}");
1135 static void large_dict(void)
1137 GString
*gstr
= g_string_new("");
1140 gen_test_json(gstr
, 10, 100);
1141 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1142 g_assert(obj
!= NULL
);
1145 g_string_free(gstr
, true);
1148 static void simple_list(void)
1152 const char *encoded
;
1156 .encoded
= "[43,42]",
1157 .decoded
= QLIT_QLIST(((QLitObject
[]){
1165 .decoded
= QLIT_QLIST(((QLitObject
[]){
1172 .decoded
= QLIT_QLIST(((QLitObject
[]){
1178 .decoded
= QLIT_QLIST(((QLitObject
[]){
1179 QLIT_QDICT(((QLitDictEntry
[]){
1188 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1192 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1193 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1195 str
= qobject_to_json(obj
);
1198 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1199 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1205 static void simple_whitespace(void)
1209 const char *encoded
;
1213 .encoded
= " [ 43 , 42 ]",
1214 .decoded
= QLIT_QLIST(((QLitObject
[]){
1221 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1222 .decoded
= QLIT_QLIST(((QLitObject
[]){
1224 QLIT_QDICT(((QLitDictEntry
[]){
1225 { "h", QLIT_QSTR("b") },
1227 QLIT_QLIST(((QLitObject
[]){
1234 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1235 .decoded
= QLIT_QLIST(((QLitObject
[]){
1237 QLIT_QDICT(((QLitDictEntry
[]){
1238 { "h", QLIT_QSTR("b") },
1239 { "a", QLIT_QNUM(32) },
1241 QLIT_QLIST(((QLitObject
[]){
1250 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1254 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1255 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1257 str
= qobject_to_json(obj
);
1260 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1261 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1268 static void simple_interpolation(void)
1270 QObject
*embedded_obj
;
1272 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1275 QLIT_QLIST(((QLitObject
[]){
1281 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1282 g_assert(embedded_obj
!= NULL
);
1284 obj
= qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj
);
1285 g_assert(qlit_equal_qobject(&decoded
, obj
));
1290 static void empty_input(void)
1295 obj
= qobject_from_json("", &err
);
1296 error_free_or_abort(&err
);
1297 g_assert(obj
== NULL
);
1300 static void blank_input(void)
1305 obj
= qobject_from_json("\n ", &err
);
1306 error_free_or_abort(&err
);
1307 g_assert(obj
== NULL
);
1310 static void junk_input(void)
1312 /* Note: junk within strings is covered elsewhere */
1316 obj
= qobject_from_json("@", &err
);
1317 error_free_or_abort(&err
);
1318 g_assert(obj
== NULL
);
1320 obj
= qobject_from_json("{\x01", &err
);
1321 error_free_or_abort(&err
);
1322 g_assert(obj
== NULL
);
1324 obj
= qobject_from_json("[0\xFF]", &err
);
1325 error_free_or_abort(&err
);
1326 g_assert(obj
== NULL
);
1328 obj
= qobject_from_json("00", &err
);
1329 error_free_or_abort(&err
);
1330 g_assert(obj
== NULL
);
1332 obj
= qobject_from_json("[1e", &err
);
1333 error_free_or_abort(&err
);
1334 g_assert(obj
== NULL
);
1336 obj
= qobject_from_json("truer", &err
);
1337 error_free_or_abort(&err
);
1338 g_assert(obj
== NULL
);
1341 static void unterminated_string(void)
1344 QObject
*obj
= qobject_from_json("\"abc", &err
);
1345 error_free_or_abort(&err
);
1346 g_assert(obj
== NULL
);
1349 static void unterminated_sq_string(void)
1352 QObject
*obj
= qobject_from_json("'abc", &err
);
1353 error_free_or_abort(&err
);
1354 g_assert(obj
== NULL
);
1357 static void unterminated_escape(void)
1360 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1361 error_free_or_abort(&err
);
1362 g_assert(obj
== NULL
);
1365 static void unterminated_array(void)
1368 QObject
*obj
= qobject_from_json("[32", &err
);
1369 error_free_or_abort(&err
);
1370 g_assert(obj
== NULL
);
1373 static void unterminated_array_comma(void)
1376 QObject
*obj
= qobject_from_json("[32,", &err
);
1377 error_free_or_abort(&err
);
1378 g_assert(obj
== NULL
);
1381 static void invalid_array_comma(void)
1384 QObject
*obj
= qobject_from_json("[32,}", &err
);
1385 error_free_or_abort(&err
);
1386 g_assert(obj
== NULL
);
1389 static void unterminated_dict(void)
1392 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1393 error_free_or_abort(&err
);
1394 g_assert(obj
== NULL
);
1397 static void unterminated_dict_comma(void)
1400 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1401 error_free_or_abort(&err
);
1402 g_assert(obj
== NULL
);
1405 static void invalid_dict_comma(void)
1408 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1409 error_free_or_abort(&err
);
1410 g_assert(obj
== NULL
);
1413 static void invalid_dict_key(void)
1416 QObject
*obj
= qobject_from_json("{32:'abc'}", &err
);
1417 error_free_or_abort(&err
);
1418 g_assert(obj
== NULL
);
1421 static void unterminated_literal(void)
1424 QObject
*obj
= qobject_from_json("nul", &err
);
1425 error_free_or_abort(&err
);
1426 g_assert(obj
== NULL
);
1429 static char *make_nest(char *buf
, size_t cnt
)
1431 memset(buf
, '[', cnt
- 1);
1434 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1439 static void limits_nesting(void)
1442 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1443 char buf
[2 * (max_nesting
+ 1) + 1];
1446 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1447 g_assert(obj
!= NULL
);
1450 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1451 error_free_or_abort(&err
);
1452 g_assert(obj
== NULL
);
1455 static void multiple_values(void)
1460 obj
= qobject_from_json("false true", &err
);
1461 error_free_or_abort(&err
);
1462 g_assert(obj
== NULL
);
1464 obj
= qobject_from_json("} true", &err
);
1465 error_free_or_abort(&err
);
1466 g_assert(obj
== NULL
);
1469 int main(int argc
, char **argv
)
1471 g_test_init(&argc
, &argv
, NULL
);
1473 g_test_add_func("/literals/string/escaped", escaped_string
);
1474 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1475 g_test_add_func("/literals/string/utf8", utf8_string
);
1477 g_test_add_func("/literals/number/simple", simple_number
);
1478 g_test_add_func("/literals/number/large", large_number
);
1479 g_test_add_func("/literals/number/float", float_number
);
1481 g_test_add_func("/literals/keyword", keyword_literal
);
1483 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1484 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1485 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1487 g_test_add_func("/dicts/simple_dict", simple_dict
);
1488 g_test_add_func("/dicts/large_dict", large_dict
);
1489 g_test_add_func("/lists/simple_list", simple_list
);
1491 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1492 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1494 g_test_add_func("/errors/empty", empty_input
);
1495 g_test_add_func("/errors/blank", blank_input
);
1496 g_test_add_func("/errors/junk", junk_input
);
1497 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1498 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1499 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1500 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1501 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1502 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1503 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1504 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1505 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1506 g_test_add_func("/errors/invalid_dict_key", invalid_dict_key
);
1507 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1508 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1509 g_test_add_func("/errors/multiple_values", multiple_values
);
1511 return g_test_run();