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)
806 { "-0", 0, .skip
= 1 },
810 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
);
820 if (test_cases
[i
].skip
== 0) {
823 str
= qobject_to_json(QOBJECT(qnum
));
824 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
832 static void large_number(void)
834 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
835 const char *gtu64
= "18446744073709551616"; /* 2^64 */
836 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
842 qnum
= qobject_to(QNum
, qobject_from_json(maxu64
, &error_abort
));
844 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
845 g_assert(!qnum_get_try_int(qnum
, &ival
));
847 str
= qobject_to_json(QOBJECT(qnum
));
848 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
852 qnum
= qobject_to(QNum
, qobject_from_json(gtu64
, &error_abort
));
854 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
855 g_assert(!qnum_get_try_uint(qnum
, &val
));
856 g_assert(!qnum_get_try_int(qnum
, &ival
));
858 str
= qobject_to_json(QOBJECT(qnum
));
859 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
863 qnum
= qobject_to(QNum
, qobject_from_json(lti64
, &error_abort
));
865 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
866 g_assert(!qnum_get_try_uint(qnum
, &val
));
867 g_assert(!qnum_get_try_int(qnum
, &ival
));
869 str
= qobject_to_json(QOBJECT(qnum
));
870 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
875 static void float_number(void)
885 { "-32.12313", -32.12313 },
886 { "-32.20e-10", -32.20e-10, .skip
= 1 },
890 for (i
= 0; test_cases
[i
].encoded
; i
++) {
894 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
895 qnum
= qobject_to(QNum
, obj
);
897 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
899 if (test_cases
[i
].skip
== 0) {
902 str
= qobject_to_json(obj
);
903 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
911 static void keyword_literal(void)
918 obj
= qobject_from_json("true", &error_abort
);
919 qbool
= qobject_to(QBool
, obj
);
921 g_assert(qbool_get_bool(qbool
) == true);
923 str
= qobject_to_json(obj
);
924 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
927 qobject_unref(qbool
);
929 obj
= qobject_from_json("false", &error_abort
);
930 qbool
= qobject_to(QBool
, obj
);
932 g_assert(qbool_get_bool(qbool
) == false);
934 str
= qobject_to_json(obj
);
935 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
938 qobject_unref(qbool
);
940 obj
= qobject_from_json("null", &error_abort
);
941 g_assert(obj
!= NULL
);
942 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
945 g_assert(QOBJECT(null
) == obj
);
951 static void interpolation_valid(void)
953 long long value_lld
= 0x123456789abcdefLL
;
954 int64_t value_d64
= value_lld
;
955 long value_ld
= (long)value_lld
;
956 int value_d
= (int)value_lld
;
957 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
958 uint64_t value_u64
= value_llu
;
959 unsigned long value_lu
= (unsigned long)value_llu
;
960 unsigned value_u
= (unsigned)value_llu
;
961 double value_f
= 2.323423423;
962 const char *value_s
= "hello world";
963 QObject
*value_p
= QOBJECT(qnull());
971 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
973 g_assert(qbool_get_bool(qbool
) == false);
974 qobject_unref(qbool
);
976 /* Test that non-zero values other than 1 get collapsed to true */
977 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
979 g_assert(qbool_get_bool(qbool
) == true);
980 qobject_unref(qbool
);
984 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
985 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
988 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
989 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
992 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
993 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
996 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRId64
, value_d64
));
997 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
1000 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
1001 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
1002 qobject_unref(qnum
);
1004 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
1005 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1006 qobject_unref(qnum
);
1008 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1009 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1010 qobject_unref(qnum
);
1012 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRIu64
, value_u64
));
1013 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1014 qobject_unref(qnum
);
1016 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1017 g_assert(qnum_get_double(qnum
) == value_f
);
1018 qobject_unref(qnum
);
1022 qstr
= qobject_to(QString
,
1023 qobject_from_jsonf_nofail("%s", value_s
));
1024 g_assert_cmpstr(qstring_get_try_str(qstr
), ==, value_s
);
1025 qobject_unref(qstr
);
1029 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1030 g_assert(qobj
== value_p
);
1033 static void interpolation_unknown(void)
1035 if (g_test_subprocess()) {
1036 qobject_from_jsonf_nofail("%x", 666);
1038 g_test_trap_subprocess(NULL
, 0, 0);
1039 g_test_trap_assert_failed();
1040 g_test_trap_assert_stderr("*Unexpected error*"
1041 "invalid interpolation '%x'*");
1044 static void interpolation_string(void)
1046 if (g_test_subprocess()) {
1047 qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1049 g_test_trap_subprocess(NULL
, 0, 0);
1050 g_test_trap_assert_failed();
1051 g_test_trap_assert_stderr("*Unexpected error*"
1052 "can't interpolate into string*");
1055 static void simple_dict(void)
1059 const char *encoded
;
1063 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1064 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1065 { "foo", QLIT_QNUM(42) },
1066 { "bar", QLIT_QSTR("hello world") },
1071 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1075 .encoded
= "{\"foo\": 43}",
1076 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1077 { "foo", QLIT_QNUM(43) },
1084 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1088 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1089 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1091 str
= qobject_to_json(obj
);
1094 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1095 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1102 * this generates json of the form:
1103 * a(0,m) = [0, 1, ..., m-1]
1108 * 'key(n-1)': a(n-1,m)
1111 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1117 if (nest_level_max
== 0) {
1118 g_string_append(gstr
, "[");
1119 for (i
= 0; i
< elem_count
; i
++) {
1120 g_string_append_printf(gstr
, "%d", i
);
1121 if (i
< elem_count
- 1) {
1122 g_string_append_printf(gstr
, ", ");
1125 g_string_append(gstr
, "]");
1129 g_string_append(gstr
, "{");
1130 for (i
= 0; i
< nest_level_max
; i
++) {
1131 g_string_append_printf(gstr
, "'key%d': ", i
);
1132 gen_test_json(gstr
, i
, elem_count
);
1133 if (i
< nest_level_max
- 1) {
1134 g_string_append(gstr
, ",");
1137 g_string_append(gstr
, "}");
1140 static void large_dict(void)
1142 GString
*gstr
= g_string_new("");
1145 gen_test_json(gstr
, 10, 100);
1146 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1147 g_assert(obj
!= NULL
);
1150 g_string_free(gstr
, true);
1153 static void simple_list(void)
1157 const char *encoded
;
1161 .encoded
= "[43,42]",
1162 .decoded
= QLIT_QLIST(((QLitObject
[]){
1170 .decoded
= QLIT_QLIST(((QLitObject
[]){
1177 .decoded
= QLIT_QLIST(((QLitObject
[]){
1183 .decoded
= QLIT_QLIST(((QLitObject
[]){
1184 QLIT_QDICT(((QLitDictEntry
[]){
1193 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1197 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1198 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1200 str
= qobject_to_json(obj
);
1203 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1204 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1210 static void simple_whitespace(void)
1214 const char *encoded
;
1218 .encoded
= " [ 43 , 42 ]",
1219 .decoded
= QLIT_QLIST(((QLitObject
[]){
1226 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1227 .decoded
= QLIT_QLIST(((QLitObject
[]){
1229 QLIT_QDICT(((QLitDictEntry
[]){
1230 { "h", QLIT_QSTR("b") },
1232 QLIT_QLIST(((QLitObject
[]){
1239 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1240 .decoded
= QLIT_QLIST(((QLitObject
[]){
1242 QLIT_QDICT(((QLitDictEntry
[]){
1243 { "h", QLIT_QSTR("b") },
1244 { "a", QLIT_QNUM(32) },
1246 QLIT_QLIST(((QLitObject
[]){
1255 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1259 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1260 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1262 str
= qobject_to_json(obj
);
1265 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1266 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1273 static void simple_interpolation(void)
1275 QObject
*embedded_obj
;
1277 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1280 QLIT_QLIST(((QLitObject
[]){
1286 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1287 g_assert(embedded_obj
!= NULL
);
1289 obj
= qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj
);
1290 g_assert(qlit_equal_qobject(&decoded
, obj
));
1295 static void empty_input(void)
1300 obj
= qobject_from_json("", &err
);
1301 error_free_or_abort(&err
);
1302 g_assert(obj
== NULL
);
1305 static void blank_input(void)
1310 obj
= qobject_from_json("\n ", &err
);
1311 error_free_or_abort(&err
);
1312 g_assert(obj
== NULL
);
1315 static void junk_input(void)
1317 /* Note: junk within strings is covered elsewhere */
1321 obj
= qobject_from_json("@", &err
);
1322 error_free_or_abort(&err
);
1323 g_assert(obj
== NULL
);
1325 obj
= qobject_from_json("{\x01", &err
);
1326 error_free_or_abort(&err
);
1327 g_assert(obj
== NULL
);
1329 obj
= qobject_from_json("[0\xFF]", &err
);
1330 error_free_or_abort(&err
);
1331 g_assert(obj
== NULL
);
1333 obj
= qobject_from_json("00", &err
);
1334 error_free_or_abort(&err
);
1335 g_assert(obj
== NULL
);
1337 obj
= qobject_from_json("[1e", &err
);
1338 error_free_or_abort(&err
);
1339 g_assert(obj
== NULL
);
1341 obj
= qobject_from_json("truer", &err
);
1342 error_free_or_abort(&err
);
1343 g_assert(obj
== NULL
);
1346 static void unterminated_string(void)
1349 QObject
*obj
= qobject_from_json("\"abc", &err
);
1350 error_free_or_abort(&err
);
1351 g_assert(obj
== NULL
);
1354 static void unterminated_sq_string(void)
1357 QObject
*obj
= qobject_from_json("'abc", &err
);
1358 error_free_or_abort(&err
);
1359 g_assert(obj
== NULL
);
1362 static void unterminated_escape(void)
1365 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1366 error_free_or_abort(&err
);
1367 g_assert(obj
== NULL
);
1370 static void unterminated_array(void)
1373 QObject
*obj
= qobject_from_json("[32", &err
);
1374 error_free_or_abort(&err
);
1375 g_assert(obj
== NULL
);
1378 static void unterminated_array_comma(void)
1381 QObject
*obj
= qobject_from_json("[32,", &err
);
1382 error_free_or_abort(&err
);
1383 g_assert(obj
== NULL
);
1386 static void invalid_array_comma(void)
1389 QObject
*obj
= qobject_from_json("[32,}", &err
);
1390 error_free_or_abort(&err
);
1391 g_assert(obj
== NULL
);
1394 static void unterminated_dict(void)
1397 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1398 error_free_or_abort(&err
);
1399 g_assert(obj
== NULL
);
1402 static void unterminated_dict_comma(void)
1405 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1406 error_free_or_abort(&err
);
1407 g_assert(obj
== NULL
);
1410 static void invalid_dict_comma(void)
1413 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1414 error_free_or_abort(&err
);
1415 g_assert(obj
== NULL
);
1418 static void unterminated_literal(void)
1421 QObject
*obj
= qobject_from_json("nul", &err
);
1422 error_free_or_abort(&err
);
1423 g_assert(obj
== NULL
);
1426 static char *make_nest(char *buf
, size_t cnt
)
1428 memset(buf
, '[', cnt
- 1);
1431 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1436 static void limits_nesting(void)
1439 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1440 char buf
[2 * (max_nesting
+ 1) + 1];
1443 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1444 g_assert(obj
!= NULL
);
1447 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1448 error_free_or_abort(&err
);
1449 g_assert(obj
== NULL
);
1452 static void multiple_values(void)
1457 obj
= qobject_from_json("false true", &err
);
1458 error_free_or_abort(&err
);
1459 g_assert(obj
== NULL
);
1461 obj
= qobject_from_json("} true", &err
);
1462 error_free_or_abort(&err
);
1463 g_assert(obj
== NULL
);
1466 int main(int argc
, char **argv
)
1468 g_test_init(&argc
, &argv
, NULL
);
1470 g_test_add_func("/literals/string/escaped", escaped_string
);
1471 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1472 g_test_add_func("/literals/string/utf8", utf8_string
);
1474 g_test_add_func("/literals/number/simple", simple_number
);
1475 g_test_add_func("/literals/number/large", large_number
);
1476 g_test_add_func("/literals/number/float", float_number
);
1478 g_test_add_func("/literals/keyword", keyword_literal
);
1480 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1481 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1482 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1484 g_test_add_func("/dicts/simple_dict", simple_dict
);
1485 g_test_add_func("/dicts/large_dict", large_dict
);
1486 g_test_add_func("/lists/simple_list", simple_list
);
1488 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1489 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1491 g_test_add_func("/errors/empty", empty_input
);
1492 g_test_add_func("/errors/blank", blank_input
);
1493 g_test_add_func("/errors/junk", junk_input
);
1494 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1495 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1496 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1497 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1498 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1499 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1500 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1501 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1502 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1503 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1504 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1505 g_test_add_func("/errors/multiple_values", multiple_values
);
1507 return g_test_run();