Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
[qemu/ar7.git] / tests / check-qjson.c
blobe6d6935653db0519e5b73302d3f6d9098b6c1ab1
1 /*
2 * Copyright IBM, Corp. 2009
3 * Copyright (c) 2013, 2015 Red Hat Inc.
5 * Authors:
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.
13 #include "qemu/osdep.h"
15 #include "qapi/qmp/types.h"
16 #include "qapi/qmp/qjson.h"
17 #include "qemu-common.h"
19 static void escaped_string(void)
21 int i;
22 struct {
23 const char *encoded;
24 const char *decoded;
25 int skip;
26 } test_cases[] = {
27 { "\"\\b\"", "\b" },
28 { "\"\\f\"", "\f" },
29 { "\"\\n\"", "\n" },
30 { "\"\\r\"", "\r" },
31 { "\"\\t\"", "\t" },
32 { "\"/\"", "/" },
33 { "\"\\/\"", "/", .skip = 1 },
34 { "\"\\\\\"", "\\" },
35 { "\"\\\"\"", "\"" },
36 { "\"hello world \\\"embedded string\\\"\"",
37 "hello world \"embedded string\"" },
38 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
39 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip = 1 },
40 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
41 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
42 { "'\\b'", "\b", .skip = 1 },
43 { "'\\f'", "\f", .skip = 1 },
44 { "'\\n'", "\n", .skip = 1 },
45 { "'\\r'", "\r", .skip = 1 },
46 { "'\\t'", "\t", .skip = 1 },
47 { "'\\/'", "/", .skip = 1 },
48 { "'\\\\'", "\\", .skip = 1 },
52 for (i = 0; test_cases[i].encoded; i++) {
53 QObject *obj;
54 QString *str;
56 obj = qobject_from_json(test_cases[i].encoded);
57 str = qobject_to_qstring(obj);
58 g_assert(str);
59 g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].decoded);
61 if (test_cases[i].skip == 0) {
62 str = qobject_to_json(obj);
63 g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].encoded);
64 qobject_decref(obj);
67 QDECREF(str);
71 static void simple_string(void)
73 int i;
74 struct {
75 const char *encoded;
76 const char *decoded;
77 } test_cases[] = {
78 { "\"hello world\"", "hello world" },
79 { "\"the quick brown fox jumped over the fence\"",
80 "the quick brown fox jumped over the fence" },
84 for (i = 0; test_cases[i].encoded; i++) {
85 QObject *obj;
86 QString *str;
88 obj = qobject_from_json(test_cases[i].encoded);
89 str = qobject_to_qstring(obj);
90 g_assert(str);
91 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
93 str = qobject_to_json(obj);
94 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
96 qobject_decref(obj);
98 QDECREF(str);
102 static void single_quote_string(void)
104 int i;
105 struct {
106 const char *encoded;
107 const char *decoded;
108 } test_cases[] = {
109 { "'hello world'", "hello world" },
110 { "'the quick brown fox \\' jumped over the fence'",
111 "the quick brown fox ' jumped over the fence" },
115 for (i = 0; test_cases[i].encoded; i++) {
116 QObject *obj;
117 QString *str;
119 obj = qobject_from_json(test_cases[i].encoded);
120 str = qobject_to_qstring(obj);
121 g_assert(str);
122 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
124 QDECREF(str);
128 static void utf8_string(void)
131 * FIXME Current behavior for invalid UTF-8 sequences is
132 * incorrect. This test expects current, incorrect results.
133 * They're all marked "bug:" below, and are to be replaced by
134 * correct ones as the bugs get fixed.
136 * The JSON parser rejects some invalid sequences, but accepts
137 * others without correcting the problem.
139 * We should either reject all invalid sequences, or minimize
140 * overlong sequences and replace all other invalid sequences by a
141 * suitable replacement character. A common choice for
142 * replacement is U+FFFD.
144 * Problem: we can't easily deal with embedded U+0000. Parsing
145 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
146 * which gets misinterpreted as NUL-terminated "this ". We should
147 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
148 * UTF-8").
150 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
151 * capability and stress test at
152 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
154 static const struct {
155 const char *json_in;
156 const char *utf8_out;
157 const char *json_out; /* defaults to @json_in */
158 const char *utf8_in; /* defaults to @utf8_out */
159 } test_cases[] = {
161 * Bug markers used here:
162 * - bug: not corrected
163 * JSON parser fails to correct invalid sequence(s)
164 * - bug: rejected
165 * JSON parser rejects invalid sequence(s)
166 * We may choose to define this as feature
167 * - bug: want "..."
168 * JSON parser produces incorrect result, this is the
169 * correct one, assuming replacement character U+FFFF
170 * We may choose to reject instead of replace
173 /* 1 Some correct UTF-8 text */
175 /* a bit of German */
176 "\"Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
177 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.\"",
178 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
179 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
180 "\"Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
181 " jeden gr\\u00F6\\u00DFeren Zwerg.\"",
184 /* a bit of Greek */
185 "\"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5\"",
186 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
187 "\"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5\"",
189 /* 2 Boundary condition test cases */
190 /* 2.1 First possible sequence of a certain length */
191 /* 2.1.1 1 byte U+0000 */
193 "\"\\u0000\"",
194 "", /* bug: want overlong "\xC0\x80" */
195 "\"\\u0000\"",
196 "\xC0\x80",
198 /* 2.1.2 2 bytes U+0080 */
200 "\"\xC2\x80\"",
201 "\xC2\x80",
202 "\"\\u0080\"",
204 /* 2.1.3 3 bytes U+0800 */
206 "\"\xE0\xA0\x80\"",
207 "\xE0\xA0\x80",
208 "\"\\u0800\"",
210 /* 2.1.4 4 bytes U+10000 */
212 "\"\xF0\x90\x80\x80\"",
213 "\xF0\x90\x80\x80",
214 "\"\\uD800\\uDC00\"",
216 /* 2.1.5 5 bytes U+200000 */
218 "\"\xF8\x88\x80\x80\x80\"",
219 NULL, /* bug: rejected */
220 "\"\\uFFFD\"",
221 "\xF8\x88\x80\x80\x80",
223 /* 2.1.6 6 bytes U+4000000 */
225 "\"\xFC\x84\x80\x80\x80\x80\"",
226 NULL, /* bug: rejected */
227 "\"\\uFFFD\"",
228 "\xFC\x84\x80\x80\x80\x80",
230 /* 2.2 Last possible sequence of a certain length */
231 /* 2.2.1 1 byte U+007F */
233 "\"\x7F\"",
234 "\x7F",
235 "\"\\u007F\"",
237 /* 2.2.2 2 bytes U+07FF */
239 "\"\xDF\xBF\"",
240 "\xDF\xBF",
241 "\"\\u07FF\"",
244 * 2.2.3 3 bytes U+FFFC
245 * The last possible sequence is actually U+FFFF. But that's
246 * a noncharacter, and already covered by its own test case
247 * under 5.3. Same for U+FFFE. U+FFFD is the last character
248 * in the BMP, and covered under 2.3. Because of U+FFFD's
249 * special role as replacement character, it's worth testing
250 * U+FFFC here.
253 "\"\xEF\xBF\xBC\"",
254 "\xEF\xBF\xBC",
255 "\"\\uFFFC\"",
257 /* 2.2.4 4 bytes U+1FFFFF */
259 "\"\xF7\xBF\xBF\xBF\"",
260 NULL, /* bug: rejected */
261 "\"\\uFFFD\"",
262 "\xF7\xBF\xBF\xBF",
264 /* 2.2.5 5 bytes U+3FFFFFF */
266 "\"\xFB\xBF\xBF\xBF\xBF\"",
267 NULL, /* bug: rejected */
268 "\"\\uFFFD\"",
269 "\xFB\xBF\xBF\xBF\xBF",
271 /* 2.2.6 6 bytes U+7FFFFFFF */
273 "\"\xFD\xBF\xBF\xBF\xBF\xBF\"",
274 NULL, /* bug: rejected */
275 "\"\\uFFFD\"",
276 "\xFD\xBF\xBF\xBF\xBF\xBF",
278 /* 2.3 Other boundary conditions */
280 /* last one before surrogate range: U+D7FF */
281 "\"\xED\x9F\xBF\"",
282 "\xED\x9F\xBF",
283 "\"\\uD7FF\"",
286 /* first one after surrogate range: U+E000 */
287 "\"\xEE\x80\x80\"",
288 "\xEE\x80\x80",
289 "\"\\uE000\"",
292 /* last one in BMP: U+FFFD */
293 "\"\xEF\xBF\xBD\"",
294 "\xEF\xBF\xBD",
295 "\"\\uFFFD\"",
298 /* last one in last plane: U+10FFFD */
299 "\"\xF4\x8F\xBF\xBD\"",
300 "\xF4\x8F\xBF\xBD",
301 "\"\\uDBFF\\uDFFD\""
304 /* first one beyond Unicode range: U+110000 */
305 "\"\xF4\x90\x80\x80\"",
306 "\xF4\x90\x80\x80",
307 "\"\\uFFFD\"",
309 /* 3 Malformed sequences */
310 /* 3.1 Unexpected continuation bytes */
311 /* 3.1.1 First continuation byte */
313 "\"\x80\"",
314 "\x80", /* bug: not corrected */
315 "\"\\uFFFD\"",
317 /* 3.1.2 Last continuation byte */
319 "\"\xBF\"",
320 "\xBF", /* bug: not corrected */
321 "\"\\uFFFD\"",
323 /* 3.1.3 2 continuation bytes */
325 "\"\x80\xBF\"",
326 "\x80\xBF", /* bug: not corrected */
327 "\"\\uFFFD\\uFFFD\"",
329 /* 3.1.4 3 continuation bytes */
331 "\"\x80\xBF\x80\"",
332 "\x80\xBF\x80", /* bug: not corrected */
333 "\"\\uFFFD\\uFFFD\\uFFFD\"",
335 /* 3.1.5 4 continuation bytes */
337 "\"\x80\xBF\x80\xBF\"",
338 "\x80\xBF\x80\xBF", /* bug: not corrected */
339 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
341 /* 3.1.6 5 continuation bytes */
343 "\"\x80\xBF\x80\xBF\x80\"",
344 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
345 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
347 /* 3.1.7 6 continuation bytes */
349 "\"\x80\xBF\x80\xBF\x80\xBF\"",
350 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
351 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
353 /* 3.1.8 7 continuation bytes */
355 "\"\x80\xBF\x80\xBF\x80\xBF\x80\"",
356 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
357 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
359 /* 3.1.9 Sequence of all 64 possible continuation bytes */
361 "\"\x80\x81\x82\x83\x84\x85\x86\x87"
362 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
363 "\x90\x91\x92\x93\x94\x95\x96\x97"
364 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
365 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
366 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
367 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
368 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\"",
369 /* bug: not corrected */
370 "\x80\x81\x82\x83\x84\x85\x86\x87"
371 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
372 "\x90\x91\x92\x93\x94\x95\x96\x97"
373 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
374 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
375 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
376 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
377 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
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"
382 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
383 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
384 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
385 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\""
387 /* 3.2 Lonely start characters */
388 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
390 "\"\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
391 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
392 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
393 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF \"",
394 NULL, /* bug: rejected */
395 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
396 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
397 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
398 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
399 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
400 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
401 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
402 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
404 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
406 "\"\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
407 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF \"",
408 /* bug: not corrected */
409 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
410 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
411 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
412 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
414 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
416 "\"\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 \"",
417 NULL, /* bug: rejected */
418 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
419 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
421 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
423 "\"\xF8 \xF9 \xFA \xFB \"",
424 NULL, /* bug: rejected */
425 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
426 "\xF8 \xF9 \xFA \xFB ",
428 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
430 "\"\xFC \xFD \"",
431 NULL, /* bug: rejected */
432 "\"\\uFFFD \\uFFFD \"",
433 "\xFC \xFD ",
435 /* 3.3 Sequences with last continuation byte missing */
436 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
438 "\"\xC0\"",
439 NULL, /* bug: rejected */
440 "\"\\uFFFD\"",
441 "\xC0",
443 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
445 "\"\xE0\x80\"",
446 "\xE0\x80", /* bug: not corrected */
447 "\"\\uFFFD\"",
449 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
451 "\"\xF0\x80\x80\"",
452 "\xF0\x80\x80", /* bug: not corrected */
453 "\"\\uFFFD\"",
455 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
457 "\"\xF8\x80\x80\x80\"",
458 NULL, /* bug: rejected */
459 "\"\\uFFFD\"",
460 "\xF8\x80\x80\x80",
462 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
464 "\"\xFC\x80\x80\x80\x80\"",
465 NULL, /* bug: rejected */
466 "\"\\uFFFD\"",
467 "\xFC\x80\x80\x80\x80",
469 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
471 "\"\xDF\"",
472 "\xDF", /* bug: not corrected */
473 "\"\\uFFFD\"",
475 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
477 "\"\xEF\xBF\"",
478 "\xEF\xBF", /* bug: not corrected */
479 "\"\\uFFFD\"",
481 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
483 "\"\xF7\xBF\xBF\"",
484 NULL, /* bug: rejected */
485 "\"\\uFFFD\"",
486 "\xF7\xBF\xBF",
488 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
490 "\"\xFB\xBF\xBF\xBF\"",
491 NULL, /* bug: rejected */
492 "\"\\uFFFD\"",
493 "\xFB\xBF\xBF\xBF",
495 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
497 "\"\xFD\xBF\xBF\xBF\xBF\"",
498 NULL, /* bug: rejected */
499 "\"\\uFFFD\"",
500 "\xFD\xBF\xBF\xBF\xBF",
502 /* 3.4 Concatenation of incomplete sequences */
504 "\"\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
505 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF\"",
506 NULL, /* bug: rejected */
507 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
508 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
509 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
510 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
512 /* 3.5 Impossible bytes */
514 "\"\xFE\"",
515 NULL, /* bug: rejected */
516 "\"\\uFFFD\"",
517 "\xFE",
520 "\"\xFF\"",
521 NULL, /* bug: rejected */
522 "\"\\uFFFD\"",
523 "\xFF",
526 "\"\xFE\xFE\xFF\xFF\"",
527 NULL, /* bug: rejected */
528 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
529 "\xFE\xFE\xFF\xFF",
531 /* 4 Overlong sequences */
532 /* 4.1 Overlong '/' */
534 "\"\xC0\xAF\"",
535 NULL, /* bug: rejected */
536 "\"\\uFFFD\"",
537 "\xC0\xAF",
540 "\"\xE0\x80\xAF\"",
541 "\xE0\x80\xAF", /* bug: not corrected */
542 "\"\\uFFFD\"",
545 "\"\xF0\x80\x80\xAF\"",
546 "\xF0\x80\x80\xAF", /* bug: not corrected */
547 "\"\\uFFFD\"",
550 "\"\xF8\x80\x80\x80\xAF\"",
551 NULL, /* bug: rejected */
552 "\"\\uFFFD\"",
553 "\xF8\x80\x80\x80\xAF",
556 "\"\xFC\x80\x80\x80\x80\xAF\"",
557 NULL, /* bug: rejected */
558 "\"\\uFFFD\"",
559 "\xFC\x80\x80\x80\x80\xAF",
562 * 4.2 Maximum overlong sequences
563 * Highest Unicode value that is still resulting in an
564 * overlong sequence if represented with the given number of
565 * bytes. This is a boundary test for safe UTF-8 decoders.
568 /* \U+007F */
569 "\"\xC1\xBF\"",
570 NULL, /* bug: rejected */
571 "\"\\uFFFD\"",
572 "\xC1\xBF",
575 /* \U+07FF */
576 "\"\xE0\x9F\xBF\"",
577 "\xE0\x9F\xBF", /* bug: not corrected */
578 "\"\\uFFFD\"",
582 * \U+FFFC
583 * The actual maximum would be U+FFFF, but that's a
584 * noncharacter. Testing U+FFFC seems more useful. See
585 * also 2.2.3
587 "\"\xF0\x8F\xBF\xBC\"",
588 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
589 "\"\\uFFFD\"",
592 /* \U+1FFFFF */
593 "\"\xF8\x87\xBF\xBF\xBF\"",
594 NULL, /* bug: rejected */
595 "\"\\uFFFD\"",
596 "\xF8\x87\xBF\xBF\xBF",
599 /* \U+3FFFFFF */
600 "\"\xFC\x83\xBF\xBF\xBF\xBF\"",
601 NULL, /* bug: rejected */
602 "\"\\uFFFD\"",
603 "\xFC\x83\xBF\xBF\xBF\xBF",
605 /* 4.3 Overlong representation of the NUL character */
607 /* \U+0000 */
608 "\"\xC0\x80\"",
609 NULL, /* bug: rejected */
610 "\"\\u0000\"",
611 "\xC0\x80",
614 /* \U+0000 */
615 "\"\xE0\x80\x80\"",
616 "\xE0\x80\x80", /* bug: not corrected */
617 "\"\\uFFFD\"",
620 /* \U+0000 */
621 "\"\xF0\x80\x80\x80\"",
622 "\xF0\x80\x80\x80", /* bug: not corrected */
623 "\"\\uFFFD\"",
626 /* \U+0000 */
627 "\"\xF8\x80\x80\x80\x80\"",
628 NULL, /* bug: rejected */
629 "\"\\uFFFD\"",
630 "\xF8\x80\x80\x80\x80",
633 /* \U+0000 */
634 "\"\xFC\x80\x80\x80\x80\x80\"",
635 NULL, /* bug: rejected */
636 "\"\\uFFFD\"",
637 "\xFC\x80\x80\x80\x80\x80",
639 /* 5 Illegal code positions */
640 /* 5.1 Single UTF-16 surrogates */
642 /* \U+D800 */
643 "\"\xED\xA0\x80\"",
644 "\xED\xA0\x80", /* bug: not corrected */
645 "\"\\uFFFD\"",
648 /* \U+DB7F */
649 "\"\xED\xAD\xBF\"",
650 "\xED\xAD\xBF", /* bug: not corrected */
651 "\"\\uFFFD\"",
654 /* \U+DB80 */
655 "\"\xED\xAE\x80\"",
656 "\xED\xAE\x80", /* bug: not corrected */
657 "\"\\uFFFD\"",
660 /* \U+DBFF */
661 "\"\xED\xAF\xBF\"",
662 "\xED\xAF\xBF", /* bug: not corrected */
663 "\"\\uFFFD\"",
666 /* \U+DC00 */
667 "\"\xED\xB0\x80\"",
668 "\xED\xB0\x80", /* bug: not corrected */
669 "\"\\uFFFD\"",
672 /* \U+DF80 */
673 "\"\xED\xBE\x80\"",
674 "\xED\xBE\x80", /* bug: not corrected */
675 "\"\\uFFFD\"",
678 /* \U+DFFF */
679 "\"\xED\xBF\xBF\"",
680 "\xED\xBF\xBF", /* bug: not corrected */
681 "\"\\uFFFD\"",
683 /* 5.2 Paired UTF-16 surrogates */
685 /* \U+D800\U+DC00 */
686 "\"\xED\xA0\x80\xED\xB0\x80\"",
687 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
688 "\"\\uFFFD\\uFFFD\"",
691 /* \U+D800\U+DFFF */
692 "\"\xED\xA0\x80\xED\xBF\xBF\"",
693 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
694 "\"\\uFFFD\\uFFFD\"",
697 /* \U+DB7F\U+DC00 */
698 "\"\xED\xAD\xBF\xED\xB0\x80\"",
699 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
700 "\"\\uFFFD\\uFFFD\"",
703 /* \U+DB7F\U+DFFF */
704 "\"\xED\xAD\xBF\xED\xBF\xBF\"",
705 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
706 "\"\\uFFFD\\uFFFD\"",
709 /* \U+DB80\U+DC00 */
710 "\"\xED\xAE\x80\xED\xB0\x80\"",
711 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
712 "\"\\uFFFD\\uFFFD\"",
715 /* \U+DB80\U+DFFF */
716 "\"\xED\xAE\x80\xED\xBF\xBF\"",
717 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
718 "\"\\uFFFD\\uFFFD\"",
721 /* \U+DBFF\U+DC00 */
722 "\"\xED\xAF\xBF\xED\xB0\x80\"",
723 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
724 "\"\\uFFFD\\uFFFD\"",
727 /* \U+DBFF\U+DFFF */
728 "\"\xED\xAF\xBF\xED\xBF\xBF\"",
729 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
730 "\"\\uFFFD\\uFFFD\"",
732 /* 5.3 Other illegal code positions */
733 /* BMP noncharacters */
735 /* \U+FFFE */
736 "\"\xEF\xBF\xBE\"",
737 "\xEF\xBF\xBE", /* bug: not corrected */
738 "\"\\uFFFD\"",
741 /* \U+FFFF */
742 "\"\xEF\xBF\xBF\"",
743 "\xEF\xBF\xBF", /* bug: not corrected */
744 "\"\\uFFFD\"",
747 /* U+FDD0 */
748 "\"\xEF\xB7\x90\"",
749 "\xEF\xB7\x90", /* bug: not corrected */
750 "\"\\uFFFD\"",
753 /* U+FDEF */
754 "\"\xEF\xB7\xAF\"",
755 "\xEF\xB7\xAF", /* bug: not corrected */
756 "\"\\uFFFD\"",
758 /* Plane 1 .. 16 noncharacters */
760 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
761 "\"\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
762 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
763 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
764 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
765 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
766 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
767 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
768 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
769 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
770 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
771 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
772 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
773 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
774 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
775 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
776 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF\"",
777 /* bug: not corrected */
778 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
779 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
780 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
781 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
782 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
783 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
784 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
785 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
786 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
787 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
788 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
789 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
790 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
791 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
792 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
793 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
794 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
795 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
796 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
797 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
801 int i;
802 QObject *obj;
803 QString *str;
804 const char *json_in, *utf8_out, *utf8_in, *json_out;
806 for (i = 0; test_cases[i].json_in; i++) {
807 json_in = test_cases[i].json_in;
808 utf8_out = test_cases[i].utf8_out;
809 utf8_in = test_cases[i].utf8_in ?: test_cases[i].utf8_out;
810 json_out = test_cases[i].json_out ?: test_cases[i].json_in;
812 obj = qobject_from_json(json_in);
813 if (utf8_out) {
814 str = qobject_to_qstring(obj);
815 g_assert(str);
816 g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
817 } else {
818 g_assert(!obj);
820 qobject_decref(obj);
822 obj = QOBJECT(qstring_from_str(utf8_in));
823 str = qobject_to_json(obj);
824 if (json_out) {
825 g_assert(str);
826 g_assert_cmpstr(qstring_get_str(str), ==, json_out);
827 } else {
828 g_assert(!str);
830 QDECREF(str);
831 qobject_decref(obj);
834 * Disabled, because qobject_from_json() is buggy, and I can't
835 * be bothered to add the expected incorrect results.
836 * FIXME Enable once these bugs have been fixed.
838 if (0 && json_out != json_in) {
839 obj = qobject_from_json(json_out);
840 str = qobject_to_qstring(obj);
841 g_assert(str);
842 g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
847 static void vararg_string(void)
849 int i;
850 struct {
851 const char *decoded;
852 } test_cases[] = {
853 { "hello world" },
854 { "the quick brown fox jumped over the fence" },
858 for (i = 0; test_cases[i].decoded; i++) {
859 QString *str;
861 str = qobject_to_qstring(qobject_from_jsonf("%s",
862 test_cases[i].decoded));
863 g_assert(str);
864 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
866 QDECREF(str);
870 static void simple_number(void)
872 int i;
873 struct {
874 const char *encoded;
875 int64_t decoded;
876 int skip;
877 } test_cases[] = {
878 { "0", 0 },
879 { "1234", 1234 },
880 { "1", 1 },
881 { "-32", -32 },
882 { "-0", 0, .skip = 1 },
883 { },
886 for (i = 0; test_cases[i].encoded; i++) {
887 QInt *qint;
889 qint = qobject_to_qint(qobject_from_json(test_cases[i].encoded));
890 g_assert(qint);
891 g_assert(qint_get_int(qint) == test_cases[i].decoded);
892 if (test_cases[i].skip == 0) {
893 QString *str;
895 str = qobject_to_json(QOBJECT(qint));
896 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
897 QDECREF(str);
900 QDECREF(qint);
904 static void float_number(void)
906 int i;
907 struct {
908 const char *encoded;
909 double decoded;
910 int skip;
911 } test_cases[] = {
912 { "32.43", 32.43 },
913 { "0.222", 0.222 },
914 { "-32.12313", -32.12313 },
915 { "-32.20e-10", -32.20e-10, .skip = 1 },
916 { },
919 for (i = 0; test_cases[i].encoded; i++) {
920 QObject *obj;
921 QFloat *qfloat;
923 obj = qobject_from_json(test_cases[i].encoded);
924 qfloat = qobject_to_qfloat(obj);
925 g_assert(qfloat);
926 g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded);
928 if (test_cases[i].skip == 0) {
929 QString *str;
931 str = qobject_to_json(obj);
932 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
933 QDECREF(str);
936 QDECREF(qfloat);
940 static void vararg_number(void)
942 QInt *qint;
943 QFloat *qfloat;
944 int value = 0x2342;
945 long long value_ll = 0x2342342343LL;
946 double valuef = 2.323423423;
948 qint = qobject_to_qint(qobject_from_jsonf("%d", value));
949 g_assert(qint_get_int(qint) == value);
950 QDECREF(qint);
952 qint = qobject_to_qint(qobject_from_jsonf("%lld", value_ll));
953 g_assert(qint_get_int(qint) == value_ll);
954 QDECREF(qint);
956 qfloat = qobject_to_qfloat(qobject_from_jsonf("%f", valuef));
957 g_assert(qfloat_get_double(qfloat) == valuef);
958 QDECREF(qfloat);
961 static void keyword_literal(void)
963 QObject *obj;
964 QBool *qbool;
965 QObject *null;
966 QString *str;
968 obj = qobject_from_json("true");
969 qbool = qobject_to_qbool(obj);
970 g_assert(qbool);
971 g_assert(qbool_get_bool(qbool) == true);
973 str = qobject_to_json(obj);
974 g_assert(strcmp(qstring_get_str(str), "true") == 0);
975 QDECREF(str);
977 QDECREF(qbool);
979 obj = qobject_from_json("false");
980 qbool = qobject_to_qbool(obj);
981 g_assert(qbool);
982 g_assert(qbool_get_bool(qbool) == false);
984 str = qobject_to_json(obj);
985 g_assert(strcmp(qstring_get_str(str), "false") == 0);
986 QDECREF(str);
988 QDECREF(qbool);
990 qbool = qobject_to_qbool(qobject_from_jsonf("%i", false));
991 g_assert(qbool);
992 g_assert(qbool_get_bool(qbool) == false);
993 QDECREF(qbool);
995 /* Test that non-zero values other than 1 get collapsed to true */
996 qbool = qobject_to_qbool(qobject_from_jsonf("%i", 2));
997 g_assert(qbool);
998 g_assert(qbool_get_bool(qbool) == true);
999 QDECREF(qbool);
1001 obj = qobject_from_json("null");
1002 g_assert(obj != NULL);
1003 g_assert(qobject_type(obj) == QTYPE_QNULL);
1005 null = qnull();
1006 g_assert(null == obj);
1008 qobject_decref(obj);
1009 qobject_decref(null);
1012 typedef struct LiteralQDictEntry LiteralQDictEntry;
1013 typedef struct LiteralQObject LiteralQObject;
1015 struct LiteralQObject
1017 int type;
1018 union {
1019 int64_t qint;
1020 const char *qstr;
1021 LiteralQDictEntry *qdict;
1022 LiteralQObject *qlist;
1023 } value;
1026 struct LiteralQDictEntry
1028 const char *key;
1029 LiteralQObject value;
1032 #define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
1033 #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
1034 #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
1035 #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
1037 typedef struct QListCompareHelper
1039 int index;
1040 LiteralQObject *objs;
1041 int result;
1042 } QListCompareHelper;
1044 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
1046 static void compare_helper(QObject *obj, void *opaque)
1048 QListCompareHelper *helper = opaque;
1050 if (helper->result == 0) {
1051 return;
1054 if (helper->objs[helper->index].type == QTYPE_NONE) {
1055 helper->result = 0;
1056 return;
1059 helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
1062 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
1064 if (!rhs || lhs->type != qobject_type(rhs)) {
1065 return 0;
1068 switch (lhs->type) {
1069 case QTYPE_QINT:
1070 return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
1071 case QTYPE_QSTRING:
1072 return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
1073 case QTYPE_QDICT: {
1074 int i;
1076 for (i = 0; lhs->value.qdict[i].key; i++) {
1077 QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key);
1079 if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
1080 return 0;
1084 return 1;
1086 case QTYPE_QLIST: {
1087 QListCompareHelper helper;
1089 helper.index = 0;
1090 helper.objs = lhs->value.qlist;
1091 helper.result = 1;
1093 qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
1095 return helper.result;
1097 default:
1098 break;
1101 return 0;
1104 static void simple_dict(void)
1106 int i;
1107 struct {
1108 const char *encoded;
1109 LiteralQObject decoded;
1110 } test_cases[] = {
1112 .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
1113 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
1114 { "foo", QLIT_QINT(42) },
1115 { "bar", QLIT_QSTR("hello world") },
1117 })),
1118 }, {
1119 .encoded = "{}",
1120 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
1122 })),
1123 }, {
1124 .encoded = "{\"foo\": 43}",
1125 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
1126 { "foo", QLIT_QINT(43) },
1128 })),
1133 for (i = 0; test_cases[i].encoded; i++) {
1134 QObject *obj;
1135 QString *str;
1137 obj = qobject_from_json(test_cases[i].encoded);
1138 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1140 str = qobject_to_json(obj);
1141 qobject_decref(obj);
1143 obj = qobject_from_json(qstring_get_str(str));
1144 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1145 qobject_decref(obj);
1146 QDECREF(str);
1151 * this generates json of the form:
1152 * a(0,m) = [0, 1, ..., m-1]
1153 * a(n,m) = {
1154 * 'key0': a(0,m),
1155 * 'key1': a(1,m),
1156 * ...
1157 * 'key(n-1)': a(n-1,m)
1160 static void gen_test_json(GString *gstr, int nest_level_max,
1161 int elem_count)
1163 int i;
1165 g_assert(gstr);
1166 if (nest_level_max == 0) {
1167 g_string_append(gstr, "[");
1168 for (i = 0; i < elem_count; i++) {
1169 g_string_append_printf(gstr, "%d", i);
1170 if (i < elem_count - 1) {
1171 g_string_append_printf(gstr, ", ");
1174 g_string_append(gstr, "]");
1175 return;
1178 g_string_append(gstr, "{");
1179 for (i = 0; i < nest_level_max; i++) {
1180 g_string_append_printf(gstr, "'key%d': ", i);
1181 gen_test_json(gstr, i, elem_count);
1182 if (i < nest_level_max - 1) {
1183 g_string_append(gstr, ",");
1186 g_string_append(gstr, "}");
1189 static void large_dict(void)
1191 GString *gstr = g_string_new("");
1192 QObject *obj;
1194 gen_test_json(gstr, 10, 100);
1195 obj = qobject_from_json(gstr->str);
1196 g_assert(obj != NULL);
1198 qobject_decref(obj);
1199 g_string_free(gstr, true);
1202 static void simple_list(void)
1204 int i;
1205 struct {
1206 const char *encoded;
1207 LiteralQObject decoded;
1208 } test_cases[] = {
1210 .encoded = "[43,42]",
1211 .decoded = QLIT_QLIST(((LiteralQObject[]){
1212 QLIT_QINT(43),
1213 QLIT_QINT(42),
1215 })),
1218 .encoded = "[43]",
1219 .decoded = QLIT_QLIST(((LiteralQObject[]){
1220 QLIT_QINT(43),
1222 })),
1225 .encoded = "[]",
1226 .decoded = QLIT_QLIST(((LiteralQObject[]){
1228 })),
1231 .encoded = "[{}]",
1232 .decoded = QLIT_QLIST(((LiteralQObject[]){
1233 QLIT_QDICT(((LiteralQDictEntry[]){
1235 })),
1237 })),
1242 for (i = 0; test_cases[i].encoded; i++) {
1243 QObject *obj;
1244 QString *str;
1246 obj = qobject_from_json(test_cases[i].encoded);
1247 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1249 str = qobject_to_json(obj);
1250 qobject_decref(obj);
1252 obj = qobject_from_json(qstring_get_str(str));
1253 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1254 qobject_decref(obj);
1255 QDECREF(str);
1259 static void simple_whitespace(void)
1261 int i;
1262 struct {
1263 const char *encoded;
1264 LiteralQObject decoded;
1265 } test_cases[] = {
1267 .encoded = " [ 43 , 42 ]",
1268 .decoded = QLIT_QLIST(((LiteralQObject[]){
1269 QLIT_QINT(43),
1270 QLIT_QINT(42),
1272 })),
1275 .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
1276 .decoded = QLIT_QLIST(((LiteralQObject[]){
1277 QLIT_QINT(43),
1278 QLIT_QDICT(((LiteralQDictEntry[]){
1279 { "h", QLIT_QSTR("b") },
1280 { }})),
1281 QLIT_QLIST(((LiteralQObject[]){
1282 { }})),
1283 QLIT_QINT(42),
1285 })),
1288 .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1289 .decoded = QLIT_QLIST(((LiteralQObject[]){
1290 QLIT_QINT(43),
1291 QLIT_QDICT(((LiteralQDictEntry[]){
1292 { "h", QLIT_QSTR("b") },
1293 { "a", QLIT_QINT(32) },
1294 { }})),
1295 QLIT_QLIST(((LiteralQObject[]){
1296 { }})),
1297 QLIT_QINT(42),
1299 })),
1304 for (i = 0; test_cases[i].encoded; i++) {
1305 QObject *obj;
1306 QString *str;
1308 obj = qobject_from_json(test_cases[i].encoded);
1309 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1311 str = qobject_to_json(obj);
1312 qobject_decref(obj);
1314 obj = qobject_from_json(qstring_get_str(str));
1315 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1317 qobject_decref(obj);
1318 QDECREF(str);
1322 static void simple_varargs(void)
1324 QObject *embedded_obj;
1325 QObject *obj;
1326 LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
1327 QLIT_QINT(1),
1328 QLIT_QINT(2),
1329 QLIT_QLIST(((LiteralQObject[]){
1330 QLIT_QINT(32),
1331 QLIT_QINT(42),
1332 {}})),
1333 {}}));
1335 embedded_obj = qobject_from_json("[32, 42]");
1336 g_assert(embedded_obj != NULL);
1338 obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
1339 g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1);
1341 qobject_decref(obj);
1344 static void empty_input(void)
1346 const char *empty = "";
1348 QObject *obj = qobject_from_json(empty);
1349 g_assert(obj == NULL);
1352 static void unterminated_string(void)
1354 QObject *obj = qobject_from_json("\"abc");
1355 g_assert(obj == NULL);
1358 static void unterminated_sq_string(void)
1360 QObject *obj = qobject_from_json("'abc");
1361 g_assert(obj == NULL);
1364 static void unterminated_escape(void)
1366 QObject *obj = qobject_from_json("\"abc\\\"");
1367 g_assert(obj == NULL);
1370 static void unterminated_array(void)
1372 QObject *obj = qobject_from_json("[32");
1373 g_assert(obj == NULL);
1376 static void unterminated_array_comma(void)
1378 QObject *obj = qobject_from_json("[32,");
1379 g_assert(obj == NULL);
1382 static void invalid_array_comma(void)
1384 QObject *obj = qobject_from_json("[32,}");
1385 g_assert(obj == NULL);
1388 static void unterminated_dict(void)
1390 QObject *obj = qobject_from_json("{'abc':32");
1391 g_assert(obj == NULL);
1394 static void unterminated_dict_comma(void)
1396 QObject *obj = qobject_from_json("{'abc':32,");
1397 g_assert(obj == NULL);
1400 static void invalid_dict_comma(void)
1402 QObject *obj = qobject_from_json("{'abc':32,}");
1403 g_assert(obj == NULL);
1406 static void unterminated_literal(void)
1408 QObject *obj = qobject_from_json("nul");
1409 g_assert(obj == NULL);
1412 static char *make_nest(char *buf, size_t cnt)
1414 memset(buf, '[', cnt - 1);
1415 buf[cnt - 1] = '{';
1416 buf[cnt] = '}';
1417 memset(buf + cnt + 1, ']', cnt - 1);
1418 buf[2 * cnt] = 0;
1419 return buf;
1422 static void limits_nesting(void)
1424 enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
1425 char buf[2 * (max_nesting + 1) + 1];
1426 QObject *obj;
1428 obj = qobject_from_json(make_nest(buf, max_nesting));
1429 g_assert(obj != NULL);
1430 qobject_decref(obj);
1432 obj = qobject_from_json(make_nest(buf, max_nesting + 1));
1433 g_assert(obj == NULL);
1436 int main(int argc, char **argv)
1438 g_test_init(&argc, &argv, NULL);
1440 g_test_add_func("/literals/string/simple", simple_string);
1441 g_test_add_func("/literals/string/escaped", escaped_string);
1442 g_test_add_func("/literals/string/utf8", utf8_string);
1443 g_test_add_func("/literals/string/single_quote", single_quote_string);
1444 g_test_add_func("/literals/string/vararg", vararg_string);
1446 g_test_add_func("/literals/number/simple", simple_number);
1447 g_test_add_func("/literals/number/float", float_number);
1448 g_test_add_func("/literals/number/vararg", vararg_number);
1450 g_test_add_func("/literals/keyword", keyword_literal);
1452 g_test_add_func("/dicts/simple_dict", simple_dict);
1453 g_test_add_func("/dicts/large_dict", large_dict);
1454 g_test_add_func("/lists/simple_list", simple_list);
1456 g_test_add_func("/whitespace/simple_whitespace", simple_whitespace);
1458 g_test_add_func("/varargs/simple_varargs", simple_varargs);
1460 g_test_add_func("/errors/empty_input", empty_input);
1461 g_test_add_func("/errors/unterminated/string", unterminated_string);
1462 g_test_add_func("/errors/unterminated/escape", unterminated_escape);
1463 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string);
1464 g_test_add_func("/errors/unterminated/array", unterminated_array);
1465 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma);
1466 g_test_add_func("/errors/unterminated/dict", unterminated_dict);
1467 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma);
1468 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
1469 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
1470 g_test_add_func("/errors/unterminated/literal", unterminated_literal);
1471 g_test_add_func("/errors/limits/nesting", limits_nesting);
1473 return g_test_run();