2 * Copyright IBM, Corp. 2009
3 * Copyright (c) 2013, 2015 Red Hat Inc.
6 * Anthony Liguori <aliguori@us.ibm.com>
7 * Markus Armbruster <armbru@redhat.com>
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include "qapi/error.h"
17 #include "qapi/qmp/qbool.h"
18 #include "qapi/qmp/qjson.h"
19 #include "qapi/qmp/qlit.h"
20 #include "qapi/qmp/qnull.h"
21 #include "qapi/qmp/qnum.h"
22 #include "qapi/qmp/qstring.h"
23 #include "qemu/unicode.h"
24 #include "qemu-common.h"
26 static QString
*from_json_str(const char *jstr
, bool single
, Error
**errp
)
28 char quote
= single
? '\'' : '"';
29 char *qjstr
= g_strdup_printf("%c%s%c", quote
, jstr
, quote
);
30 QString
*ret
= qobject_to(QString
, qobject_from_json(qjstr
, errp
));
36 static char *to_json_str(QString
*str
)
38 QString
*json
= qobject_to_json(QOBJECT(str
));
44 /* peel off double quotes */
45 jstr
= g_strndup(qstring_get_str(json
) + 1,
46 qstring_get_length(json
) - 2);
51 static void escaped_string(void)
54 /* Content of JSON string to parse with qobject_from_json() */
56 /* Expected parse output; to unparse with qobject_to_json() */
60 { "\\b\\f\\n\\r\\t\\\\\\\"", "\b\f\n\r\t\\\"" },
61 { "\\/\\'", "/'", .skip
= 1 },
62 { "single byte utf-8 \\u0020", "single byte utf-8 ", .skip
= 1 },
63 { "double byte utf-8 \\u00A2", "double byte utf-8 \xc2\xa2" },
64 { "triple byte utf-8 \\u20AC", "triple byte utf-8 \xe2\x82\xac" },
65 { "quadruple byte utf-8 \\uD834\\uDD1E", /* U+1D11E */
66 "quadruple byte utf-8 \xF0\x9D\x84\x9E" },
73 { "\\u12345", "\341\210\2645" },
74 { "\\u0000x", "\xC0\x80x" },
75 { "unpaired leading surrogate \\uD800", NULL
},
76 { "unpaired leading surrogate \\uD800\\uCAFE", NULL
},
77 { "unpaired leading surrogate \\uD800\\uD801\\uDC02", NULL
},
78 { "unpaired trailing surrogate \\uDC00", NULL
},
79 { "backward surrogate pair \\uDC00\\uD800", NULL
},
80 { "noncharacter U+FDD0 \\uFDD0", NULL
},
81 { "noncharacter U+FDEF \\uFDEF", NULL
},
82 { "noncharacter U+1FFFE \\uD87F\\uDFFE", NULL
},
83 { "noncharacter U+10FFFF \\uDC3F\\uDFFF", NULL
},
90 for (i
= 0; test_cases
[i
].json_in
; i
++) {
91 for (j
= 0; j
< 2; j
++) {
92 if (test_cases
[i
].utf8_out
) {
93 cstr
= from_json_str(test_cases
[i
].json_in
, j
, &error_abort
);
94 g_assert_cmpstr(qstring_get_try_str(cstr
),
95 ==, test_cases
[i
].utf8_out
);
96 if (!test_cases
[i
].skip
) {
97 jstr
= to_json_str(cstr
);
98 g_assert_cmpstr(jstr
, ==, test_cases
[i
].json_in
);
103 cstr
= from_json_str(test_cases
[i
].json_in
, j
, NULL
);
110 static void string_with_quotes(void)
112 const char *test_cases
[] = {
113 "\"the bee's knees\"",
121 for (i
= 0; test_cases
[i
]; i
++) {
122 str
= qobject_to(QString
,
123 qobject_from_json(test_cases
[i
], &error_abort
));
125 cstr
= g_strndup(test_cases
[i
] + 1, strlen(test_cases
[i
]) - 2);
126 g_assert_cmpstr(qstring_get_str(str
), ==, cstr
);
132 static void utf8_string(void)
135 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
136 * capability and stress test at
137 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
139 static const struct {
140 /* Content of JSON string to parse with qobject_from_json() */
142 /* Expected parse output */
143 const char *utf8_out
;
144 /* Expected unparse output, defaults to @json_in */
145 const char *json_out
;
147 /* 0 Control characters */
150 * Note: \x00 is impossible, other representations of
151 * U+0000 are covered under 4.3
153 "\x01\x02\x03\x04\x05\x06\x07"
154 "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
155 "\x10\x11\x12\x13\x14\x15\x16\x17"
156 "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
158 "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007"
159 "\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F"
160 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017"
161 "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F",
163 /* 1 Some correct UTF-8 text */
165 /* a bit of German */
166 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
167 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
168 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
169 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
170 "Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
171 " jeden gr\\u00F6\\u00DFeren Zwerg.",
175 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
176 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
177 "\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
179 /* 2 Boundary condition test cases */
180 /* 2.1 First possible sequence of a certain length */
182 * 2.1.1 1 byte U+0020
183 * Control characters are already covered by their own test
184 * case under 0. Test the first 1 byte non-control character
191 /* 2.1.2 2 bytes U+0080 */
197 /* 2.1.3 3 bytes U+0800 */
203 /* 2.1.4 4 bytes U+10000 */
209 /* 2.1.5 5 bytes U+200000 */
211 "\xF8\x88\x80\x80\x80",
215 /* 2.1.6 6 bytes U+4000000 */
217 "\xFC\x84\x80\x80\x80\x80",
221 /* 2.2 Last possible sequence of a certain length */
222 /* 2.2.1 1 byte U+007F */
228 /* 2.2.2 2 bytes U+07FF */
235 * 2.2.3 3 bytes U+FFFC
236 * The last possible sequence is actually U+FFFF. But that's
237 * a noncharacter, and already covered by its own test case
238 * under 5.3. Same for U+FFFE. U+FFFD is the last character
239 * in the BMP, and covered under 2.3. Because of U+FFFD's
240 * special role as replacement character, it's worth testing
248 /* 2.2.4 4 bytes U+1FFFFF */
254 /* 2.2.5 5 bytes U+3FFFFFF */
256 "\xFB\xBF\xBF\xBF\xBF",
260 /* 2.2.6 6 bytes U+7FFFFFFF */
262 "\xFD\xBF\xBF\xBF\xBF\xBF",
266 /* 2.3 Other boundary conditions */
268 /* last one before surrogate range: U+D7FF */
274 /* first one after surrogate range: U+E000 */
280 /* last one in BMP: U+FFFD */
286 /* last one in last plane: U+10FFFD */
292 /* first one beyond Unicode range: U+110000 */
297 /* 3 Malformed sequences */
298 /* 3.1 Unexpected continuation bytes */
299 /* 3.1.1 First continuation byte */
305 /* 3.1.2 Last continuation byte */
311 /* 3.1.3 2 continuation bytes */
317 /* 3.1.4 3 continuation bytes */
321 "\\uFFFD\\uFFFD\\uFFFD",
323 /* 3.1.5 4 continuation bytes */
327 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
329 /* 3.1.6 5 continuation bytes */
331 "\x80\xBF\x80\xBF\x80",
333 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
335 /* 3.1.7 6 continuation bytes */
337 "\x80\xBF\x80\xBF\x80\xBF",
339 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
341 /* 3.1.8 7 continuation bytes */
343 "\x80\xBF\x80\xBF\x80\xBF\x80",
345 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
347 /* 3.1.9 Sequence of all 64 possible continuation bytes */
349 "\x80\x81\x82\x83\x84\x85\x86\x87"
350 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
351 "\x90\x91\x92\x93\x94\x95\x96\x97"
352 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
353 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
354 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
355 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
356 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
358 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
359 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
360 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
361 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
362 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
363 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
364 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
365 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
367 /* 3.2 Lonely start characters */
368 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
370 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
371 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
372 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
373 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
375 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
376 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
377 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
378 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
380 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
382 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
383 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
385 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
386 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
388 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
390 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
392 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
394 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
396 "\xF8 \xF9 \xFA \xFB ",
398 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
400 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
406 /* 3.3 Sequences with last continuation byte missing */
407 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
413 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
419 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
425 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
431 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
433 "\xFC\x80\x80\x80\x80",
437 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
443 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
449 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
455 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
461 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
463 "\xFD\xBF\xBF\xBF\xBF",
467 /* 3.4 Concatenation of incomplete sequences */
469 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
470 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
472 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
473 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
475 /* 3.5 Impossible bytes */
489 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
491 /* 4 Overlong sequences */
492 /* 4.1 Overlong '/' */
509 "\xF8\x80\x80\x80\xAF",
514 "\xFC\x80\x80\x80\x80\xAF",
519 * 4.2 Maximum overlong sequences
520 * Highest Unicode value that is still resulting in an
521 * overlong sequence if represented with the given number of
522 * bytes. This is a boundary test for safe UTF-8 decoders.
539 * The actual maximum would be U+FFFF, but that's a
540 * noncharacter. Testing U+FFFC seems more useful. See
549 "\xF8\x87\xBF\xBF\xBF",
555 "\xFC\x83\xBF\xBF\xBF\xBF",
559 /* 4.3 Overlong representation of the NUL character */
580 "\xF8\x80\x80\x80\x80",
586 "\xFC\x80\x80\x80\x80\x80",
590 /* 5 Illegal code positions */
591 /* 5.1 Single UTF-16 surrogates */
634 /* 5.2 Paired UTF-16 surrogates */
637 "\xED\xA0\x80\xED\xB0\x80",
643 "\xED\xA0\x80\xED\xBF\xBF",
649 "\xED\xAD\xBF\xED\xB0\x80",
655 "\xED\xAD\xBF\xED\xBF\xBF",
661 "\xED\xAE\x80\xED\xB0\x80",
667 "\xED\xAE\x80\xED\xBF\xBF",
673 "\xED\xAF\xBF\xED\xB0\x80",
679 "\xED\xAF\xBF\xED\xBF\xBF",
683 /* 5.3 Other illegal code positions */
684 /* BMP noncharacters */
709 /* Plane 1 .. 16 noncharacters */
711 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
712 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
713 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
714 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
715 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
716 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
717 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
718 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
719 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
720 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
721 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
722 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
723 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
724 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
725 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
726 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
727 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
729 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
730 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
731 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
732 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
738 const char *json_in
, *utf8_out
, *utf8_in
, *json_out
, *tail
;
739 char *end
, *in
, *jstr
;
741 for (i
= 0; test_cases
[i
].json_in
; i
++) {
742 for (j
= 0; j
< 2; j
++) {
743 json_in
= test_cases
[i
].json_in
;
744 utf8_out
= test_cases
[i
].utf8_out
;
745 utf8_in
= test_cases
[i
].utf8_out
?: test_cases
[i
].json_in
;
746 json_out
= test_cases
[i
].json_out
?: test_cases
[i
].json_in
;
748 /* Parse @json_in, expect @utf8_out */
750 str
= from_json_str(json_in
, j
, &error_abort
);
751 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_out
);
754 str
= from_json_str(json_in
, j
, NULL
);
757 * Failure may be due to any sequence, but *all* sequences
758 * are expected to fail. Test each one in isolation.
760 for (tail
= json_in
; *tail
; tail
= end
) {
761 mod_utf8_codepoint(tail
, 6, &end
);
765 in
= strndup(tail
, end
- tail
);
766 str
= from_json_str(in
, j
, NULL
);
772 /* Unparse @utf8_in, expect @json_out */
773 str
= qstring_from_str(utf8_in
);
774 jstr
= to_json_str(str
);
775 g_assert_cmpstr(jstr
, ==, json_out
);
779 /* Parse @json_out right back, unless it has replacements */
780 if (!strstr(json_out
, "\\uFFFD")) {
781 str
= from_json_str(json_out
, j
, &error_abort
);
782 g_assert_cmpstr(qstring_get_try_str(str
), ==, utf8_in
);
788 static void simple_number(void)
800 { "-0", 0, .skip
= 1 },
804 for (i
= 0; test_cases
[i
].encoded
; i
++) {
808 qnum
= qobject_to(QNum
,
809 qobject_from_json(test_cases
[i
].encoded
,
812 g_assert(qnum_get_try_int(qnum
, &val
));
813 g_assert_cmpint(val
, ==, test_cases
[i
].decoded
);
814 if (test_cases
[i
].skip
== 0) {
817 str
= qobject_to_json(QOBJECT(qnum
));
818 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
826 static void large_number(void)
828 const char *maxu64
= "18446744073709551615"; /* 2^64-1 */
829 const char *gtu64
= "18446744073709551616"; /* 2^64 */
830 const char *lti64
= "-9223372036854775809"; /* -2^63 - 1 */
836 qnum
= qobject_to(QNum
, qobject_from_json(maxu64
, &error_abort
));
838 g_assert_cmpuint(qnum_get_uint(qnum
), ==, 18446744073709551615U);
839 g_assert(!qnum_get_try_int(qnum
, &ival
));
841 str
= qobject_to_json(QOBJECT(qnum
));
842 g_assert_cmpstr(qstring_get_str(str
), ==, maxu64
);
846 qnum
= qobject_to(QNum
, qobject_from_json(gtu64
, &error_abort
));
848 g_assert_cmpfloat(qnum_get_double(qnum
), ==, 18446744073709552e3
);
849 g_assert(!qnum_get_try_uint(qnum
, &val
));
850 g_assert(!qnum_get_try_int(qnum
, &ival
));
852 str
= qobject_to_json(QOBJECT(qnum
));
853 g_assert_cmpstr(qstring_get_str(str
), ==, gtu64
);
857 qnum
= qobject_to(QNum
, qobject_from_json(lti64
, &error_abort
));
859 g_assert_cmpfloat(qnum_get_double(qnum
), ==, -92233720368547758e2
);
860 g_assert(!qnum_get_try_uint(qnum
, &val
));
861 g_assert(!qnum_get_try_int(qnum
, &ival
));
863 str
= qobject_to_json(QOBJECT(qnum
));
864 g_assert_cmpstr(qstring_get_str(str
), ==, "-9223372036854775808");
869 static void float_number(void)
879 { "-32.12313", -32.12313 },
880 { "-32.20e-10", -32.20e-10, .skip
= 1 },
884 for (i
= 0; test_cases
[i
].encoded
; i
++) {
888 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
889 qnum
= qobject_to(QNum
, obj
);
891 g_assert(qnum_get_double(qnum
) == test_cases
[i
].decoded
);
893 if (test_cases
[i
].skip
== 0) {
896 str
= qobject_to_json(obj
);
897 g_assert(strcmp(qstring_get_str(str
), test_cases
[i
].encoded
) == 0);
905 static void keyword_literal(void)
912 obj
= qobject_from_json("true", &error_abort
);
913 qbool
= qobject_to(QBool
, obj
);
915 g_assert(qbool_get_bool(qbool
) == true);
917 str
= qobject_to_json(obj
);
918 g_assert(strcmp(qstring_get_str(str
), "true") == 0);
921 qobject_unref(qbool
);
923 obj
= qobject_from_json("false", &error_abort
);
924 qbool
= qobject_to(QBool
, obj
);
926 g_assert(qbool_get_bool(qbool
) == false);
928 str
= qobject_to_json(obj
);
929 g_assert(strcmp(qstring_get_str(str
), "false") == 0);
932 qobject_unref(qbool
);
934 obj
= qobject_from_json("null", &error_abort
);
935 g_assert(obj
!= NULL
);
936 g_assert(qobject_type(obj
) == QTYPE_QNULL
);
939 g_assert(QOBJECT(null
) == obj
);
945 static void interpolation_valid(void)
947 long long value_lld
= 0x123456789abcdefLL
;
948 int64_t value_d64
= value_lld
;
949 long value_ld
= (long)value_lld
;
950 int value_d
= (int)value_lld
;
951 unsigned long long value_llu
= 0xfedcba9876543210ULL
;
952 uint64_t value_u64
= value_llu
;
953 unsigned long value_lu
= (unsigned long)value_llu
;
954 unsigned value_u
= (unsigned)value_llu
;
955 double value_f
= 2.323423423;
956 const char *value_s
= "hello world";
957 QObject
*value_p
= QOBJECT(qnull());
965 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", false));
967 g_assert(qbool_get_bool(qbool
) == false);
968 qobject_unref(qbool
);
970 /* Test that non-zero values other than 1 get collapsed to true */
971 qbool
= qobject_to(QBool
, qobject_from_jsonf_nofail("%i", 2));
973 g_assert(qbool_get_bool(qbool
) == true);
974 qobject_unref(qbool
);
978 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%d", value_d
));
979 g_assert_cmpint(qnum_get_int(qnum
), ==, value_d
);
982 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%ld", value_ld
));
983 g_assert_cmpint(qnum_get_int(qnum
), ==, value_ld
);
986 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lld", value_lld
));
987 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
990 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRId64
, value_d64
));
991 g_assert_cmpint(qnum_get_int(qnum
), ==, value_lld
);
994 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%u", value_u
));
995 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_u
);
998 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%lu", value_lu
));
999 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_lu
);
1000 qobject_unref(qnum
);
1002 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%llu", value_llu
));
1003 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1004 qobject_unref(qnum
);
1006 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%" PRIu64
, value_u64
));
1007 g_assert_cmpuint(qnum_get_uint(qnum
), ==, value_llu
);
1008 qobject_unref(qnum
);
1010 qnum
= qobject_to(QNum
, qobject_from_jsonf_nofail("%f", value_f
));
1011 g_assert(qnum_get_double(qnum
) == value_f
);
1012 qobject_unref(qnum
);
1016 qstr
= qobject_to(QString
,
1017 qobject_from_jsonf_nofail("%s", value_s
));
1018 g_assert_cmpstr(qstring_get_try_str(qstr
), ==, value_s
);
1019 qobject_unref(qstr
);
1023 qobj
= qobject_from_jsonf_nofail("%p", value_p
);
1024 g_assert(qobj
== value_p
);
1027 static void interpolation_unknown(void)
1029 if (g_test_subprocess()) {
1030 qobject_from_jsonf_nofail("%x", 666);
1032 g_test_trap_subprocess(NULL
, 0, 0);
1033 g_test_trap_assert_failed();
1034 g_test_trap_assert_stderr("*Unexpected error*"
1035 "invalid interpolation '%x'*");
1038 static void interpolation_string(void)
1040 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1046 /* Dangerous misfeature: % is silently ignored in strings */
1047 qobj
= qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1048 g_assert(qlit_equal_qobject(&decoded
, qobj
));
1049 qobject_unref(qobj
);
1052 static void simple_dict(void)
1056 const char *encoded
;
1060 .encoded
= "{\"foo\": 42, \"bar\": \"hello world\"}",
1061 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1062 { "foo", QLIT_QNUM(42) },
1063 { "bar", QLIT_QSTR("hello world") },
1068 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1072 .encoded
= "{\"foo\": 43}",
1073 .decoded
= QLIT_QDICT(((QLitDictEntry
[]){
1074 { "foo", QLIT_QNUM(43) },
1081 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1085 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1086 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1088 str
= qobject_to_json(obj
);
1091 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1092 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1099 * this generates json of the form:
1100 * a(0,m) = [0, 1, ..., m-1]
1105 * 'key(n-1)': a(n-1,m)
1108 static void gen_test_json(GString
*gstr
, int nest_level_max
,
1114 if (nest_level_max
== 0) {
1115 g_string_append(gstr
, "[");
1116 for (i
= 0; i
< elem_count
; i
++) {
1117 g_string_append_printf(gstr
, "%d", i
);
1118 if (i
< elem_count
- 1) {
1119 g_string_append_printf(gstr
, ", ");
1122 g_string_append(gstr
, "]");
1126 g_string_append(gstr
, "{");
1127 for (i
= 0; i
< nest_level_max
; i
++) {
1128 g_string_append_printf(gstr
, "'key%d': ", i
);
1129 gen_test_json(gstr
, i
, elem_count
);
1130 if (i
< nest_level_max
- 1) {
1131 g_string_append(gstr
, ",");
1134 g_string_append(gstr
, "}");
1137 static void large_dict(void)
1139 GString
*gstr
= g_string_new("");
1142 gen_test_json(gstr
, 10, 100);
1143 obj
= qobject_from_json(gstr
->str
, &error_abort
);
1144 g_assert(obj
!= NULL
);
1147 g_string_free(gstr
, true);
1150 static void simple_list(void)
1154 const char *encoded
;
1158 .encoded
= "[43,42]",
1159 .decoded
= QLIT_QLIST(((QLitObject
[]){
1167 .decoded
= QLIT_QLIST(((QLitObject
[]){
1174 .decoded
= QLIT_QLIST(((QLitObject
[]){
1180 .decoded
= QLIT_QLIST(((QLitObject
[]){
1181 QLIT_QDICT(((QLitDictEntry
[]){
1190 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1194 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1195 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1197 str
= qobject_to_json(obj
);
1200 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1201 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1207 static void simple_whitespace(void)
1211 const char *encoded
;
1215 .encoded
= " [ 43 , 42 ]",
1216 .decoded
= QLIT_QLIST(((QLitObject
[]){
1223 .encoded
= "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1224 .decoded
= QLIT_QLIST(((QLitObject
[]){
1226 QLIT_QDICT(((QLitDictEntry
[]){
1227 { "h", QLIT_QSTR("b") },
1229 QLIT_QLIST(((QLitObject
[]){
1236 .encoded
= " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1237 .decoded
= QLIT_QLIST(((QLitObject
[]){
1239 QLIT_QDICT(((QLitDictEntry
[]){
1240 { "h", QLIT_QSTR("b") },
1241 { "a", QLIT_QNUM(32) },
1243 QLIT_QLIST(((QLitObject
[]){
1252 for (i
= 0; test_cases
[i
].encoded
; i
++) {
1256 obj
= qobject_from_json(test_cases
[i
].encoded
, &error_abort
);
1257 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1259 str
= qobject_to_json(obj
);
1262 obj
= qobject_from_json(qstring_get_str(str
), &error_abort
);
1263 g_assert(qlit_equal_qobject(&test_cases
[i
].decoded
, obj
));
1270 static void simple_interpolation(void)
1272 QObject
*embedded_obj
;
1274 QLitObject decoded
= QLIT_QLIST(((QLitObject
[]){
1277 QLIT_QLIST(((QLitObject
[]){
1283 embedded_obj
= qobject_from_json("[32, 42]", &error_abort
);
1284 g_assert(embedded_obj
!= NULL
);
1286 obj
= qobject_from_jsonf_nofail("[%d, 2, %p]", 1, embedded_obj
);
1287 g_assert(qlit_equal_qobject(&decoded
, obj
));
1292 static void empty_input(void)
1294 QObject
*obj
= qobject_from_json("", &error_abort
);
1295 g_assert(obj
== NULL
);
1298 static void blank_input(void)
1300 QObject
*obj
= qobject_from_json("\n ", &error_abort
);
1301 g_assert(obj
== NULL
);
1304 static void junk_input(void)
1306 /* Note: junk within strings is covered elsewhere */
1310 obj
= qobject_from_json("@", &err
);
1311 error_free_or_abort(&err
);
1312 g_assert(obj
== NULL
);
1314 obj
= qobject_from_json("{\x01", &err
);
1315 error_free_or_abort(&err
);
1316 g_assert(obj
== NULL
);
1318 obj
= qobject_from_json("[0\xFF]", &err
);
1319 error_free_or_abort(&err
);
1320 g_assert(obj
== NULL
);
1322 obj
= qobject_from_json("00", &err
);
1323 error_free_or_abort(&err
);
1324 g_assert(obj
== NULL
);
1326 obj
= qobject_from_json("[1e", &err
);
1327 error_free_or_abort(&err
);
1328 g_assert(obj
== NULL
);
1330 obj
= qobject_from_json("truer", &err
);
1331 error_free_or_abort(&err
);
1332 g_assert(obj
== NULL
);
1335 static void unterminated_string(void)
1338 QObject
*obj
= qobject_from_json("\"abc", &err
);
1339 error_free_or_abort(&err
);
1340 g_assert(obj
== NULL
);
1343 static void unterminated_sq_string(void)
1346 QObject
*obj
= qobject_from_json("'abc", &err
);
1347 error_free_or_abort(&err
);
1348 g_assert(obj
== NULL
);
1351 static void unterminated_escape(void)
1354 QObject
*obj
= qobject_from_json("\"abc\\\"", &err
);
1355 error_free_or_abort(&err
);
1356 g_assert(obj
== NULL
);
1359 static void unterminated_array(void)
1362 QObject
*obj
= qobject_from_json("[32", &err
);
1363 error_free_or_abort(&err
);
1364 g_assert(obj
== NULL
);
1367 static void unterminated_array_comma(void)
1370 QObject
*obj
= qobject_from_json("[32,", &err
);
1371 error_free_or_abort(&err
);
1372 g_assert(obj
== NULL
);
1375 static void invalid_array_comma(void)
1378 QObject
*obj
= qobject_from_json("[32,}", &err
);
1379 error_free_or_abort(&err
);
1380 g_assert(obj
== NULL
);
1383 static void unterminated_dict(void)
1386 QObject
*obj
= qobject_from_json("{'abc':32", &err
);
1387 error_free_or_abort(&err
);
1388 g_assert(obj
== NULL
);
1391 static void unterminated_dict_comma(void)
1394 QObject
*obj
= qobject_from_json("{'abc':32,", &err
);
1395 error_free_or_abort(&err
);
1396 g_assert(obj
== NULL
);
1399 static void invalid_dict_comma(void)
1402 QObject
*obj
= qobject_from_json("{'abc':32,}", &err
);
1403 error_free_or_abort(&err
);
1404 g_assert(obj
== NULL
);
1407 static void unterminated_literal(void)
1410 QObject
*obj
= qobject_from_json("nul", &err
);
1411 error_free_or_abort(&err
);
1412 g_assert(obj
== NULL
);
1415 static char *make_nest(char *buf
, size_t cnt
)
1417 memset(buf
, '[', cnt
- 1);
1420 memset(buf
+ cnt
+ 1, ']', cnt
- 1);
1425 static void limits_nesting(void)
1428 enum { max_nesting
= 1024 }; /* see qobject/json-streamer.c */
1429 char buf
[2 * (max_nesting
+ 1) + 1];
1432 obj
= qobject_from_json(make_nest(buf
, max_nesting
), &error_abort
);
1433 g_assert(obj
!= NULL
);
1436 obj
= qobject_from_json(make_nest(buf
, max_nesting
+ 1), &err
);
1437 error_free_or_abort(&err
);
1438 g_assert(obj
== NULL
);
1441 static void multiple_values(void)
1446 obj
= qobject_from_json("false true", &err
);
1447 error_free_or_abort(&err
);
1448 g_assert(obj
== NULL
);
1450 obj
= qobject_from_json("} true", &err
);
1451 error_free_or_abort(&err
);
1452 g_assert(obj
== NULL
);
1455 int main(int argc
, char **argv
)
1457 g_test_init(&argc
, &argv
, NULL
);
1459 g_test_add_func("/literals/string/escaped", escaped_string
);
1460 g_test_add_func("/literals/string/quotes", string_with_quotes
);
1461 g_test_add_func("/literals/string/utf8", utf8_string
);
1463 g_test_add_func("/literals/number/simple", simple_number
);
1464 g_test_add_func("/literals/number/large", large_number
);
1465 g_test_add_func("/literals/number/float", float_number
);
1467 g_test_add_func("/literals/keyword", keyword_literal
);
1469 g_test_add_func("/literals/interpolation/valid", interpolation_valid
);
1470 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown
);
1471 g_test_add_func("/literals/interpolation/string", interpolation_string
);
1473 g_test_add_func("/dicts/simple_dict", simple_dict
);
1474 g_test_add_func("/dicts/large_dict", large_dict
);
1475 g_test_add_func("/lists/simple_list", simple_list
);
1477 g_test_add_func("/mixed/simple_whitespace", simple_whitespace
);
1478 g_test_add_func("/mixed/interpolation", simple_interpolation
);
1480 g_test_add_func("/errors/empty", empty_input
);
1481 g_test_add_func("/errors/blank", blank_input
);
1482 g_test_add_func("/errors/junk", junk_input
);
1483 g_test_add_func("/errors/unterminated/string", unterminated_string
);
1484 g_test_add_func("/errors/unterminated/escape", unterminated_escape
);
1485 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string
);
1486 g_test_add_func("/errors/unterminated/array", unterminated_array
);
1487 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma
);
1488 g_test_add_func("/errors/unterminated/dict", unterminated_dict
);
1489 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma
);
1490 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma
);
1491 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma
);
1492 g_test_add_func("/errors/unterminated/literal", unterminated_literal
);
1493 g_test_add_func("/errors/limits/nesting", limits_nesting
);
1494 g_test_add_func("/errors/multiple_values", multiple_values
);
1496 return g_test_run();