mips jazz: compile only in 64 bit
[qemu/ar7.git] / tests / check-qjson.c
blob60e5b22a988cb22b91f43e3879b44307b79e65a8
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 <glib.h>
15 #include "qapi/qmp/qstring.h"
16 #include "qapi/qmp/qint.h"
17 #include "qapi/qmp/qdict.h"
18 #include "qapi/qmp/qlist.h"
19 #include "qapi/qmp/qfloat.h"
20 #include "qapi/qmp/qbool.h"
21 #include "qapi/qmp/qjson.h"
23 #include "qemu-common.h"
25 static void escaped_string(void)
27 int i;
28 struct {
29 const char *encoded;
30 const char *decoded;
31 int skip;
32 } test_cases[] = {
33 { "\"\\b\"", "\b" },
34 { "\"\\f\"", "\f" },
35 { "\"\\n\"", "\n" },
36 { "\"\\r\"", "\r" },
37 { "\"\\t\"", "\t" },
38 { "\"/\"", "/" },
39 { "\"\\/\"", "/", .skip = 1 },
40 { "\"\\\\\"", "\\" },
41 { "\"\\\"\"", "\"" },
42 { "\"hello world \\\"embedded string\\\"\"",
43 "hello world \"embedded string\"" },
44 { "\"hello world\\nwith new line\"", "hello world\nwith new line" },
45 { "\"single byte utf-8 \\u0020\"", "single byte utf-8 ", .skip = 1 },
46 { "\"double byte utf-8 \\u00A2\"", "double byte utf-8 \xc2\xa2" },
47 { "\"triple byte utf-8 \\u20AC\"", "triple byte utf-8 \xe2\x82\xac" },
48 { "'\\b'", "\b", .skip = 1 },
49 { "'\\f'", "\f", .skip = 1 },
50 { "'\\n'", "\n", .skip = 1 },
51 { "'\\r'", "\r", .skip = 1 },
52 { "'\\t'", "\t", .skip = 1 },
53 { "'\\/'", "/", .skip = 1 },
54 { "'\\\\'", "\\", .skip = 1 },
58 for (i = 0; test_cases[i].encoded; i++) {
59 QObject *obj;
60 QString *str;
62 obj = qobject_from_json(test_cases[i].encoded);
64 g_assert(obj != NULL);
65 g_assert(qobject_type(obj) == QTYPE_QSTRING);
67 str = qobject_to_qstring(obj);
68 g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].decoded);
70 if (test_cases[i].skip == 0) {
71 str = qobject_to_json(obj);
72 g_assert_cmpstr(qstring_get_str(str), ==, test_cases[i].encoded);
73 qobject_decref(obj);
76 QDECREF(str);
80 static void simple_string(void)
82 int i;
83 struct {
84 const char *encoded;
85 const char *decoded;
86 } test_cases[] = {
87 { "\"hello world\"", "hello world" },
88 { "\"the quick brown fox jumped over the fence\"",
89 "the quick brown fox jumped over the fence" },
93 for (i = 0; test_cases[i].encoded; i++) {
94 QObject *obj;
95 QString *str;
97 obj = qobject_from_json(test_cases[i].encoded);
99 g_assert(obj != NULL);
100 g_assert(qobject_type(obj) == QTYPE_QSTRING);
102 str = qobject_to_qstring(obj);
103 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
105 str = qobject_to_json(obj);
106 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
108 qobject_decref(obj);
110 QDECREF(str);
114 static void single_quote_string(void)
116 int i;
117 struct {
118 const char *encoded;
119 const char *decoded;
120 } test_cases[] = {
121 { "'hello world'", "hello world" },
122 { "'the quick brown fox \\' jumped over the fence'",
123 "the quick brown fox ' jumped over the fence" },
127 for (i = 0; test_cases[i].encoded; i++) {
128 QObject *obj;
129 QString *str;
131 obj = qobject_from_json(test_cases[i].encoded);
133 g_assert(obj != NULL);
134 g_assert(qobject_type(obj) == QTYPE_QSTRING);
136 str = qobject_to_qstring(obj);
137 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
139 QDECREF(str);
143 static void utf8_string(void)
146 * FIXME Current behavior for invalid UTF-8 sequences is
147 * incorrect. This test expects current, incorrect results.
148 * They're all marked "bug:" below, and are to be replaced by
149 * correct ones as the bugs get fixed.
151 * The JSON parser rejects some invalid sequences, but accepts
152 * others without correcting the problem.
154 * We should either reject all invalid sequences, or minimize
155 * overlong sequences and replace all other invalid sequences by a
156 * suitable replacement character. A common choice for
157 * replacement is U+FFFD.
159 * Problem: we can't easily deal with embedded U+0000. Parsing
160 * the JSON string "this \\u0000" is fun" yields "this \0 is fun",
161 * which gets misinterpreted as NUL-terminated "this ". We should
162 * consider using overlong encoding \xC0\x80 for U+0000 ("modified
163 * UTF-8").
165 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
166 * capability and stress test at
167 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
169 static const struct {
170 const char *json_in;
171 const char *utf8_out;
172 const char *json_out; /* defaults to @json_in */
173 const char *utf8_in; /* defaults to @utf8_out */
174 } test_cases[] = {
176 * Bug markers used here:
177 * - bug: not corrected
178 * JSON parser fails to correct invalid sequence(s)
179 * - bug: rejected
180 * JSON parser rejects invalid sequence(s)
181 * We may choose to define this as feature
182 * - bug: want "..."
183 * JSON parser produces incorrect result, this is the
184 * correct one, assuming replacement character U+FFFF
185 * We may choose to reject instead of replace
188 /* 1 Some correct UTF-8 text */
190 /* a bit of German */
191 "\"Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
192 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.\"",
193 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
194 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
195 "\"Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
196 " jeden gr\\u00F6\\u00DFeren Zwerg.\"",
199 /* a bit of Greek */
200 "\"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5\"",
201 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
202 "\"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5\"",
204 /* 2 Boundary condition test cases */
205 /* 2.1 First possible sequence of a certain length */
206 /* 2.1.1 1 byte U+0000 */
208 "\"\\u0000\"",
209 "", /* bug: want overlong "\xC0\x80" */
210 "\"\\u0000\"",
211 "\xC0\x80",
213 /* 2.1.2 2 bytes U+0080 */
215 "\"\xC2\x80\"",
216 "\xC2\x80",
217 "\"\\u0080\"",
219 /* 2.1.3 3 bytes U+0800 */
221 "\"\xE0\xA0\x80\"",
222 "\xE0\xA0\x80",
223 "\"\\u0800\"",
225 /* 2.1.4 4 bytes U+10000 */
227 "\"\xF0\x90\x80\x80\"",
228 "\xF0\x90\x80\x80",
229 "\"\\uD800\\uDC00\"",
231 /* 2.1.5 5 bytes U+200000 */
233 "\"\xF8\x88\x80\x80\x80\"",
234 NULL, /* bug: rejected */
235 "\"\\uFFFD\"",
236 "\xF8\x88\x80\x80\x80",
238 /* 2.1.6 6 bytes U+4000000 */
240 "\"\xFC\x84\x80\x80\x80\x80\"",
241 NULL, /* bug: rejected */
242 "\"\\uFFFD\"",
243 "\xFC\x84\x80\x80\x80\x80",
245 /* 2.2 Last possible sequence of a certain length */
246 /* 2.2.1 1 byte U+007F */
248 "\"\x7F\"",
249 "\x7F",
250 "\"\\u007F\"",
252 /* 2.2.2 2 bytes U+07FF */
254 "\"\xDF\xBF\"",
255 "\xDF\xBF",
256 "\"\\u07FF\"",
259 * 2.2.3 3 bytes U+FFFC
260 * The last possible sequence is actually U+FFFF. But that's
261 * a noncharacter, and already covered by its own test case
262 * under 5.3. Same for U+FFFE. U+FFFD is the last character
263 * in the BMP, and covered under 2.3. Because of U+FFFD's
264 * special role as replacement character, it's worth testing
265 * U+FFFC here.
268 "\"\xEF\xBF\xBC\"",
269 "\xEF\xBF\xBC",
270 "\"\\uFFFC\"",
272 /* 2.2.4 4 bytes U+1FFFFF */
274 "\"\xF7\xBF\xBF\xBF\"",
275 NULL, /* bug: rejected */
276 "\"\\uFFFD\"",
277 "\xF7\xBF\xBF\xBF",
279 /* 2.2.5 5 bytes U+3FFFFFF */
281 "\"\xFB\xBF\xBF\xBF\xBF\"",
282 NULL, /* bug: rejected */
283 "\"\\uFFFD\"",
284 "\xFB\xBF\xBF\xBF\xBF",
286 /* 2.2.6 6 bytes U+7FFFFFFF */
288 "\"\xFD\xBF\xBF\xBF\xBF\xBF\"",
289 NULL, /* bug: rejected */
290 "\"\\uFFFD\"",
291 "\xFD\xBF\xBF\xBF\xBF\xBF",
293 /* 2.3 Other boundary conditions */
295 /* last one before surrogate range: U+D7FF */
296 "\"\xED\x9F\xBF\"",
297 "\xED\x9F\xBF",
298 "\"\\uD7FF\"",
301 /* first one after surrogate range: U+E000 */
302 "\"\xEE\x80\x80\"",
303 "\xEE\x80\x80",
304 "\"\\uE000\"",
307 /* last one in BMP: U+FFFD */
308 "\"\xEF\xBF\xBD\"",
309 "\xEF\xBF\xBD",
310 "\"\\uFFFD\"",
313 /* last one in last plane: U+10FFFD */
314 "\"\xF4\x8F\xBF\xBD\"",
315 "\xF4\x8F\xBF\xBD",
316 "\"\\uDBFF\\uDFFD\""
319 /* first one beyond Unicode range: U+110000 */
320 "\"\xF4\x90\x80\x80\"",
321 "\xF4\x90\x80\x80",
322 "\"\\uFFFD\"",
324 /* 3 Malformed sequences */
325 /* 3.1 Unexpected continuation bytes */
326 /* 3.1.1 First continuation byte */
328 "\"\x80\"",
329 "\x80", /* bug: not corrected */
330 "\"\\uFFFD\"",
332 /* 3.1.2 Last continuation byte */
334 "\"\xBF\"",
335 "\xBF", /* bug: not corrected */
336 "\"\\uFFFD\"",
338 /* 3.1.3 2 continuation bytes */
340 "\"\x80\xBF\"",
341 "\x80\xBF", /* bug: not corrected */
342 "\"\\uFFFD\\uFFFD\"",
344 /* 3.1.4 3 continuation bytes */
346 "\"\x80\xBF\x80\"",
347 "\x80\xBF\x80", /* bug: not corrected */
348 "\"\\uFFFD\\uFFFD\\uFFFD\"",
350 /* 3.1.5 4 continuation bytes */
352 "\"\x80\xBF\x80\xBF\"",
353 "\x80\xBF\x80\xBF", /* bug: not corrected */
354 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
356 /* 3.1.6 5 continuation bytes */
358 "\"\x80\xBF\x80\xBF\x80\"",
359 "\x80\xBF\x80\xBF\x80", /* bug: not corrected */
360 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
362 /* 3.1.7 6 continuation bytes */
364 "\"\x80\xBF\x80\xBF\x80\xBF\"",
365 "\x80\xBF\x80\xBF\x80\xBF", /* bug: not corrected */
366 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
368 /* 3.1.8 7 continuation bytes */
370 "\"\x80\xBF\x80\xBF\x80\xBF\x80\"",
371 "\x80\xBF\x80\xBF\x80\xBF\x80", /* bug: not corrected */
372 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
374 /* 3.1.9 Sequence of all 64 possible continuation bytes */
376 "\"\x80\x81\x82\x83\x84\x85\x86\x87"
377 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
378 "\x90\x91\x92\x93\x94\x95\x96\x97"
379 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
380 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
381 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
382 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
383 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\"",
384 /* bug: not corrected */
385 "\x80\x81\x82\x83\x84\x85\x86\x87"
386 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
387 "\x90\x91\x92\x93\x94\x95\x96\x97"
388 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
389 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
390 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
391 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
392 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
393 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
394 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
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 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
400 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\""
402 /* 3.2 Lonely start characters */
403 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
405 "\"\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
406 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
407 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
408 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF \"",
409 NULL, /* bug: rejected */
410 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
411 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
412 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
413 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
414 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
415 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
416 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
417 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
419 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
421 "\"\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
422 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF \"",
423 /* bug: not corrected */
424 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
425 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
426 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
427 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
429 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
431 "\"\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 \"",
432 NULL, /* bug: rejected */
433 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
434 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
436 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
438 "\"\xF8 \xF9 \xFA \xFB \"",
439 NULL, /* bug: rejected */
440 "\"\\uFFFD \\uFFFD \\uFFFD \\uFFFD \"",
441 "\xF8 \xF9 \xFA \xFB ",
443 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
445 "\"\xFC \xFD \"",
446 NULL, /* bug: rejected */
447 "\"\\uFFFD \\uFFFD \"",
448 "\xFC \xFD ",
450 /* 3.3 Sequences with last continuation byte missing */
451 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
453 "\"\xC0\"",
454 NULL, /* bug: rejected */
455 "\"\\uFFFD\"",
456 "\xC0",
458 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
460 "\"\xE0\x80\"",
461 "\xE0\x80", /* bug: not corrected */
462 "\"\\uFFFD\"",
464 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
466 "\"\xF0\x80\x80\"",
467 "\xF0\x80\x80", /* bug: not corrected */
468 "\"\\uFFFD\"",
470 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
472 "\"\xF8\x80\x80\x80\"",
473 NULL, /* bug: rejected */
474 "\"\\uFFFD\"",
475 "\xF8\x80\x80\x80",
477 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
479 "\"\xFC\x80\x80\x80\x80\"",
480 NULL, /* bug: rejected */
481 "\"\\uFFFD\"",
482 "\xFC\x80\x80\x80\x80",
484 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
486 "\"\xDF\"",
487 "\xDF", /* bug: not corrected */
488 "\"\\uFFFD\"",
490 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
492 "\"\xEF\xBF\"",
493 "\xEF\xBF", /* bug: not corrected */
494 "\"\\uFFFD\"",
496 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
498 "\"\xF7\xBF\xBF\"",
499 NULL, /* bug: rejected */
500 "\"\\uFFFD\"",
501 "\xF7\xBF\xBF",
503 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
505 "\"\xFB\xBF\xBF\xBF\"",
506 NULL, /* bug: rejected */
507 "\"\\uFFFD\"",
508 "\xFB\xBF\xBF\xBF",
510 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
512 "\"\xFD\xBF\xBF\xBF\xBF\"",
513 NULL, /* bug: rejected */
514 "\"\\uFFFD\"",
515 "\xFD\xBF\xBF\xBF\xBF",
517 /* 3.4 Concatenation of incomplete sequences */
519 "\"\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
520 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF\"",
521 NULL, /* bug: rejected */
522 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
523 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
524 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
525 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
527 /* 3.5 Impossible bytes */
529 "\"\xFE\"",
530 NULL, /* bug: rejected */
531 "\"\\uFFFD\"",
532 "\xFE",
535 "\"\xFF\"",
536 NULL, /* bug: rejected */
537 "\"\\uFFFD\"",
538 "\xFF",
541 "\"\xFE\xFE\xFF\xFF\"",
542 NULL, /* bug: rejected */
543 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
544 "\xFE\xFE\xFF\xFF",
546 /* 4 Overlong sequences */
547 /* 4.1 Overlong '/' */
549 "\"\xC0\xAF\"",
550 NULL, /* bug: rejected */
551 "\"\\uFFFD\"",
552 "\xC0\xAF",
555 "\"\xE0\x80\xAF\"",
556 "\xE0\x80\xAF", /* bug: not corrected */
557 "\"\\uFFFD\"",
560 "\"\xF0\x80\x80\xAF\"",
561 "\xF0\x80\x80\xAF", /* bug: not corrected */
562 "\"\\uFFFD\"",
565 "\"\xF8\x80\x80\x80\xAF\"",
566 NULL, /* bug: rejected */
567 "\"\\uFFFD\"",
568 "\xF8\x80\x80\x80\xAF",
571 "\"\xFC\x80\x80\x80\x80\xAF\"",
572 NULL, /* bug: rejected */
573 "\"\\uFFFD\"",
574 "\xFC\x80\x80\x80\x80\xAF",
577 * 4.2 Maximum overlong sequences
578 * Highest Unicode value that is still resulting in an
579 * overlong sequence if represented with the given number of
580 * bytes. This is a boundary test for safe UTF-8 decoders.
583 /* \U+007F */
584 "\"\xC1\xBF\"",
585 NULL, /* bug: rejected */
586 "\"\\uFFFD\"",
587 "\xC1\xBF",
590 /* \U+07FF */
591 "\"\xE0\x9F\xBF\"",
592 "\xE0\x9F\xBF", /* bug: not corrected */
593 "\"\\uFFFD\"",
597 * \U+FFFC
598 * The actual maximum would be U+FFFF, but that's a
599 * noncharacter. Testing U+FFFC seems more useful. See
600 * also 2.2.3
602 "\"\xF0\x8F\xBF\xBC\"",
603 "\xF0\x8F\xBF\xBC", /* bug: not corrected */
604 "\"\\uFFFD\"",
607 /* \U+1FFFFF */
608 "\"\xF8\x87\xBF\xBF\xBF\"",
609 NULL, /* bug: rejected */
610 "\"\\uFFFD\"",
611 "\xF8\x87\xBF\xBF\xBF",
614 /* \U+3FFFFFF */
615 "\"\xFC\x83\xBF\xBF\xBF\xBF\"",
616 NULL, /* bug: rejected */
617 "\"\\uFFFD\"",
618 "\xFC\x83\xBF\xBF\xBF\xBF",
620 /* 4.3 Overlong representation of the NUL character */
622 /* \U+0000 */
623 "\"\xC0\x80\"",
624 NULL, /* bug: rejected */
625 "\"\\u0000\"",
626 "\xC0\x80",
629 /* \U+0000 */
630 "\"\xE0\x80\x80\"",
631 "\xE0\x80\x80", /* bug: not corrected */
632 "\"\\uFFFD\"",
635 /* \U+0000 */
636 "\"\xF0\x80\x80\x80\"",
637 "\xF0\x80\x80\x80", /* bug: not corrected */
638 "\"\\uFFFD\"",
641 /* \U+0000 */
642 "\"\xF8\x80\x80\x80\x80\"",
643 NULL, /* bug: rejected */
644 "\"\\uFFFD\"",
645 "\xF8\x80\x80\x80\x80",
648 /* \U+0000 */
649 "\"\xFC\x80\x80\x80\x80\x80\"",
650 NULL, /* bug: rejected */
651 "\"\\uFFFD\"",
652 "\xFC\x80\x80\x80\x80\x80",
654 /* 5 Illegal code positions */
655 /* 5.1 Single UTF-16 surrogates */
657 /* \U+D800 */
658 "\"\xED\xA0\x80\"",
659 "\xED\xA0\x80", /* bug: not corrected */
660 "\"\\uFFFD\"",
663 /* \U+DB7F */
664 "\"\xED\xAD\xBF\"",
665 "\xED\xAD\xBF", /* bug: not corrected */
666 "\"\\uFFFD\"",
669 /* \U+DB80 */
670 "\"\xED\xAE\x80\"",
671 "\xED\xAE\x80", /* bug: not corrected */
672 "\"\\uFFFD\"",
675 /* \U+DBFF */
676 "\"\xED\xAF\xBF\"",
677 "\xED\xAF\xBF", /* bug: not corrected */
678 "\"\\uFFFD\"",
681 /* \U+DC00 */
682 "\"\xED\xB0\x80\"",
683 "\xED\xB0\x80", /* bug: not corrected */
684 "\"\\uFFFD\"",
687 /* \U+DF80 */
688 "\"\xED\xBE\x80\"",
689 "\xED\xBE\x80", /* bug: not corrected */
690 "\"\\uFFFD\"",
693 /* \U+DFFF */
694 "\"\xED\xBF\xBF\"",
695 "\xED\xBF\xBF", /* bug: not corrected */
696 "\"\\uFFFD\"",
698 /* 5.2 Paired UTF-16 surrogates */
700 /* \U+D800\U+DC00 */
701 "\"\xED\xA0\x80\xED\xB0\x80\"",
702 "\xED\xA0\x80\xED\xB0\x80", /* bug: not corrected */
703 "\"\\uFFFD\\uFFFD\"",
706 /* \U+D800\U+DFFF */
707 "\"\xED\xA0\x80\xED\xBF\xBF\"",
708 "\xED\xA0\x80\xED\xBF\xBF", /* bug: not corrected */
709 "\"\\uFFFD\\uFFFD\"",
712 /* \U+DB7F\U+DC00 */
713 "\"\xED\xAD\xBF\xED\xB0\x80\"",
714 "\xED\xAD\xBF\xED\xB0\x80", /* bug: not corrected */
715 "\"\\uFFFD\\uFFFD\"",
718 /* \U+DB7F\U+DFFF */
719 "\"\xED\xAD\xBF\xED\xBF\xBF\"",
720 "\xED\xAD\xBF\xED\xBF\xBF", /* bug: not corrected */
721 "\"\\uFFFD\\uFFFD\"",
724 /* \U+DB80\U+DC00 */
725 "\"\xED\xAE\x80\xED\xB0\x80\"",
726 "\xED\xAE\x80\xED\xB0\x80", /* bug: not corrected */
727 "\"\\uFFFD\\uFFFD\"",
730 /* \U+DB80\U+DFFF */
731 "\"\xED\xAE\x80\xED\xBF\xBF\"",
732 "\xED\xAE\x80\xED\xBF\xBF", /* bug: not corrected */
733 "\"\\uFFFD\\uFFFD\"",
736 /* \U+DBFF\U+DC00 */
737 "\"\xED\xAF\xBF\xED\xB0\x80\"",
738 "\xED\xAF\xBF\xED\xB0\x80", /* bug: not corrected */
739 "\"\\uFFFD\\uFFFD\"",
742 /* \U+DBFF\U+DFFF */
743 "\"\xED\xAF\xBF\xED\xBF\xBF\"",
744 "\xED\xAF\xBF\xED\xBF\xBF", /* bug: not corrected */
745 "\"\\uFFFD\\uFFFD\"",
747 /* 5.3 Other illegal code positions */
748 /* BMP noncharacters */
750 /* \U+FFFE */
751 "\"\xEF\xBF\xBE\"",
752 "\xEF\xBF\xBE", /* bug: not corrected */
753 "\"\\uFFFD\"",
756 /* \U+FFFF */
757 "\"\xEF\xBF\xBF\"",
758 "\xEF\xBF\xBF", /* bug: not corrected */
759 "\"\\uFFFD\"",
762 /* U+FDD0 */
763 "\"\xEF\xB7\x90\"",
764 "\xEF\xB7\x90", /* bug: not corrected */
765 "\"\\uFFFD\"",
768 /* U+FDEF */
769 "\"\xEF\xB7\xAF\"",
770 "\xEF\xB7\xAF", /* bug: not corrected */
771 "\"\\uFFFD\"",
773 /* Plane 1 .. 16 noncharacters */
775 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
776 "\"\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
777 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
778 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
779 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
780 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
781 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
782 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
783 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
784 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
785 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
786 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
787 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
788 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
789 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
790 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
791 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF\"",
792 /* bug: not corrected */
793 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
794 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
795 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
796 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
797 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
798 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
799 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
800 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
801 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
802 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
803 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
804 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
805 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
806 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
807 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
808 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
809 "\"\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
810 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
811 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
812 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\"",
816 int i;
817 QObject *obj;
818 QString *str;
819 const char *json_in, *utf8_out, *utf8_in, *json_out;
821 for (i = 0; test_cases[i].json_in; i++) {
822 json_in = test_cases[i].json_in;
823 utf8_out = test_cases[i].utf8_out;
824 utf8_in = test_cases[i].utf8_in ?: test_cases[i].utf8_out;
825 json_out = test_cases[i].json_out ?: test_cases[i].json_in;
827 obj = qobject_from_json(json_in);
828 if (utf8_out) {
829 g_assert(obj);
830 g_assert(qobject_type(obj) == QTYPE_QSTRING);
831 str = qobject_to_qstring(obj);
832 g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
833 } else {
834 g_assert(!obj);
836 qobject_decref(obj);
838 obj = QOBJECT(qstring_from_str(utf8_in));
839 str = qobject_to_json(obj);
840 if (json_out) {
841 g_assert(str);
842 g_assert_cmpstr(qstring_get_str(str), ==, json_out);
843 } else {
844 g_assert(!str);
846 QDECREF(str);
847 qobject_decref(obj);
850 * Disabled, because qobject_from_json() is buggy, and I can't
851 * be bothered to add the expected incorrect results.
852 * FIXME Enable once these bugs have been fixed.
854 if (0 && json_out != json_in) {
855 obj = qobject_from_json(json_out);
856 g_assert(obj);
857 g_assert(qobject_type(obj) == QTYPE_QSTRING);
858 str = qobject_to_qstring(obj);
859 g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
864 static void vararg_string(void)
866 int i;
867 struct {
868 const char *decoded;
869 } test_cases[] = {
870 { "hello world" },
871 { "the quick brown fox jumped over the fence" },
875 for (i = 0; test_cases[i].decoded; i++) {
876 QObject *obj;
877 QString *str;
879 obj = qobject_from_jsonf("%s", test_cases[i].decoded);
881 g_assert(obj != NULL);
882 g_assert(qobject_type(obj) == QTYPE_QSTRING);
884 str = qobject_to_qstring(obj);
885 g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
887 QDECREF(str);
891 static void simple_number(void)
893 int i;
894 struct {
895 const char *encoded;
896 int64_t decoded;
897 int skip;
898 } test_cases[] = {
899 { "0", 0 },
900 { "1234", 1234 },
901 { "1", 1 },
902 { "-32", -32 },
903 { "-0", 0, .skip = 1 },
904 { },
907 for (i = 0; test_cases[i].encoded; i++) {
908 QObject *obj;
909 QInt *qint;
911 obj = qobject_from_json(test_cases[i].encoded);
912 g_assert(obj != NULL);
913 g_assert(qobject_type(obj) == QTYPE_QINT);
915 qint = qobject_to_qint(obj);
916 g_assert(qint_get_int(qint) == test_cases[i].decoded);
917 if (test_cases[i].skip == 0) {
918 QString *str;
920 str = qobject_to_json(obj);
921 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
922 QDECREF(str);
925 QDECREF(qint);
929 static void float_number(void)
931 int i;
932 struct {
933 const char *encoded;
934 double decoded;
935 int skip;
936 } test_cases[] = {
937 { "32.43", 32.43 },
938 { "0.222", 0.222 },
939 { "-32.12313", -32.12313 },
940 { "-32.20e-10", -32.20e-10, .skip = 1 },
941 { },
944 for (i = 0; test_cases[i].encoded; i++) {
945 QObject *obj;
946 QFloat *qfloat;
948 obj = qobject_from_json(test_cases[i].encoded);
949 g_assert(obj != NULL);
950 g_assert(qobject_type(obj) == QTYPE_QFLOAT);
952 qfloat = qobject_to_qfloat(obj);
953 g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded);
955 if (test_cases[i].skip == 0) {
956 QString *str;
958 str = qobject_to_json(obj);
959 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
960 QDECREF(str);
963 QDECREF(qfloat);
967 static void vararg_number(void)
969 QObject *obj;
970 QInt *qint;
971 QFloat *qfloat;
972 int value = 0x2342;
973 int64_t value64 = 0x2342342343LL;
974 double valuef = 2.323423423;
976 obj = qobject_from_jsonf("%d", value);
977 g_assert(obj != NULL);
978 g_assert(qobject_type(obj) == QTYPE_QINT);
980 qint = qobject_to_qint(obj);
981 g_assert(qint_get_int(qint) == value);
983 QDECREF(qint);
985 obj = qobject_from_jsonf("%" PRId64, value64);
986 g_assert(obj != NULL);
987 g_assert(qobject_type(obj) == QTYPE_QINT);
989 qint = qobject_to_qint(obj);
990 g_assert(qint_get_int(qint) == value64);
992 QDECREF(qint);
994 obj = qobject_from_jsonf("%f", valuef);
995 g_assert(obj != NULL);
996 g_assert(qobject_type(obj) == QTYPE_QFLOAT);
998 qfloat = qobject_to_qfloat(obj);
999 g_assert(qfloat_get_double(qfloat) == valuef);
1001 QDECREF(qfloat);
1004 static void keyword_literal(void)
1006 QObject *obj;
1007 QBool *qbool;
1008 QObject *null;
1009 QString *str;
1011 obj = qobject_from_json("true");
1012 g_assert(obj != NULL);
1013 g_assert(qobject_type(obj) == QTYPE_QBOOL);
1015 qbool = qobject_to_qbool(obj);
1016 g_assert(qbool_get_int(qbool) != 0);
1018 str = qobject_to_json(obj);
1019 g_assert(strcmp(qstring_get_str(str), "true") == 0);
1020 QDECREF(str);
1022 QDECREF(qbool);
1024 obj = qobject_from_json("false");
1025 g_assert(obj != NULL);
1026 g_assert(qobject_type(obj) == QTYPE_QBOOL);
1028 qbool = qobject_to_qbool(obj);
1029 g_assert(qbool_get_int(qbool) == 0);
1031 str = qobject_to_json(obj);
1032 g_assert(strcmp(qstring_get_str(str), "false") == 0);
1033 QDECREF(str);
1035 QDECREF(qbool);
1037 obj = qobject_from_jsonf("%i", false);
1038 g_assert(obj != NULL);
1039 g_assert(qobject_type(obj) == QTYPE_QBOOL);
1041 qbool = qobject_to_qbool(obj);
1042 g_assert(qbool_get_int(qbool) == 0);
1044 QDECREF(qbool);
1046 obj = qobject_from_jsonf("%i", true);
1047 g_assert(obj != NULL);
1048 g_assert(qobject_type(obj) == QTYPE_QBOOL);
1050 qbool = qobject_to_qbool(obj);
1051 g_assert(qbool_get_int(qbool) != 0);
1053 QDECREF(qbool);
1055 obj = qobject_from_json("null");
1056 g_assert(obj != NULL);
1057 g_assert(qobject_type(obj) == QTYPE_QNULL);
1059 null = qnull();
1060 g_assert(null == obj);
1062 qobject_decref(obj);
1063 qobject_decref(null);
1066 typedef struct LiteralQDictEntry LiteralQDictEntry;
1067 typedef struct LiteralQObject LiteralQObject;
1069 struct LiteralQObject
1071 int type;
1072 union {
1073 int64_t qint;
1074 const char *qstr;
1075 LiteralQDictEntry *qdict;
1076 LiteralQObject *qlist;
1077 } value;
1080 struct LiteralQDictEntry
1082 const char *key;
1083 LiteralQObject value;
1086 #define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
1087 #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
1088 #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
1089 #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
1091 typedef struct QListCompareHelper
1093 int index;
1094 LiteralQObject *objs;
1095 int result;
1096 } QListCompareHelper;
1098 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs);
1100 static void compare_helper(QObject *obj, void *opaque)
1102 QListCompareHelper *helper = opaque;
1104 if (helper->result == 0) {
1105 return;
1108 if (helper->objs[helper->index].type == QTYPE_NONE) {
1109 helper->result = 0;
1110 return;
1113 helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj);
1116 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
1118 if (lhs->type != qobject_type(rhs)) {
1119 return 0;
1122 switch (lhs->type) {
1123 case QTYPE_QINT:
1124 return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
1125 case QTYPE_QSTRING:
1126 return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
1127 case QTYPE_QDICT: {
1128 int i;
1130 for (i = 0; lhs->value.qdict[i].key; i++) {
1131 QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key);
1133 if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) {
1134 return 0;
1138 return 1;
1140 case QTYPE_QLIST: {
1141 QListCompareHelper helper;
1143 helper.index = 0;
1144 helper.objs = lhs->value.qlist;
1145 helper.result = 1;
1147 qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper);
1149 return helper.result;
1151 default:
1152 break;
1155 return 0;
1158 static void simple_dict(void)
1160 int i;
1161 struct {
1162 const char *encoded;
1163 LiteralQObject decoded;
1164 } test_cases[] = {
1166 .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
1167 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
1168 { "foo", QLIT_QINT(42) },
1169 { "bar", QLIT_QSTR("hello world") },
1171 })),
1172 }, {
1173 .encoded = "{}",
1174 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
1176 })),
1177 }, {
1178 .encoded = "{\"foo\": 43}",
1179 .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
1180 { "foo", QLIT_QINT(43) },
1182 })),
1187 for (i = 0; test_cases[i].encoded; i++) {
1188 QObject *obj;
1189 QString *str;
1191 obj = qobject_from_json(test_cases[i].encoded);
1192 g_assert(obj != NULL);
1193 g_assert(qobject_type(obj) == QTYPE_QDICT);
1195 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1197 str = qobject_to_json(obj);
1198 qobject_decref(obj);
1200 obj = qobject_from_json(qstring_get_str(str));
1201 g_assert(obj != NULL);
1202 g_assert(qobject_type(obj) == QTYPE_QDICT);
1204 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1205 qobject_decref(obj);
1206 QDECREF(str);
1211 * this generates json of the form:
1212 * a(0,m) = [0, 1, ..., m-1]
1213 * a(n,m) = {
1214 * 'key0': a(0,m),
1215 * 'key1': a(1,m),
1216 * ...
1217 * 'key(n-1)': a(n-1,m)
1220 static void gen_test_json(GString *gstr, int nest_level_max,
1221 int elem_count)
1223 int i;
1225 g_assert(gstr);
1226 if (nest_level_max == 0) {
1227 g_string_append(gstr, "[");
1228 for (i = 0; i < elem_count; i++) {
1229 g_string_append_printf(gstr, "%d", i);
1230 if (i < elem_count - 1) {
1231 g_string_append_printf(gstr, ", ");
1234 g_string_append(gstr, "]");
1235 return;
1238 g_string_append(gstr, "{");
1239 for (i = 0; i < nest_level_max; i++) {
1240 g_string_append_printf(gstr, "'key%d': ", i);
1241 gen_test_json(gstr, i, elem_count);
1242 if (i < nest_level_max - 1) {
1243 g_string_append(gstr, ",");
1246 g_string_append(gstr, "}");
1249 static void large_dict(void)
1251 GString *gstr = g_string_new("");
1252 QObject *obj;
1254 gen_test_json(gstr, 10, 100);
1255 obj = qobject_from_json(gstr->str);
1256 g_assert(obj != NULL);
1258 qobject_decref(obj);
1259 g_string_free(gstr, true);
1262 static void simple_list(void)
1264 int i;
1265 struct {
1266 const char *encoded;
1267 LiteralQObject decoded;
1268 } test_cases[] = {
1270 .encoded = "[43,42]",
1271 .decoded = QLIT_QLIST(((LiteralQObject[]){
1272 QLIT_QINT(43),
1273 QLIT_QINT(42),
1275 })),
1278 .encoded = "[43]",
1279 .decoded = QLIT_QLIST(((LiteralQObject[]){
1280 QLIT_QINT(43),
1282 })),
1285 .encoded = "[]",
1286 .decoded = QLIT_QLIST(((LiteralQObject[]){
1288 })),
1291 .encoded = "[{}]",
1292 .decoded = QLIT_QLIST(((LiteralQObject[]){
1293 QLIT_QDICT(((LiteralQDictEntry[]){
1295 })),
1297 })),
1302 for (i = 0; test_cases[i].encoded; i++) {
1303 QObject *obj;
1304 QString *str;
1306 obj = qobject_from_json(test_cases[i].encoded);
1307 g_assert(obj != NULL);
1308 g_assert(qobject_type(obj) == QTYPE_QLIST);
1310 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1312 str = qobject_to_json(obj);
1313 qobject_decref(obj);
1315 obj = qobject_from_json(qstring_get_str(str));
1316 g_assert(obj != NULL);
1317 g_assert(qobject_type(obj) == QTYPE_QLIST);
1319 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1320 qobject_decref(obj);
1321 QDECREF(str);
1325 static void simple_whitespace(void)
1327 int i;
1328 struct {
1329 const char *encoded;
1330 LiteralQObject decoded;
1331 } test_cases[] = {
1333 .encoded = " [ 43 , 42 ]",
1334 .decoded = QLIT_QLIST(((LiteralQObject[]){
1335 QLIT_QINT(43),
1336 QLIT_QINT(42),
1338 })),
1341 .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
1342 .decoded = QLIT_QLIST(((LiteralQObject[]){
1343 QLIT_QINT(43),
1344 QLIT_QDICT(((LiteralQDictEntry[]){
1345 { "h", QLIT_QSTR("b") },
1346 { }})),
1347 QLIT_QLIST(((LiteralQObject[]){
1348 { }})),
1349 QLIT_QINT(42),
1351 })),
1354 .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1355 .decoded = QLIT_QLIST(((LiteralQObject[]){
1356 QLIT_QINT(43),
1357 QLIT_QDICT(((LiteralQDictEntry[]){
1358 { "h", QLIT_QSTR("b") },
1359 { "a", QLIT_QINT(32) },
1360 { }})),
1361 QLIT_QLIST(((LiteralQObject[]){
1362 { }})),
1363 QLIT_QINT(42),
1365 })),
1370 for (i = 0; test_cases[i].encoded; i++) {
1371 QObject *obj;
1372 QString *str;
1374 obj = qobject_from_json(test_cases[i].encoded);
1375 g_assert(obj != NULL);
1376 g_assert(qobject_type(obj) == QTYPE_QLIST);
1378 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1380 str = qobject_to_json(obj);
1381 qobject_decref(obj);
1383 obj = qobject_from_json(qstring_get_str(str));
1384 g_assert(obj != NULL);
1385 g_assert(qobject_type(obj) == QTYPE_QLIST);
1387 g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);
1389 qobject_decref(obj);
1390 QDECREF(str);
1394 static void simple_varargs(void)
1396 QObject *embedded_obj;
1397 QObject *obj;
1398 LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
1399 QLIT_QINT(1),
1400 QLIT_QINT(2),
1401 QLIT_QLIST(((LiteralQObject[]){
1402 QLIT_QINT(32),
1403 QLIT_QINT(42),
1404 {}})),
1405 {}}));
1407 embedded_obj = qobject_from_json("[32, 42]");
1408 g_assert(embedded_obj != NULL);
1410 obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj);
1411 g_assert(obj != NULL);
1413 g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1);
1415 qobject_decref(obj);
1418 static void empty_input(void)
1420 const char *empty = "";
1422 QObject *obj = qobject_from_json(empty);
1423 g_assert(obj == NULL);
1426 static void unterminated_string(void)
1428 QObject *obj = qobject_from_json("\"abc");
1429 g_assert(obj == NULL);
1432 static void unterminated_sq_string(void)
1434 QObject *obj = qobject_from_json("'abc");
1435 g_assert(obj == NULL);
1438 static void unterminated_escape(void)
1440 QObject *obj = qobject_from_json("\"abc\\\"");
1441 g_assert(obj == NULL);
1444 static void unterminated_array(void)
1446 QObject *obj = qobject_from_json("[32");
1447 g_assert(obj == NULL);
1450 static void unterminated_array_comma(void)
1452 QObject *obj = qobject_from_json("[32,");
1453 g_assert(obj == NULL);
1456 static void invalid_array_comma(void)
1458 QObject *obj = qobject_from_json("[32,}");
1459 g_assert(obj == NULL);
1462 static void unterminated_dict(void)
1464 QObject *obj = qobject_from_json("{'abc':32");
1465 g_assert(obj == NULL);
1468 static void unterminated_dict_comma(void)
1470 QObject *obj = qobject_from_json("{'abc':32,");
1471 g_assert(obj == NULL);
1474 static void invalid_dict_comma(void)
1476 QObject *obj = qobject_from_json("{'abc':32,}");
1477 g_assert(obj == NULL);
1480 static void unterminated_literal(void)
1482 QObject *obj = qobject_from_json("nul");
1483 g_assert(obj == NULL);
1486 int main(int argc, char **argv)
1488 g_test_init(&argc, &argv, NULL);
1490 g_test_add_func("/literals/string/simple", simple_string);
1491 g_test_add_func("/literals/string/escaped", escaped_string);
1492 g_test_add_func("/literals/string/utf8", utf8_string);
1493 g_test_add_func("/literals/string/single_quote", single_quote_string);
1494 g_test_add_func("/literals/string/vararg", vararg_string);
1496 g_test_add_func("/literals/number/simple", simple_number);
1497 g_test_add_func("/literals/number/float", float_number);
1498 g_test_add_func("/literals/number/vararg", vararg_number);
1500 g_test_add_func("/literals/keyword", keyword_literal);
1502 g_test_add_func("/dicts/simple_dict", simple_dict);
1503 g_test_add_func("/dicts/large_dict", large_dict);
1504 g_test_add_func("/lists/simple_list", simple_list);
1506 g_test_add_func("/whitespace/simple_whitespace", simple_whitespace);
1508 g_test_add_func("/varargs/simple_varargs", simple_varargs);
1510 g_test_add_func("/errors/empty_input", empty_input);
1511 g_test_add_func("/errors/unterminated/string", unterminated_string);
1512 g_test_add_func("/errors/unterminated/escape", unterminated_escape);
1513 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string);
1514 g_test_add_func("/errors/unterminated/array", unterminated_array);
1515 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma);
1516 g_test_add_func("/errors/unterminated/dict", unterminated_dict);
1517 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma);
1518 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
1519 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
1520 g_test_add_func("/errors/unterminated/literal", unterminated_literal);
1522 return g_test_run();