ui: introduce enum to track VNC client framebuffer update request state
[qemu/ar7.git] / tests / check-qjson.c
blob59227934ce11341cd69e017b4da62f900bddac53
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.
14 #include "qemu/osdep.h"
16 #include "qapi/error.h"
17 #include "qapi/qmp/types.h"
18 #include "qapi/qmp/qjson.h"
19 #include "qapi/qmp/qlit.h"
20 #include "qemu-common.h"
22 static void escaped_string(void)
24 int i;
25 struct {
26 const char *encoded;
27 const char *decoded;
28 int skip;
29 } test_cases[] = {
30 { "\"\\b\"", "\b" },
31 { "\"\\f\"", "\f" },
32 { "\"\\n\"", "\n" },
33 { "\"\\r\"", "\r" },
34 { "\"\\t\"", "\t" },
35 { "\"/\"", "/" },
36 { "\"\\/\"", "/", .skip = 1 },
37 { "\"\\\\\"", "\\" },
38 { "\"\\\"\"", "\"" },
39 { "\"hello world \\\"embedded string\\\"\"",
40 "hello world \"embedded string\"" },
41 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
42 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip = 1 },
43 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
44 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
45 { "'\\b'", "\b", .skip = 1 },
46 { "'\\f'", "\f", .skip = 1 },
47 { "'\\n'", "\n", .skip = 1 },
48 { "'\\r'", "\r", .skip = 1 },
49 { "'\\t'", "\t", .skip = 1 },
50 { "'\\/'", "/", .skip = 1 },
51 { "'\\\\'", "\\", .skip = 1 },
55 for (i = 0; test_cases[i].encoded; i++) {
56 QObject *obj;
57 QString *str;
59 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
60 str = qobject_to_qstring(obj);
61 g_assert(str);
62 g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].decoded);
64 if (test_cases[i].skip == 0) {
65 str = qobject_to_json(obj);
66 g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].encoded);
67 qobject_decref(obj);
70 QDECREF(str);
74 static void simple_string(void)
76 int i;
77 struct {
78 const char *encoded;
79 const char *decoded;
80 } test_cases[] = {
81 { "\"hello world\"", "hello world" },
82 { "\"the quick brown fox jumped over the fence\"",
83 "the quick brown fox jumped over the fence" },
87 for (i = 0; test_cases[i].encoded; i++) {
88 QObject *obj;
89 QString *str;
91 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
92 str = qobject_to_qstring(obj);
93 g_assert(str);
94 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
96 str = qobject_to_json(obj);
97 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
99 qobject_decref(obj);
101 QDECREF(str);
105 static void single_quote_string(void)
107 int i;
108 struct {
109 const char *encoded;
110 const char *decoded;
111 } test_cases[] = {
112 { "'hello world'", "hello world" },
113 { "'the quick brown fox \\' jumped over the fence'",
114 "the quick brown fox ' jumped over the fence" },
118 for (i = 0; test_cases[i].encoded; i++) {
119 QObject *obj;
120 QString *str;
122 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
123 str = qobject_to_qstring(obj);
124 g_assert(str);
125 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
127 QDECREF(str);
131 static void utf8_string(void)
134 * FIXME Current behavior for invalid UTF-8 sequences is
135 * incorrect. This test expects current, incorrect results.
136 * They're all marked "bug:" below, and are to be replaced by
137 * correct ones as the bugs get fixed.
139 * The JSON parser rejects some invalid sequences, but accepts
140 * others without correcting the problem.
142 * We should either reject all invalid sequences, or minimize
143 * overlong sequences and replace all other invalid sequences by a
144 * suitable replacement character. A common choice for
145 * replacement is U+FFFD.
147 * Problem: we can't easily deal with embedded U+0000. Parsing
148 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
149 * which gets misinterpreted as NUL-terminated "this ". We should
150 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
151 * UTF-8").
153 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
154 * capability and stress test at
155 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
157 static const struct {
158 const char *json_in;
159 const char *utf8_out;
160 const char *json_out; /* defaults to @json_in */
161 const char *utf8_in; /* defaults to @utf8_out */
162 } test_cases[] = {
164 * Bug markers used here:
165 * - bug: not corrected
166 * JSON parser fails to correct invalid sequence(s)
167 * - bug: rejected
168 * JSON parser rejects invalid sequence(s)
169 * We may choose to define this as feature
170 * - bug: want "..."
171 * JSON parser produces incorrect result, this is the
172 * correct one, assuming replacement character U+FFFF
173 * We may choose to reject instead of replace
176 /* 1 Some correct UTF-8 text */
178 /* a bit of German */
179 "\"Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
180 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.\"",
181 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
182 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
183 "\"Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
184 " jeden gr\\u00F6\\u00DFeren Zwerg.\"",
187 /* a bit of Greek */
188 "\"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5\"",
189 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
190 "\"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5\"",
192 /* 2 Boundary condition test cases */
193 /* 2.1 First possible sequence of a certain length */
194 /* 2.1.1 1 byte U+0000 */
196 "\"\\u0000\"",
197 "", /* bug: want overlong "\xC0\x80" */
198 "\"\\u0000\"",
199 "\xC0\x80",
201 /* 2.1.2 2 bytes U+0080 */
203 "\"\xC2\x80\"",
204 "\xC2\x80",
205 "\"\\u0080\"",
207 /* 2.1.3 3 bytes U+0800 */
209 "\"\xE0\xA0\x80\"",
210 "\xE0\xA0\x80",
211 "\"\\u0800\"",
213 /* 2.1.4 4 bytes U+10000 */
215 "\"\xF0\x90\x80\x80\"",
216 "\xF0\x90\x80\x80",
217 "\"\\uD800\\uDC00\"",
219 /* 2.1.5 5 bytes U+200000 */
221 "\"\xF8\x88\x80\x80\x80\"",
222 NULL, /* bug: rejected */
223 "\"\\uFFFD\"",
224 "\xF8\x88\x80\x80\x80",
226 /* 2.1.6 6 bytes U+4000000 */
228 "\"\xFC\x84\x80\x80\x80\x80\"",
229 NULL, /* bug: rejected */
230 "\"\\uFFFD\"",
231 "\xFC\x84\x80\x80\x80\x80",
233 /* 2.2 Last possible sequence of a certain length */
234 /* 2.2.1 1 byte U+007F */
236 "\"\x7F\"",
237 "\x7F",
238 "\"\\u007F\"",
240 /* 2.2.2 2 bytes U+07FF */
242 "\"\xDF\xBF\"",
243 "\xDF\xBF",
244 "\"\\u07FF\"",
247 * 2.2.3 3 bytes U+FFFC
248 * The last possible sequence is actually U+FFFF. But that's
249 * a noncharacter, and already covered by its own test case
250 * under 5.3. Same for U+FFFE. U+FFFD is the last character
251 * in the BMP, and covered under 2.3. Because of U+FFFD's
252 * special role as replacement character, it's worth testing
253 * U+FFFC here.
256 "\"\xEF\xBF\xBC\"",
257 "\xEF\xBF\xBC",
258 "\"\\uFFFC\"",
260 /* 2.2.4 4 bytes U+1FFFFF */
262 "\"\xF7\xBF\xBF\xBF\"",
263 NULL, /* bug: rejected */
264 "\"\\uFFFD\"",
265 "\xF7\xBF\xBF\xBF",
267 /* 2.2.5 5 bytes U+3FFFFFF */
269 "\"\xFB\xBF\xBF\xBF\xBF\"",
270 NULL, /* bug: rejected */
271 "\"\\uFFFD\"",
272 "\xFB\xBF\xBF\xBF\xBF",
274 /* 2.2.6 6 bytes U+7FFFFFFF */
276 "\"\xFD\xBF\xBF\xBF\xBF\xBF\"",
277 NULL, /* bug: rejected */
278 "\"\\uFFFD\"",
279 "\xFD\xBF\xBF\xBF\xBF\xBF",
281 /* 2.3 Other boundary conditions */
283 /* last one before surrogate range: U+D7FF */
284 "\"\xED\x9F\xBF\"",
285 "\xED\x9F\xBF",
286 "\"\\uD7FF\"",
289 /* first one after surrogate range: U+E000 */
290 "\"\xEE\x80\x80\"",
291 "\xEE\x80\x80",
292 "\"\\uE000\"",
295 /* last one in BMP: U+FFFD */
296 "\"\xEF\xBF\xBD\"",
297 "\xEF\xBF\xBD",
298 "\"\\uFFFD\"",
301 /* last one in last plane: U+10FFFD */
302 "\"\xF4\x8F\xBF\xBD\"",
303 "\xF4\x8F\xBF\xBD",
304 "\"\\uDBFF\\uDFFD\""
307 /* first one beyond Unicode range: U+110000 */
308 "\"\xF4\x90\x80\x80\"",
309 "\xF4\x90\x80\x80",
310 "\"\\uFFFD\"",
312 /* 3 Malformed sequences */
313 /* 3.1 Unexpected continuation bytes */
314 /* 3.1.1 First continuation byte */
316 "\"\x80\"",
317 "\x80", /* bug: not corrected */
318 "\"\\uFFFD\"",
320 /* 3.1.2 Last continuation byte */
322 "\"\xBF\"",
323 "\xBF", /* bug: not corrected */
324 "\"\\uFFFD\"",
326 /* 3.1.3 2 continuation bytes */
328 "\"\x80\xBF\"",
329 "\x80\xBF", /* bug: not corrected */
330 "\"\\uFFFD\\uFFFD\"",
332 /* 3.1.4 3 continuation bytes */
334 "\"\x80\xBF\x80\"",
335 "\x80\xBF\x80", /* bug: not corrected */
336 "\"\\uFFFD\\uFFFD\\uFFFD\"",
338 /* 3.1.5 4 continuation bytes */
340 "\"\x80\xBF\x80\xBF\"",
341 "\x80\xBF\x80\xBF", /* bug: not corrected */
342 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
344 /* 3.1.6 5 continuation bytes */
346 "\"\x80\xBF\x80\xBF\x80\"",
347 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
348 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
350 /* 3.1.7 6 continuation bytes */
352 "\"\x80\xBF\x80\xBF\x80\xBF\"",
353 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
354 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
356 /* 3.1.8 7 continuation bytes */
358 "\"\x80\xBF\x80\xBF\x80\xBF\x80\"",
359 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
360 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
362 /* 3.1.9 Sequence of all 64 possible continuation bytes */
364 "\"\x80\x81\x82\x83\x84\x85\x86\x87"
365 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
366 "\x90\x91\x92\x93\x94\x95\x96\x97"
367 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
368 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
369 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
370 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
371 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\"",
372 /* bug: not corrected */
373 "\x80\x81\x82\x83\x84\x85\x86\x87"
374 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
375 "\x90\x91\x92\x93\x94\x95\x96\x97"
376 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
377 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
378 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
379 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
380 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
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"
386 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
387 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
388 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\""
390 /* 3.2 Lonely start characters */
391 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
393 "\"\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
394 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
395 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
396 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF \"",
397 NULL, /* bug: rejected */
398 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
399 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
400 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
401 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
402 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
403 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
404 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
405 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
407 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
409 "\"\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
410 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF \"",
411 /* bug: not corrected */
412 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
413 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
414 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
415 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
417 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
419 "\"\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 \"",
420 NULL, /* bug: rejected */
421 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
422 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
424 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
426 "\"\xF8 \xF9 \xFA \xFB \"",
427 NULL, /* bug: rejected */
428 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
429 "\xF8 \xF9 \xFA \xFB ",
431 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
433 "\"\xFC \xFD \"",
434 NULL, /* bug: rejected */
435 "\"\\uFFFD \\uFFFD \"",
436 "\xFC \xFD ",
438 /* 3.3 Sequences with last continuation byte missing */
439 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
441 "\"\xC0\"",
442 NULL, /* bug: rejected */
443 "\"\\uFFFD\"",
444 "\xC0",
446 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
448 "\"\xE0\x80\"",
449 "\xE0\x80", /* bug: not corrected */
450 "\"\\uFFFD\"",
452 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
454 "\"\xF0\x80\x80\"",
455 "\xF0\x80\x80", /* bug: not corrected */
456 "\"\\uFFFD\"",
458 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
460 "\"\xF8\x80\x80\x80\"",
461 NULL, /* bug: rejected */
462 "\"\\uFFFD\"",
463 "\xF8\x80\x80\x80",
465 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
467 "\"\xFC\x80\x80\x80\x80\"",
468 NULL, /* bug: rejected */
469 "\"\\uFFFD\"",
470 "\xFC\x80\x80\x80\x80",
472 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
474 "\"\xDF\"",
475 "\xDF", /* bug: not corrected */
476 "\"\\uFFFD\"",
478 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
480 "\"\xEF\xBF\"",
481 "\xEF\xBF", /* bug: not corrected */
482 "\"\\uFFFD\"",
484 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
486 "\"\xF7\xBF\xBF\"",
487 NULL, /* bug: rejected */
488 "\"\\uFFFD\"",
489 "\xF7\xBF\xBF",
491 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
493 "\"\xFB\xBF\xBF\xBF\"",
494 NULL, /* bug: rejected */
495 "\"\\uFFFD\"",
496 "\xFB\xBF\xBF\xBF",
498 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
500 "\"\xFD\xBF\xBF\xBF\xBF\"",
501 NULL, /* bug: rejected */
502 "\"\\uFFFD\"",
503 "\xFD\xBF\xBF\xBF\xBF",
505 /* 3.4 Concatenation of incomplete sequences */
507 "\"\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
508 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF\"",
509 NULL, /* bug: rejected */
510 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
511 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
512 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
513 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
515 /* 3.5 Impossible bytes */
517 "\"\xFE\"",
518 NULL, /* bug: rejected */
519 "\"\\uFFFD\"",
520 "\xFE",
523 "\"\xFF\"",
524 NULL, /* bug: rejected */
525 "\"\\uFFFD\"",
526 "\xFF",
529 "\"\xFE\xFE\xFF\xFF\"",
530 NULL, /* bug: rejected */
531 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
532 "\xFE\xFE\xFF\xFF",
534 /* 4 Overlong sequences */
535 /* 4.1 Overlong '/' */
537 "\"\xC0\xAF\"",
538 NULL, /* bug: rejected */
539 "\"\\uFFFD\"",
540 "\xC0\xAF",
543 "\"\xE0\x80\xAF\"",
544 "\xE0\x80\xAF", /* bug: not corrected */
545 "\"\\uFFFD\"",
548 "\"\xF0\x80\x80\xAF\"",
549 "\xF0\x80\x80\xAF", /* bug: not corrected */
550 "\"\\uFFFD\"",
553 "\"\xF8\x80\x80\x80\xAF\"",
554 NULL, /* bug: rejected */
555 "\"\\uFFFD\"",
556 "\xF8\x80\x80\x80\xAF",
559 "\"\xFC\x80\x80\x80\x80\xAF\"",
560 NULL, /* bug: rejected */
561 "\"\\uFFFD\"",
562 "\xFC\x80\x80\x80\x80\xAF",
565 * 4.2 Maximum overlong sequences
566 * Highest Unicode value that is still resulting in an
567 * overlong sequence if represented with the given number of
568 * bytes. This is a boundary test for safe UTF-8 decoders.
571 /* \U+007F */
572 "\"\xC1\xBF\"",
573 NULL, /* bug: rejected */
574 "\"\\uFFFD\"",
575 "\xC1\xBF",
578 /* \U+07FF */
579 "\"\xE0\x9F\xBF\"",
580 "\xE0\x9F\xBF", /* bug: not corrected */
581 "\"\\uFFFD\"",
585 * \U+FFFC
586 * The actual maximum would be U+FFFF, but that's a
587 * noncharacter. Testing U+FFFC seems more useful. See
588 * also 2.2.3
590 "\"\xF0\x8F\xBF\xBC\"",
591 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
592 "\"\\uFFFD\"",
595 /* \U+1FFFFF */
596 "\"\xF8\x87\xBF\xBF\xBF\"",
597 NULL, /* bug: rejected */
598 "\"\\uFFFD\"",
599 "\xF8\x87\xBF\xBF\xBF",
602 /* \U+3FFFFFF */
603 "\"\xFC\x83\xBF\xBF\xBF\xBF\"",
604 NULL, /* bug: rejected */
605 "\"\\uFFFD\"",
606 "\xFC\x83\xBF\xBF\xBF\xBF",
608 /* 4.3 Overlong representation of the NUL character */
610 /* \U+0000 */
611 "\"\xC0\x80\"",
612 NULL, /* bug: rejected */
613 "\"\\u0000\"",
614 "\xC0\x80",
617 /* \U+0000 */
618 "\"\xE0\x80\x80\"",
619 "\xE0\x80\x80", /* bug: not corrected */
620 "\"\\uFFFD\"",
623 /* \U+0000 */
624 "\"\xF0\x80\x80\x80\"",
625 "\xF0\x80\x80\x80", /* bug: not corrected */
626 "\"\\uFFFD\"",
629 /* \U+0000 */
630 "\"\xF8\x80\x80\x80\x80\"",
631 NULL, /* bug: rejected */
632 "\"\\uFFFD\"",
633 "\xF8\x80\x80\x80\x80",
636 /* \U+0000 */
637 "\"\xFC\x80\x80\x80\x80\x80\"",
638 NULL, /* bug: rejected */
639 "\"\\uFFFD\"",
640 "\xFC\x80\x80\x80\x80\x80",
642 /* 5 Illegal code positions */
643 /* 5.1 Single UTF-16 surrogates */
645 /* \U+D800 */
646 "\"\xED\xA0\x80\"",
647 "\xED\xA0\x80", /* bug: not corrected */
648 "\"\\uFFFD\"",
651 /* \U+DB7F */
652 "\"\xED\xAD\xBF\"",
653 "\xED\xAD\xBF", /* bug: not corrected */
654 "\"\\uFFFD\"",
657 /* \U+DB80 */
658 "\"\xED\xAE\x80\"",
659 "\xED\xAE\x80", /* bug: not corrected */
660 "\"\\uFFFD\"",
663 /* \U+DBFF */
664 "\"\xED\xAF\xBF\"",
665 "\xED\xAF\xBF", /* bug: not corrected */
666 "\"\\uFFFD\"",
669 /* \U+DC00 */
670 "\"\xED\xB0\x80\"",
671 "\xED\xB0\x80", /* bug: not corrected */
672 "\"\\uFFFD\"",
675 /* \U+DF80 */
676 "\"\xED\xBE\x80\"",
677 "\xED\xBE\x80", /* bug: not corrected */
678 "\"\\uFFFD\"",
681 /* \U+DFFF */
682 "\"\xED\xBF\xBF\"",
683 "\xED\xBF\xBF", /* bug: not corrected */
684 "\"\\uFFFD\"",
686 /* 5.2 Paired UTF-16 surrogates */
688 /* \U+D800\U+DC00 */
689 "\"\xED\xA0\x80\xED\xB0\x80\"",
690 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
691 "\"\\uFFFD\\uFFFD\"",
694 /* \U+D800\U+DFFF */
695 "\"\xED\xA0\x80\xED\xBF\xBF\"",
696 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
697 "\"\\uFFFD\\uFFFD\"",
700 /* \U+DB7F\U+DC00 */
701 "\"\xED\xAD\xBF\xED\xB0\x80\"",
702 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
703 "\"\\uFFFD\\uFFFD\"",
706 /* \U+DB7F\U+DFFF */
707 "\"\xED\xAD\xBF\xED\xBF\xBF\"",
708 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
709 "\"\\uFFFD\\uFFFD\"",
712 /* \U+DB80\U+DC00 */
713 "\"\xED\xAE\x80\xED\xB0\x80\"",
714 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
715 "\"\\uFFFD\\uFFFD\"",
718 /* \U+DB80\U+DFFF */
719 "\"\xED\xAE\x80\xED\xBF\xBF\"",
720 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
721 "\"\\uFFFD\\uFFFD\"",
724 /* \U+DBFF\U+DC00 */
725 "\"\xED\xAF\xBF\xED\xB0\x80\"",
726 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
727 "\"\\uFFFD\\uFFFD\"",
730 /* \U+DBFF\U+DFFF */
731 "\"\xED\xAF\xBF\xED\xBF\xBF\"",
732 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
733 "\"\\uFFFD\\uFFFD\"",
735 /* 5.3 Other illegal code positions */
736 /* BMP noncharacters */
738 /* \U+FFFE */
739 "\"\xEF\xBF\xBE\"",
740 "\xEF\xBF\xBE", /* bug: not corrected */
741 "\"\\uFFFD\"",
744 /* \U+FFFF */
745 "\"\xEF\xBF\xBF\"",
746 "\xEF\xBF\xBF", /* bug: not corrected */
747 "\"\\uFFFD\"",
750 /* U+FDD0 */
751 "\"\xEF\xB7\x90\"",
752 "\xEF\xB7\x90", /* bug: not corrected */
753 "\"\\uFFFD\"",
756 /* U+FDEF */
757 "\"\xEF\xB7\xAF\"",
758 "\xEF\xB7\xAF", /* bug: not corrected */
759 "\"\\uFFFD\"",
761 /* Plane 1 .. 16 noncharacters */
763 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
764 "\"\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
765 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
766 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
767 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
768 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
769 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
770 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
771 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
772 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
773 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
774 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
775 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
776 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
777 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
778 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
779 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF\"",
780 /* bug: not corrected */
781 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
782 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
783 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
784 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
785 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
786 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
787 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
788 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
789 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
790 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
791 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
792 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
793 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
794 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
795 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
796 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
797 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
798 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
799 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
800 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
804 int i;
805 QObject *obj;
806 QString *str;
807 const char *json_in, *utf8_out, *utf8_in, *json_out;
809 for (i = 0; test_cases[i].json_in; i++) {
810 json_in = test_cases[i].json_in;
811 utf8_out = test_cases[i].utf8_out;
812 utf8_in = test_cases[i].utf8_in ?: test_cases[i].utf8_out;
813 json_out = test_cases[i].json_out ?: test_cases[i].json_in;
815 obj = qobject_from_json(json_in, utf8_out ? &error_abort : NULL);
816 if (utf8_out) {
817 str = qobject_to_qstring(obj);
818 g_assert(str);
819 g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
820 } else {
821 g_assert(!obj);
823 qobject_decref(obj);
825 obj = QOBJECT(qstring_from_str(utf8_in));
826 str = qobject_to_json(obj);
827 if (json_out) {
828 g_assert(str);
829 g_assert_cmpstr(qstring_get_str(str), ==, json_out);
830 } else {
831 g_assert(!str);
833 QDECREF(str);
834 qobject_decref(obj);
837 * Disabled, because qobject_from_json() is buggy, and I can't
838 * be bothered to add the expected incorrect results.
839 * FIXME Enable once these bugs have been fixed.
841 if (0 && json_out != json_in) {
842 obj = qobject_from_json(json_out, &error_abort);
843 str = qobject_to_qstring(obj);
844 g_assert(str);
845 g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
850 static void vararg_string(void)
852 int i;
853 struct {
854 const char *decoded;
855 } test_cases[] = {
856 { "hello world" },
857 { "the quick brown fox jumped over the fence" },
861 for (i = 0; test_cases[i].decoded; i++) {
862 QString *str;
864 str = qobject_to_qstring(qobject_from_jsonf("%s",
865 test_cases[i].decoded));
866 g_assert(str);
867 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
869 QDECREF(str);
873 static void simple_number(void)
875 int i;
876 struct {
877 const char *encoded;
878 int64_t decoded;
879 int skip;
880 } test_cases[] = {
881 { "0", 0 },
882 { "1234", 1234 },
883 { "1", 1 },
884 { "-32", -32 },
885 { "-0", 0, .skip = 1 },
886 { },
889 for (i = 0; test_cases[i].encoded; i++) {
890 QNum *qnum;
891 int64_t val;
893 qnum = qobject_to_qnum(qobject_from_json(test_cases[i].encoded,
894 &error_abort));
895 g_assert(qnum);
896 g_assert(qnum_get_try_int(qnum, &val));
897 g_assert_cmpint(val, ==, test_cases[i].decoded);
898 if (test_cases[i].skip == 0) {
899 QString *str;
901 str = qobject_to_json(QOBJECT(qnum));
902 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
903 QDECREF(str);
906 QDECREF(qnum);
910 static void large_number(void)
912 const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
913 const char *gtu64 = "18446744073709551616"; /* 2^64 */
914 const char *lti64 = "-9223372036854775809"; /* -2^63 - 1 */
915 QNum *qnum;
916 QString *str;
917 uint64_t val;
918 int64_t ival;
920 qnum = qobject_to_qnum(qobject_from_json(maxu64, &error_abort));
921 g_assert(qnum);
922 g_assert_cmpuint(qnum_get_uint(qnum), ==, 18446744073709551615U);
923 g_assert(!qnum_get_try_int(qnum, &ival));
925 str = qobject_to_json(QOBJECT(qnum));
926 g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
927 QDECREF(str);
928 QDECREF(qnum);
930 qnum = qobject_to_qnum(qobject_from_json(gtu64, &error_abort));
931 g_assert(qnum);
932 g_assert_cmpfloat(qnum_get_double(qnum), ==, 18446744073709552e3);
933 g_assert(!qnum_get_try_uint(qnum, &val));
934 g_assert(!qnum_get_try_int(qnum, &ival));
936 str = qobject_to_json(QOBJECT(qnum));
937 g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
938 QDECREF(str);
939 QDECREF(qnum);
941 qnum = qobject_to_qnum(qobject_from_json(lti64, &error_abort));
942 g_assert(qnum);
943 g_assert_cmpfloat(qnum_get_double(qnum), ==, -92233720368547758e2);
944 g_assert(!qnum_get_try_uint(qnum, &val));
945 g_assert(!qnum_get_try_int(qnum, &ival));
947 str = qobject_to_json(QOBJECT(qnum));
948 g_assert_cmpstr(qstring_get_str(str), ==, "-9223372036854775808");
949 QDECREF(str);
950 QDECREF(qnum);
953 static void float_number(void)
955 int i;
956 struct {
957 const char *encoded;
958 double decoded;
959 int skip;
960 } test_cases[] = {
961 { "32.43", 32.43 },
962 { "0.222", 0.222 },
963 { "-32.12313", -32.12313 },
964 { "-32.20e-10", -32.20e-10, .skip = 1 },
965 { },
968 for (i = 0; test_cases[i].encoded; i++) {
969 QObject *obj;
970 QNum *qnum;
972 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
973 qnum = qobject_to_qnum(obj);
974 g_assert(qnum);
975 g_assert(qnum_get_double(qnum) == test_cases[i].decoded);
977 if (test_cases[i].skip == 0) {
978 QString *str;
980 str = qobject_to_json(obj);
981 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
982 QDECREF(str);
985 QDECREF(qnum);
989 static void vararg_number(void)
991 QNum *qnum;
992 int value = 0x2342;
993 long long value_ll = 0x2342342343LL;
994 double valuef = 2.323423423;
995 int64_t val;
997 qnum = qobject_to_qnum(qobject_from_jsonf("%d", value));
998 g_assert(qnum_get_try_int(qnum, &val));
999 g_assert_cmpint(val, ==, value);
1000 QDECREF(qnum);
1002 qnum = qobject_to_qnum(qobject_from_jsonf("%lld", value_ll));
1003 g_assert(qnum_get_try_int(qnum, &val));
1004 g_assert_cmpint(val, ==, value_ll);
1005 QDECREF(qnum);
1007 qnum = qobject_to_qnum(qobject_from_jsonf("%f", valuef));
1008 g_assert(qnum_get_double(qnum) == valuef);
1009 QDECREF(qnum);
1012 static void keyword_literal(void)
1014 QObject *obj;
1015 QBool *qbool;
1016 QNull *null;
1017 QString *str;
1019 obj = qobject_from_json("true", &error_abort);
1020 qbool = qobject_to_qbool(obj);
1021 g_assert(qbool);
1022 g_assert(qbool_get_bool(qbool) == true);
1024 str = qobject_to_json(obj);
1025 g_assert(strcmp(qstring_get_str(str), "true") == 0);
1026 QDECREF(str);
1028 QDECREF(qbool);
1030 obj = qobject_from_json("false", &error_abort);
1031 qbool = qobject_to_qbool(obj);
1032 g_assert(qbool);
1033 g_assert(qbool_get_bool(qbool) == false);
1035 str = qobject_to_json(obj);
1036 g_assert(strcmp(qstring_get_str(str), "false") == 0);
1037 QDECREF(str);
1039 QDECREF(qbool);
1041 qbool = qobject_to_qbool(qobject_from_jsonf("%i", false));
1042 g_assert(qbool);
1043 g_assert(qbool_get_bool(qbool) == false);
1044 QDECREF(qbool);
1046 /* Test that non-zero values other than 1 get collapsed to true */
1047 qbool = qobject_to_qbool(qobject_from_jsonf("%i", 2));
1048 g_assert(qbool);
1049 g_assert(qbool_get_bool(qbool) == true);
1050 QDECREF(qbool);
1052 obj = qobject_from_json("null", &error_abort);
1053 g_assert(obj != NULL);
1054 g_assert(qobject_type(obj) == QTYPE_QNULL);
1056 null = qnull();
1057 g_assert(QOBJECT(null) == obj);
1059 qobject_decref(obj);
1060 QDECREF(null);
1063 static void simple_dict(void)
1065 int i;
1066 struct {
1067 const char *encoded;
1068 QLitObject decoded;
1069 } test_cases[] = {
1071 .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
1072 .decoded = QLIT_QDICT(((QLitDictEntry[]){
1073 { "foo", QLIT_QNUM(42) },
1074 { "bar", QLIT_QSTR("hello world") },
1076 })),
1077 }, {
1078 .encoded = "{}",
1079 .decoded = QLIT_QDICT(((QLitDictEntry[]){
1081 })),
1082 }, {
1083 .encoded = "{\"foo\": 43}",
1084 .decoded = QLIT_QDICT(((QLitDictEntry[]){
1085 { "foo", QLIT_QNUM(43) },
1087 })),
1092 for (i = 0; test_cases[i].encoded; i++) {
1093 QObject *obj;
1094 QString *str;
1096 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1097 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1099 str = qobject_to_json(obj);
1100 qobject_decref(obj);
1102 obj = qobject_from_json(qstring_get_str(str), &error_abort);
1103 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1104 qobject_decref(obj);
1105 QDECREF(str);
1110 * this generates json of the form:
1111 * a(0,m) = [0, 1, ..., m-1]
1112 * a(n,m) = {
1113 * 'key0': a(0,m),
1114 * 'key1': a(1,m),
1115 * ...
1116 * 'key(n-1)': a(n-1,m)
1119 static void gen_test_json(GString *gstr, int nest_level_max,
1120 int elem_count)
1122 int i;
1124 g_assert(gstr);
1125 if (nest_level_max == 0) {
1126 g_string_append(gstr, "[");
1127 for (i = 0; i < elem_count; i++) {
1128 g_string_append_printf(gstr, "%d", i);
1129 if (i < elem_count - 1) {
1130 g_string_append_printf(gstr, ", ");
1133 g_string_append(gstr, "]");
1134 return;
1137 g_string_append(gstr, "{");
1138 for (i = 0; i < nest_level_max; i++) {
1139 g_string_append_printf(gstr, "'key%d': ", i);
1140 gen_test_json(gstr, i, elem_count);
1141 if (i < nest_level_max - 1) {
1142 g_string_append(gstr, ",");
1145 g_string_append(gstr, "}");
1148 static void large_dict(void)
1150 GString *gstr = g_string_new("");
1151 QObject *obj;
1153 gen_test_json(gstr, 10, 100);
1154 obj = qobject_from_json(gstr->str, &error_abort);
1155 g_assert(obj != NULL);
1157 qobject_decref(obj);
1158 g_string_free(gstr, true);
1161 static void simple_list(void)
1163 int i;
1164 struct {
1165 const char *encoded;
1166 QLitObject decoded;
1167 } test_cases[] = {
1169 .encoded = "[43,42]",
1170 .decoded = QLIT_QLIST(((QLitObject[]){
1171 QLIT_QNUM(43),
1172 QLIT_QNUM(42),
1174 })),
1177 .encoded = "[43]",
1178 .decoded = QLIT_QLIST(((QLitObject[]){
1179 QLIT_QNUM(43),
1181 })),
1184 .encoded = "[]",
1185 .decoded = QLIT_QLIST(((QLitObject[]){
1187 })),
1190 .encoded = "[{}]",
1191 .decoded = QLIT_QLIST(((QLitObject[]){
1192 QLIT_QDICT(((QLitDictEntry[]){
1194 })),
1196 })),
1201 for (i = 0; test_cases[i].encoded; i++) {
1202 QObject *obj;
1203 QString *str;
1205 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1206 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1208 str = qobject_to_json(obj);
1209 qobject_decref(obj);
1211 obj = qobject_from_json(qstring_get_str(str), &error_abort);
1212 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1213 qobject_decref(obj);
1214 QDECREF(str);
1218 static void simple_whitespace(void)
1220 int i;
1221 struct {
1222 const char *encoded;
1223 QLitObject decoded;
1224 } test_cases[] = {
1226 .encoded = " [ 43 , 42 ]",
1227 .decoded = QLIT_QLIST(((QLitObject[]){
1228 QLIT_QNUM(43),
1229 QLIT_QNUM(42),
1231 })),
1234 .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
1235 .decoded = QLIT_QLIST(((QLitObject[]){
1236 QLIT_QNUM(43),
1237 QLIT_QDICT(((QLitDictEntry[]){
1238 { "h", QLIT_QSTR("b") },
1239 { }})),
1240 QLIT_QLIST(((QLitObject[]){
1241 { }})),
1242 QLIT_QNUM(42),
1244 })),
1247 .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1248 .decoded = QLIT_QLIST(((QLitObject[]){
1249 QLIT_QNUM(43),
1250 QLIT_QDICT(((QLitDictEntry[]){
1251 { "h", QLIT_QSTR("b") },
1252 { "a", QLIT_QNUM(32) },
1253 { }})),
1254 QLIT_QLIST(((QLitObject[]){
1255 { }})),
1256 QLIT_QNUM(42),
1258 })),
1263 for (i = 0; test_cases[i].encoded; i++) {
1264 QObject *obj;
1265 QString *str;
1267 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1268 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1270 str = qobject_to_json(obj);
1271 qobject_decref(obj);
1273 obj = qobject_from_json(qstring_get_str(str), &error_abort);
1274 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1276 qobject_decref(obj);
1277 QDECREF(str);
1281 static void simple_varargs(void)
1283 QObject *embedded_obj;
1284 QObject *obj;
1285 QLitObject decoded = QLIT_QLIST(((QLitObject[]){
1286 QLIT_QNUM(1),
1287 QLIT_QNUM(2),
1288 QLIT_QLIST(((QLitObject[]){
1289 QLIT_QNUM(32),
1290 QLIT_QNUM(42),
1291 {}})),
1292 {}}));
1294 embedded_obj = qobject_from_json("[32, 42]", &error_abort);
1295 g_assert(embedded_obj != NULL);
1297 obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
1298 g_assert(qlit_equal_qobject(&decoded, obj));
1300 qobject_decref(obj);
1303 static void empty_input(void)
1305 const char *empty = "";
1306 QObject *obj = qobject_from_json(empty, &error_abort);
1307 g_assert(obj == NULL);
1310 static void unterminated_string(void)
1312 Error *err = NULL;
1313 QObject *obj = qobject_from_json("\"abc", &err);
1314 g_assert(!err); /* BUG */
1315 g_assert(obj == NULL);
1318 static void unterminated_sq_string(void)
1320 Error *err = NULL;
1321 QObject *obj = qobject_from_json("'abc", &err);
1322 g_assert(!err); /* BUG */
1323 g_assert(obj == NULL);
1326 static void unterminated_escape(void)
1328 Error *err = NULL;
1329 QObject *obj = qobject_from_json("\"abc\\\"", &err);
1330 g_assert(!err); /* BUG */
1331 g_assert(obj == NULL);
1334 static void unterminated_array(void)
1336 Error *err = NULL;
1337 QObject *obj = qobject_from_json("[32", &err);
1338 g_assert(!err); /* BUG */
1339 g_assert(obj == NULL);
1342 static void unterminated_array_comma(void)
1344 Error *err = NULL;
1345 QObject *obj = qobject_from_json("[32,", &err);
1346 g_assert(!err); /* BUG */
1347 g_assert(obj == NULL);
1350 static void invalid_array_comma(void)
1352 Error *err = NULL;
1353 QObject *obj = qobject_from_json("[32,}", &err);
1354 error_free_or_abort(&err);
1355 g_assert(obj == NULL);
1358 static void unterminated_dict(void)
1360 Error *err = NULL;
1361 QObject *obj = qobject_from_json("{'abc':32", &err);
1362 g_assert(!err); /* BUG */
1363 g_assert(obj == NULL);
1366 static void unterminated_dict_comma(void)
1368 Error *err = NULL;
1369 QObject *obj = qobject_from_json("{'abc':32,", &err);
1370 g_assert(!err); /* BUG */
1371 g_assert(obj == NULL);
1374 static void invalid_dict_comma(void)
1376 Error *err = NULL;
1377 QObject *obj = qobject_from_json("{'abc':32,}", &err);
1378 error_free_or_abort(&err);
1379 g_assert(obj == NULL);
1382 static void unterminated_literal(void)
1384 Error *err = NULL;
1385 QObject *obj = qobject_from_json("nul", &err);
1386 error_free_or_abort(&err);
1387 g_assert(obj == NULL);
1390 static char *make_nest(char *buf, size_t cnt)
1392 memset(buf, '[', cnt - 1);
1393 buf[cnt - 1] = '{';
1394 buf[cnt] = '}';
1395 memset(buf + cnt + 1, ']', cnt - 1);
1396 buf[2 * cnt] = 0;
1397 return buf;
1400 static void limits_nesting(void)
1402 Error *err = NULL;
1403 enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
1404 char buf[2 * (max_nesting + 1) + 1];
1405 QObject *obj;
1407 obj = qobject_from_json(make_nest(buf, max_nesting), &error_abort);
1408 g_assert(obj != NULL);
1409 qobject_decref(obj);
1411 obj = qobject_from_json(make_nest(buf, max_nesting + 1), &err);
1412 error_free_or_abort(&err);
1413 g_assert(obj == NULL);
1416 int main(int argc, char **argv)
1418 g_test_init(&argc, &argv, NULL);
1420 g_test_add_func("/literals/string/simple", simple_string);
1421 g_test_add_func("/literals/string/escaped", escaped_string);
1422 g_test_add_func("/literals/string/utf8", utf8_string);
1423 g_test_add_func("/literals/string/single_quote", single_quote_string);
1424 g_test_add_func("/literals/string/vararg", vararg_string);
1426 g_test_add_func("/literals/number/simple", simple_number);
1427 g_test_add_func("/literals/number/large", large_number);
1428 g_test_add_func("/literals/number/float", float_number);
1429 g_test_add_func("/literals/number/vararg", vararg_number);
1431 g_test_add_func("/literals/keyword", keyword_literal);
1433 g_test_add_func("/dicts/simple_dict", simple_dict);
1434 g_test_add_func("/dicts/large_dict", large_dict);
1435 g_test_add_func("/lists/simple_list", simple_list);
1437 g_test_add_func("/whitespace/simple_whitespace", simple_whitespace);
1439 g_test_add_func("/varargs/simple_varargs", simple_varargs);
1441 g_test_add_func("/errors/empty_input", empty_input);
1442 g_test_add_func("/errors/unterminated/string", unterminated_string);
1443 g_test_add_func("/errors/unterminated/escape", unterminated_escape);
1444 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string);
1445 g_test_add_func("/errors/unterminated/array", unterminated_array);
1446 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma);
1447 g_test_add_func("/errors/unterminated/dict", unterminated_dict);
1448 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma);
1449 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
1450 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
1451 g_test_add_func("/errors/unterminated/literal", unterminated_literal);
1452 g_test_add_func("/errors/limits/nesting", limits_nesting);
1454 return g_test_run();