]> git.proxmox.com Git - mirror_qemu.git/blob - tests/check-qjson.c
json: Reject invalid \uXXXX, fix \u0000
[mirror_qemu.git] / tests / check-qjson.c
1 /*
2 * Copyright IBM, Corp. 2009
3 * Copyright (c) 2013, 2015 Red Hat Inc.
4 *
5 * Authors:
6 * Anthony Liguori <aliguori@us.ibm.com>
7 * Markus Armbruster <armbru@redhat.com>
8 *
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.
11 *
12 */
13
14 #include "qemu/osdep.h"
15
16 #include "qapi/error.h"
17 #include "qapi/qmp/qbool.h"
18 #include "qapi/qmp/qjson.h"
19 #include "qapi/qmp/qlit.h"
20 #include "qapi/qmp/qnull.h"
21 #include "qapi/qmp/qnum.h"
22 #include "qapi/qmp/qstring.h"
23 #include "qemu/unicode.h"
24 #include "qemu-common.h"
25
26 static QString *from_json_str(const char *jstr, bool single, Error **errp)
27 {
28 char quote = single ? '\'' : '"';
29 char *qjstr = g_strdup_printf("%c%s%c", quote, jstr, quote);
30 QString *ret = qobject_to(QString, qobject_from_json(qjstr, errp));
31
32 g_free(qjstr);
33 return ret;
34 }
35
36 static char *to_json_str(QString *str)
37 {
38 QString *json = qobject_to_json(QOBJECT(str));
39 char *jstr;
40
41 if (!json) {
42 return NULL;
43 }
44 /* peel off double quotes */
45 jstr = g_strndup(qstring_get_str(json) + 1,
46 qstring_get_length(json) - 2);
47 qobject_unref(json);
48 return jstr;
49 }
50
51 static void escaped_string(void)
52 {
53 struct {
54 /* Content of JSON string to parse with qobject_from_json() */
55 const char *json_in;
56 /* Expected parse output; to unparse with qobject_to_json() */
57 const char *utf8_out;
58 int skip;
59 } test_cases[] = {
60 { "\\b\\f\\n\\r\\t\\\\\\\"", "\b\f\n\r\t\\\"" },
61 { "\\/\\'", "/'", .skip = 1 },
62 { "single byte utf-8 \\u0020", "single byte utf-8 ", .skip = 1 },
63 { "double byte utf-8 \\u00A2", "double byte utf-8 \xc2\xa2" },
64 { "triple byte utf-8 \\u20AC", "triple byte utf-8 \xe2\x82\xac" },
65 { "quadruple byte utf-8 \\uD834\\uDD1E", /* U+1D11E */
66 /* bug: want \xF0\x9D\x84\x9E */
67 NULL },
68 { "\\", NULL },
69 { "\\z", NULL },
70 { "\\ux", NULL },
71 { "\\u1x", NULL },
72 { "\\u12x", NULL },
73 { "\\u123x", NULL },
74 { "\\u12345", "\341\210\2645" },
75 { "\\u0000x", "\xC0\x80x" },
76 { "unpaired leading surrogate \\uD800", NULL },
77 { "unpaired leading surrogate \\uD800\\uCAFE", NULL },
78 { "unpaired leading surrogate \\uD800\\uD801\\uDC02", NULL },
79 { "unpaired trailing surrogate \\uDC00", NULL },
80 { "backward surrogate pair \\uDC00\\uD800", NULL },
81 { "noncharacter U+FDD0 \\uFDD0", NULL },
82 { "noncharacter U+FDEF \\uFDEF", NULL },
83 { "noncharacter U+1FFFE \\uD87F\\uDFFE", NULL },
84 { "noncharacter U+10FFFF \\uDC3F\\uDFFF", NULL },
85 {}
86 };
87 int i, j;
88 QString *cstr;
89 char *jstr;
90
91 for (i = 0; test_cases[i].json_in; i++) {
92 for (j = 0; j < 2; j++) {
93 if (test_cases[i].utf8_out) {
94 cstr = from_json_str(test_cases[i].json_in, j, &error_abort);
95 g_assert_cmpstr(qstring_get_try_str(cstr),
96 ==, test_cases[i].utf8_out);
97 if (!test_cases[i].skip) {
98 jstr = to_json_str(cstr);
99 g_assert_cmpstr(jstr, ==, test_cases[i].json_in);
100 g_free(jstr);
101 }
102 qobject_unref(cstr);
103 } else {
104 cstr = from_json_str(test_cases[i].json_in, j, NULL);
105 g_assert(!cstr);
106 }
107 }
108 }
109 }
110
111 static void string_with_quotes(void)
112 {
113 const char *test_cases[] = {
114 "\"the bee's knees\"",
115 "'double quote \"'",
116 NULL
117 };
118 int i;
119 QString *str;
120 char *cstr;
121
122 for (i = 0; test_cases[i]; i++) {
123 str = qobject_to(QString,
124 qobject_from_json(test_cases[i], &error_abort));
125 g_assert(str);
126 cstr = g_strndup(test_cases[i] + 1, strlen(test_cases[i]) - 2);
127 g_assert_cmpstr(qstring_get_str(str), ==, cstr);
128 g_free(cstr);
129 qobject_unref(str);
130 }
131 }
132
133 static void utf8_string(void)
134 {
135 /*
136 * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
137 * capability and stress test at
138 * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
139 */
140 static const struct {
141 /* Content of JSON string to parse with qobject_from_json() */
142 const char *json_in;
143 /* Expected parse output */
144 const char *utf8_out;
145 /* Expected unparse output, defaults to @json_in */
146 const char *json_out;
147 } test_cases[] = {
148 /* 0 Control characters */
149 {
150 /*
151 * Note: \x00 is impossible, other representations of
152 * U+0000 are covered under 4.3
153 */
154 "\x01\x02\x03\x04\x05\x06\x07"
155 "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
156 "\x10\x11\x12\x13\x14\x15\x16\x17"
157 "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
158 NULL,
159 "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007"
160 "\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F"
161 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017"
162 "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F",
163 },
164 /* 1 Some correct UTF-8 text */
165 {
166 /* a bit of German */
167 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
168 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
169 "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
170 " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
171 "Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
172 " jeden gr\\u00F6\\u00DFeren Zwerg.",
173 },
174 {
175 /* a bit of Greek */
176 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
177 "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
178 "\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
179 },
180 /* 2 Boundary condition test cases */
181 /* 2.1 First possible sequence of a certain length */
182 /*
183 * 2.1.1 1 byte U+0020
184 * Control characters are already covered by their own test
185 * case under 0. Test the first 1 byte non-control character
186 * here.
187 */
188 {
189 " ",
190 " ",
191 },
192 /* 2.1.2 2 bytes U+0080 */
193 {
194 "\xC2\x80",
195 "\xC2\x80",
196 "\\u0080",
197 },
198 /* 2.1.3 3 bytes U+0800 */
199 {
200 "\xE0\xA0\x80",
201 "\xE0\xA0\x80",
202 "\\u0800",
203 },
204 /* 2.1.4 4 bytes U+10000 */
205 {
206 "\xF0\x90\x80\x80",
207 "\xF0\x90\x80\x80",
208 "\\uD800\\uDC00",
209 },
210 /* 2.1.5 5 bytes U+200000 */
211 {
212 "\xF8\x88\x80\x80\x80",
213 NULL,
214 "\\uFFFD",
215 },
216 /* 2.1.6 6 bytes U+4000000 */
217 {
218 "\xFC\x84\x80\x80\x80\x80",
219 NULL,
220 "\\uFFFD",
221 },
222 /* 2.2 Last possible sequence of a certain length */
223 /* 2.2.1 1 byte U+007F */
224 {
225 "\x7F",
226 "\x7F",
227 "\\u007F",
228 },
229 /* 2.2.2 2 bytes U+07FF */
230 {
231 "\xDF\xBF",
232 "\xDF\xBF",
233 "\\u07FF",
234 },
235 /*
236 * 2.2.3 3 bytes U+FFFC
237 * The last possible sequence is actually U+FFFF. But that's
238 * a noncharacter, and already covered by its own test case
239 * under 5.3. Same for U+FFFE. U+FFFD is the last character
240 * in the BMP, and covered under 2.3. Because of U+FFFD's
241 * special role as replacement character, it's worth testing
242 * U+FFFC here.
243 */
244 {
245 "\xEF\xBF\xBC",
246 "\xEF\xBF\xBC",
247 "\\uFFFC",
248 },
249 /* 2.2.4 4 bytes U+1FFFFF */
250 {
251 "\xF7\xBF\xBF\xBF",
252 NULL,
253 "\\uFFFD",
254 },
255 /* 2.2.5 5 bytes U+3FFFFFF */
256 {
257 "\xFB\xBF\xBF\xBF\xBF",
258 NULL,
259 "\\uFFFD",
260 },
261 /* 2.2.6 6 bytes U+7FFFFFFF */
262 {
263 "\xFD\xBF\xBF\xBF\xBF\xBF",
264 NULL,
265 "\\uFFFD",
266 },
267 /* 2.3 Other boundary conditions */
268 {
269 /* last one before surrogate range: U+D7FF */
270 "\xED\x9F\xBF",
271 "\xED\x9F\xBF",
272 "\\uD7FF",
273 },
274 {
275 /* first one after surrogate range: U+E000 */
276 "\xEE\x80\x80",
277 "\xEE\x80\x80",
278 "\\uE000",
279 },
280 {
281 /* last one in BMP: U+FFFD */
282 "\xEF\xBF\xBD",
283 "\xEF\xBF\xBD",
284 "\\uFFFD",
285 },
286 {
287 /* last one in last plane: U+10FFFD */
288 "\xF4\x8F\xBF\xBD",
289 "\xF4\x8F\xBF\xBD",
290 "\\uDBFF\\uDFFD"
291 },
292 {
293 /* first one beyond Unicode range: U+110000 */
294 "\xF4\x90\x80\x80",
295 NULL,
296 "\\uFFFD",
297 },
298 /* 3 Malformed sequences */
299 /* 3.1 Unexpected continuation bytes */
300 /* 3.1.1 First continuation byte */
301 {
302 "\x80",
303 NULL,
304 "\\uFFFD",
305 },
306 /* 3.1.2 Last continuation byte */
307 {
308 "\xBF",
309 NULL,
310 "\\uFFFD",
311 },
312 /* 3.1.3 2 continuation bytes */
313 {
314 "\x80\xBF",
315 NULL,
316 "\\uFFFD\\uFFFD",
317 },
318 /* 3.1.4 3 continuation bytes */
319 {
320 "\x80\xBF\x80",
321 NULL,
322 "\\uFFFD\\uFFFD\\uFFFD",
323 },
324 /* 3.1.5 4 continuation bytes */
325 {
326 "\x80\xBF\x80\xBF",
327 NULL,
328 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
329 },
330 /* 3.1.6 5 continuation bytes */
331 {
332 "\x80\xBF\x80\xBF\x80",
333 NULL,
334 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
335 },
336 /* 3.1.7 6 continuation bytes */
337 {
338 "\x80\xBF\x80\xBF\x80\xBF",
339 NULL,
340 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
341 },
342 /* 3.1.8 7 continuation bytes */
343 {
344 "\x80\xBF\x80\xBF\x80\xBF\x80",
345 NULL,
346 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
347 },
348 /* 3.1.9 Sequence of all 64 possible continuation bytes */
349 {
350 "\x80\x81\x82\x83\x84\x85\x86\x87"
351 "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
352 "\x90\x91\x92\x93\x94\x95\x96\x97"
353 "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
354 "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
355 "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
356 "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
357 "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
358 NULL,
359 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
360 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
361 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
362 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
363 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
364 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
365 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
366 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
367 },
368 /* 3.2 Lonely start characters */
369 /* 3.2.1 All 32 first bytes of 2-byte sequences, followed by space */
370 {
371 "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
372 "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
373 "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
374 "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
375 NULL,
376 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
377 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
378 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
379 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
380 },
381 /* 3.2.2 All 16 first bytes of 3-byte sequences, followed by space */
382 {
383 "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
384 "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
385 NULL,
386 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
387 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
388 },
389 /* 3.2.3 All 8 first bytes of 4-byte sequences, followed by space */
390 {
391 "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
392 NULL,
393 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
394 },
395 /* 3.2.4 All 4 first bytes of 5-byte sequences, followed by space */
396 {
397 "\xF8 \xF9 \xFA \xFB ",
398 NULL,
399 "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
400 },
401 /* 3.2.5 All 2 first bytes of 6-byte sequences, followed by space */
402 {
403 "\xFC \xFD ",
404 NULL,
405 "\\uFFFD \\uFFFD ",
406 },
407 /* 3.3 Sequences with last continuation byte missing */
408 /* 3.3.1 2-byte sequence with last byte missing (U+0000) */
409 {
410 "\xC0",
411 NULL,
412 "\\uFFFD",
413 },
414 /* 3.3.2 3-byte sequence with last byte missing (U+0000) */
415 {
416 "\xE0\x80",
417 NULL,
418 "\\uFFFD",
419 },
420 /* 3.3.3 4-byte sequence with last byte missing (U+0000) */
421 {
422 "\xF0\x80\x80",
423 NULL,
424 "\\uFFFD",
425 },
426 /* 3.3.4 5-byte sequence with last byte missing (U+0000) */
427 {
428 "\xF8\x80\x80\x80",
429 NULL,
430 "\\uFFFD",
431 },
432 /* 3.3.5 6-byte sequence with last byte missing (U+0000) */
433 {
434 "\xFC\x80\x80\x80\x80",
435 NULL,
436 "\\uFFFD",
437 },
438 /* 3.3.6 2-byte sequence with last byte missing (U+07FF) */
439 {
440 "\xDF",
441 NULL,
442 "\\uFFFD",
443 },
444 /* 3.3.7 3-byte sequence with last byte missing (U+FFFF) */
445 {
446 "\xEF\xBF",
447 NULL,
448 "\\uFFFD",
449 },
450 /* 3.3.8 4-byte sequence with last byte missing (U+1FFFFF) */
451 {
452 "\xF7\xBF\xBF",
453 NULL,
454 "\\uFFFD",
455 },
456 /* 3.3.9 5-byte sequence with last byte missing (U+3FFFFFF) */
457 {
458 "\xFB\xBF\xBF\xBF",
459 NULL,
460 "\\uFFFD",
461 },
462 /* 3.3.10 6-byte sequence with last byte missing (U+7FFFFFFF) */
463 {
464 "\xFD\xBF\xBF\xBF\xBF",
465 NULL,
466 "\\uFFFD",
467 },
468 /* 3.4 Concatenation of incomplete sequences */
469 {
470 "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
471 "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
472 NULL,
473 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
474 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
475 },
476 /* 3.5 Impossible bytes */
477 {
478 "\xFE",
479 NULL,
480 "\\uFFFD",
481 },
482 {
483 "\xFF",
484 NULL,
485 "\\uFFFD",
486 },
487 {
488 "\xFE\xFE\xFF\xFF",
489 NULL,
490 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
491 },
492 /* 4 Overlong sequences */
493 /* 4.1 Overlong '/' */
494 {
495 "\xC0\xAF",
496 NULL,
497 "\\uFFFD",
498 },
499 {
500 "\xE0\x80\xAF",
501 NULL,
502 "\\uFFFD",
503 },
504 {
505 "\xF0\x80\x80\xAF",
506 NULL,
507 "\\uFFFD",
508 },
509 {
510 "\xF8\x80\x80\x80\xAF",
511 NULL,
512 "\\uFFFD",
513 },
514 {
515 "\xFC\x80\x80\x80\x80\xAF",
516 NULL,
517 "\\uFFFD",
518 },
519 /*
520 * 4.2 Maximum overlong sequences
521 * Highest Unicode value that is still resulting in an
522 * overlong sequence if represented with the given number of
523 * bytes. This is a boundary test for safe UTF-8 decoders.
524 */
525 {
526 /* \U+007F */
527 "\xC1\xBF",
528 NULL,
529 "\\uFFFD",
530 },
531 {
532 /* \U+07FF */
533 "\xE0\x9F\xBF",
534 NULL,
535 "\\uFFFD",
536 },
537 {
538 /*
539 * \U+FFFC
540 * The actual maximum would be U+FFFF, but that's a
541 * noncharacter. Testing U+FFFC seems more useful. See
542 * also 2.2.3
543 */
544 "\xF0\x8F\xBF\xBC",
545 NULL,
546 "\\uFFFD",
547 },
548 {
549 /* \U+1FFFFF */
550 "\xF8\x87\xBF\xBF\xBF",
551 NULL,
552 "\\uFFFD",
553 },
554 {
555 /* \U+3FFFFFF */
556 "\xFC\x83\xBF\xBF\xBF\xBF",
557 NULL,
558 "\\uFFFD",
559 },
560 /* 4.3 Overlong representation of the NUL character */
561 {
562 /* \U+0000 */
563 "\xC0\x80",
564 "\xC0\x80",
565 "\\u0000",
566 },
567 {
568 /* \U+0000 */
569 "\xE0\x80\x80",
570 NULL,
571 "\\uFFFD",
572 },
573 {
574 /* \U+0000 */
575 "\xF0\x80\x80\x80",
576 NULL,
577 "\\uFFFD",
578 },
579 {
580 /* \U+0000 */
581 "\xF8\x80\x80\x80\x80",
582 NULL,
583 "\\uFFFD",
584 },
585 {
586 /* \U+0000 */
587 "\xFC\x80\x80\x80\x80\x80",
588 NULL,
589 "\\uFFFD",
590 },
591 /* 5 Illegal code positions */
592 /* 5.1 Single UTF-16 surrogates */
593 {
594 /* \U+D800 */
595 "\xED\xA0\x80",
596 NULL,
597 "\\uFFFD",
598 },
599 {
600 /* \U+DB7F */
601 "\xED\xAD\xBF",
602 NULL,
603 "\\uFFFD",
604 },
605 {
606 /* \U+DB80 */
607 "\xED\xAE\x80",
608 NULL,
609 "\\uFFFD",
610 },
611 {
612 /* \U+DBFF */
613 "\xED\xAF\xBF",
614 NULL,
615 "\\uFFFD",
616 },
617 {
618 /* \U+DC00 */
619 "\xED\xB0\x80",
620 NULL,
621 "\\uFFFD",
622 },
623 {
624 /* \U+DF80 */
625 "\xED\xBE\x80",
626 NULL,
627 "\\uFFFD",
628 },
629 {
630 /* \U+DFFF */
631 "\xED\xBF\xBF",
632 NULL,
633 "\\uFFFD",
634 },
635 /* 5.2 Paired UTF-16 surrogates */
636 {
637 /* \U+D800\U+DC00 */
638 "\xED\xA0\x80\xED\xB0\x80",
639 NULL,
640 "\\uFFFD\\uFFFD",
641 },
642 {
643 /* \U+D800\U+DFFF */
644 "\xED\xA0\x80\xED\xBF\xBF",
645 NULL,
646 "\\uFFFD\\uFFFD",
647 },
648 {
649 /* \U+DB7F\U+DC00 */
650 "\xED\xAD\xBF\xED\xB0\x80",
651 NULL,
652 "\\uFFFD\\uFFFD",
653 },
654 {
655 /* \U+DB7F\U+DFFF */
656 "\xED\xAD\xBF\xED\xBF\xBF",
657 NULL,
658 "\\uFFFD\\uFFFD",
659 },
660 {
661 /* \U+DB80\U+DC00 */
662 "\xED\xAE\x80\xED\xB0\x80",
663 NULL,
664 "\\uFFFD\\uFFFD",
665 },
666 {
667 /* \U+DB80\U+DFFF */
668 "\xED\xAE\x80\xED\xBF\xBF",
669 NULL,
670 "\\uFFFD\\uFFFD",
671 },
672 {
673 /* \U+DBFF\U+DC00 */
674 "\xED\xAF\xBF\xED\xB0\x80",
675 NULL,
676 "\\uFFFD\\uFFFD",
677 },
678 {
679 /* \U+DBFF\U+DFFF */
680 "\xED\xAF\xBF\xED\xBF\xBF",
681 NULL,
682 "\\uFFFD\\uFFFD",
683 },
684 /* 5.3 Other illegal code positions */
685 /* BMP noncharacters */
686 {
687 /* \U+FFFE */
688 "\xEF\xBF\xBE",
689 NULL,
690 "\\uFFFD",
691 },
692 {
693 /* \U+FFFF */
694 "\xEF\xBF\xBF",
695 NULL,
696 "\\uFFFD",
697 },
698 {
699 /* U+FDD0 */
700 "\xEF\xB7\x90",
701 NULL,
702 "\\uFFFD",
703 },
704 {
705 /* U+FDEF */
706 "\xEF\xB7\xAF",
707 NULL,
708 "\\uFFFD",
709 },
710 /* Plane 1 .. 16 noncharacters */
711 {
712 /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
713 "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
714 "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
715 "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
716 "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
717 "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
718 "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
719 "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
720 "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
721 "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
722 "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
723 "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
724 "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
725 "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
726 "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
727 "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
728 "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
729 NULL,
730 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
731 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
732 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
733 "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
734 },
735 {}
736 };
737 int i, j;
738 QString *str;
739 const char *json_in, *utf8_out, *utf8_in, *json_out, *tail;
740 char *end, *in, *jstr;
741
742 for (i = 0; test_cases[i].json_in; i++) {
743 for (j = 0; j < 2; j++) {
744 json_in = test_cases[i].json_in;
745 utf8_out = test_cases[i].utf8_out;
746 utf8_in = test_cases[i].utf8_out ?: test_cases[i].json_in;
747 json_out = test_cases[i].json_out ?: test_cases[i].json_in;
748
749 /* Parse @json_in, expect @utf8_out */
750 if (utf8_out) {
751 str = from_json_str(json_in, j, &error_abort);
752 g_assert_cmpstr(qstring_get_try_str(str), ==, utf8_out);
753 qobject_unref(str);
754 } else {
755 str = from_json_str(json_in, j, NULL);
756 g_assert(!str);
757 /*
758 * Failure may be due to any sequence, but *all* sequences
759 * are expected to fail. Test each one in isolation.
760 */
761 for (tail = json_in; *tail; tail = end) {
762 mod_utf8_codepoint(tail, 6, &end);
763 if (*end == ' ') {
764 end++;
765 }
766 in = strndup(tail, end - tail);
767 str = from_json_str(in, j, NULL);
768 g_assert(!str);
769 g_free(in);
770 }
771 }
772
773 /* Unparse @utf8_in, expect @json_out */
774 str = qstring_from_str(utf8_in);
775 jstr = to_json_str(str);
776 g_assert_cmpstr(jstr, ==, json_out);
777 qobject_unref(str);
778 g_free(jstr);
779
780 /*
781 * Parse @json_out right back
782 * Disabled, because qobject_from_json() is buggy, and I can't
783 * be bothered to add the expected incorrect results.
784 * FIXME Enable once these bugs have been fixed.
785 */
786 if (0 && json_out != json_in) {
787 str = from_json_str(json_out, j, &error_abort);
788 g_assert_cmpstr(qstring_get_try_str(str), ==, utf8_out);
789 }
790 }
791 }
792 }
793
794 static void simple_number(void)
795 {
796 int i;
797 struct {
798 const char *encoded;
799 int64_t decoded;
800 int skip;
801 } test_cases[] = {
802 { "0", 0 },
803 { "1234", 1234 },
804 { "1", 1 },
805 { "-32", -32 },
806 { "-0", 0, .skip = 1 },
807 { },
808 };
809
810 for (i = 0; test_cases[i].encoded; i++) {
811 QNum *qnum;
812 int64_t val;
813
814 qnum = qobject_to(QNum,
815 qobject_from_json(test_cases[i].encoded,
816 &error_abort));
817 g_assert(qnum);
818 g_assert(qnum_get_try_int(qnum, &val));
819 g_assert_cmpint(val, ==, test_cases[i].decoded);
820 if (test_cases[i].skip == 0) {
821 QString *str;
822
823 str = qobject_to_json(QOBJECT(qnum));
824 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
825 qobject_unref(str);
826 }
827
828 qobject_unref(qnum);
829 }
830 }
831
832 static void large_number(void)
833 {
834 const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
835 const char *gtu64 = "18446744073709551616"; /* 2^64 */
836 const char *lti64 = "-9223372036854775809"; /* -2^63 - 1 */
837 QNum *qnum;
838 QString *str;
839 uint64_t val;
840 int64_t ival;
841
842 qnum = qobject_to(QNum, qobject_from_json(maxu64, &error_abort));
843 g_assert(qnum);
844 g_assert_cmpuint(qnum_get_uint(qnum), ==, 18446744073709551615U);
845 g_assert(!qnum_get_try_int(qnum, &ival));
846
847 str = qobject_to_json(QOBJECT(qnum));
848 g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
849 qobject_unref(str);
850 qobject_unref(qnum);
851
852 qnum = qobject_to(QNum, qobject_from_json(gtu64, &error_abort));
853 g_assert(qnum);
854 g_assert_cmpfloat(qnum_get_double(qnum), ==, 18446744073709552e3);
855 g_assert(!qnum_get_try_uint(qnum, &val));
856 g_assert(!qnum_get_try_int(qnum, &ival));
857
858 str = qobject_to_json(QOBJECT(qnum));
859 g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
860 qobject_unref(str);
861 qobject_unref(qnum);
862
863 qnum = qobject_to(QNum, qobject_from_json(lti64, &error_abort));
864 g_assert(qnum);
865 g_assert_cmpfloat(qnum_get_double(qnum), ==, -92233720368547758e2);
866 g_assert(!qnum_get_try_uint(qnum, &val));
867 g_assert(!qnum_get_try_int(qnum, &ival));
868
869 str = qobject_to_json(QOBJECT(qnum));
870 g_assert_cmpstr(qstring_get_str(str), ==, "-9223372036854775808");
871 qobject_unref(str);
872 qobject_unref(qnum);
873 }
874
875 static void float_number(void)
876 {
877 int i;
878 struct {
879 const char *encoded;
880 double decoded;
881 int skip;
882 } test_cases[] = {
883 { "32.43", 32.43 },
884 { "0.222", 0.222 },
885 { "-32.12313", -32.12313 },
886 { "-32.20e-10", -32.20e-10, .skip = 1 },
887 { },
888 };
889
890 for (i = 0; test_cases[i].encoded; i++) {
891 QObject *obj;
892 QNum *qnum;
893
894 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
895 qnum = qobject_to(QNum, obj);
896 g_assert(qnum);
897 g_assert(qnum_get_double(qnum) == test_cases[i].decoded);
898
899 if (test_cases[i].skip == 0) {
900 QString *str;
901
902 str = qobject_to_json(obj);
903 g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
904 qobject_unref(str);
905 }
906
907 qobject_unref(qnum);
908 }
909 }
910
911 static void keyword_literal(void)
912 {
913 QObject *obj;
914 QBool *qbool;
915 QNull *null;
916 QString *str;
917
918 obj = qobject_from_json("true", &error_abort);
919 qbool = qobject_to(QBool, obj);
920 g_assert(qbool);
921 g_assert(qbool_get_bool(qbool) == true);
922
923 str = qobject_to_json(obj);
924 g_assert(strcmp(qstring_get_str(str), "true") == 0);
925 qobject_unref(str);
926
927 qobject_unref(qbool);
928
929 obj = qobject_from_json("false", &error_abort);
930 qbool = qobject_to(QBool, obj);
931 g_assert(qbool);
932 g_assert(qbool_get_bool(qbool) == false);
933
934 str = qobject_to_json(obj);
935 g_assert(strcmp(qstring_get_str(str), "false") == 0);
936 qobject_unref(str);
937
938 qobject_unref(qbool);
939
940 obj = qobject_from_json("null", &error_abort);
941 g_assert(obj != NULL);
942 g_assert(qobject_type(obj) == QTYPE_QNULL);
943
944 null = qnull();
945 g_assert(QOBJECT(null) == obj);
946
947 qobject_unref(obj);
948 qobject_unref(null);
949 }
950
951 static void interpolation_valid(void)
952 {
953 long long value_lld = 0x123456789abcdefLL;
954 long value_ld = (long)value_lld;
955 int value_d = (int)value_lld;
956 unsigned long long value_llu = 0xfedcba9876543210ULL;
957 unsigned long value_lu = (unsigned long)value_llu;
958 unsigned value_u = (unsigned)value_llu;
959 double value_f = 2.323423423;
960 const char *value_s = "hello world";
961 QObject *value_p = QOBJECT(qnull());
962 QBool *qbool;
963 QNum *qnum;
964 QString *qstr;
965 QObject *qobj;
966
967 /* bool */
968
969 qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", false));
970 g_assert(qbool);
971 g_assert(qbool_get_bool(qbool) == false);
972 qobject_unref(qbool);
973
974 /* Test that non-zero values other than 1 get collapsed to true */
975 qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", 2));
976 g_assert(qbool);
977 g_assert(qbool_get_bool(qbool) == true);
978 qobject_unref(qbool);
979
980 /* number */
981
982 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%d", value_d));
983 g_assert_cmpint(qnum_get_int(qnum), ==, value_d);
984 qobject_unref(qnum);
985
986 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%ld", value_ld));
987 g_assert_cmpint(qnum_get_int(qnum), ==, value_ld);
988 qobject_unref(qnum);
989
990 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lld", value_lld));
991 g_assert_cmpint(qnum_get_int(qnum), ==, value_lld);
992 qobject_unref(qnum);
993
994 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%u", value_u));
995 g_assert_cmpuint(qnum_get_uint(qnum), ==, value_u);
996 qobject_unref(qnum);
997
998 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lu", value_lu));
999 g_assert_cmpuint(qnum_get_uint(qnum), ==, value_lu);
1000 qobject_unref(qnum);
1001
1002 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%llu", value_llu));
1003 g_assert_cmpuint(qnum_get_uint(qnum), ==, value_llu);
1004 qobject_unref(qnum);
1005
1006 qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%f", value_f));
1007 g_assert(qnum_get_double(qnum) == value_f);
1008 qobject_unref(qnum);
1009
1010 /* string */
1011
1012 qstr = qobject_to(QString,
1013 qobject_from_jsonf_nofail("%s", value_s));
1014 g_assert_cmpstr(qstring_get_try_str(qstr), ==, value_s);
1015 qobject_unref(qstr);
1016
1017 /* object */
1018
1019 qobj = qobject_from_jsonf_nofail("%p", value_p);
1020 g_assert(qobj == value_p);
1021 }
1022
1023 static void interpolation_unknown(void)
1024 {
1025 if (g_test_subprocess()) {
1026 qobject_from_jsonf_nofail("%x", 666);
1027 }
1028 g_test_trap_subprocess(NULL, 0, 0);
1029 g_test_trap_assert_failed();
1030 }
1031
1032 static void interpolation_string(void)
1033 {
1034 QLitObject decoded = QLIT_QLIST(((QLitObject[]){
1035 QLIT_QSTR("%s"),
1036 QLIT_QSTR("eins"),
1037 {}}));
1038 QObject *qobj;
1039
1040 /* Dangerous misfeature: % is silently ignored in strings */
1041 qobj = qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1042 g_assert(qlit_equal_qobject(&decoded, qobj));
1043 qobject_unref(qobj);
1044 }
1045
1046 static void simple_dict(void)
1047 {
1048 int i;
1049 struct {
1050 const char *encoded;
1051 QLitObject decoded;
1052 } test_cases[] = {
1053 {
1054 .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
1055 .decoded = QLIT_QDICT(((QLitDictEntry[]){
1056 { "foo", QLIT_QNUM(42) },
1057 { "bar", QLIT_QSTR("hello world") },
1058 { }
1059 })),
1060 }, {
1061 .encoded = "{}",
1062 .decoded = QLIT_QDICT(((QLitDictEntry[]){
1063 { }
1064 })),
1065 }, {
1066 .encoded = "{\"foo\": 43}",
1067 .decoded = QLIT_QDICT(((QLitDictEntry[]){
1068 { "foo", QLIT_QNUM(43) },
1069 { }
1070 })),
1071 },
1072 { }
1073 };
1074
1075 for (i = 0; test_cases[i].encoded; i++) {
1076 QObject *obj;
1077 QString *str;
1078
1079 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1080 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1081
1082 str = qobject_to_json(obj);
1083 qobject_unref(obj);
1084
1085 obj = qobject_from_json(qstring_get_str(str), &error_abort);
1086 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1087 qobject_unref(obj);
1088 qobject_unref(str);
1089 }
1090 }
1091
1092 /*
1093 * this generates json of the form:
1094 * a(0,m) = [0, 1, ..., m-1]
1095 * a(n,m) = {
1096 * 'key0': a(0,m),
1097 * 'key1': a(1,m),
1098 * ...
1099 * 'key(n-1)': a(n-1,m)
1100 * }
1101 */
1102 static void gen_test_json(GString *gstr, int nest_level_max,
1103 int elem_count)
1104 {
1105 int i;
1106
1107 g_assert(gstr);
1108 if (nest_level_max == 0) {
1109 g_string_append(gstr, "[");
1110 for (i = 0; i < elem_count; i++) {
1111 g_string_append_printf(gstr, "%d", i);
1112 if (i < elem_count - 1) {
1113 g_string_append_printf(gstr, ", ");
1114 }
1115 }
1116 g_string_append(gstr, "]");
1117 return;
1118 }
1119
1120 g_string_append(gstr, "{");
1121 for (i = 0; i < nest_level_max; i++) {
1122 g_string_append_printf(gstr, "'key%d': ", i);
1123 gen_test_json(gstr, i, elem_count);
1124 if (i < nest_level_max - 1) {
1125 g_string_append(gstr, ",");
1126 }
1127 }
1128 g_string_append(gstr, "}");
1129 }
1130
1131 static void large_dict(void)
1132 {
1133 GString *gstr = g_string_new("");
1134 QObject *obj;
1135
1136 gen_test_json(gstr, 10, 100);
1137 obj = qobject_from_json(gstr->str, &error_abort);
1138 g_assert(obj != NULL);
1139
1140 qobject_unref(obj);
1141 g_string_free(gstr, true);
1142 }
1143
1144 static void simple_list(void)
1145 {
1146 int i;
1147 struct {
1148 const char *encoded;
1149 QLitObject decoded;
1150 } test_cases[] = {
1151 {
1152 .encoded = "[43,42]",
1153 .decoded = QLIT_QLIST(((QLitObject[]){
1154 QLIT_QNUM(43),
1155 QLIT_QNUM(42),
1156 { }
1157 })),
1158 },
1159 {
1160 .encoded = "[43]",
1161 .decoded = QLIT_QLIST(((QLitObject[]){
1162 QLIT_QNUM(43),
1163 { }
1164 })),
1165 },
1166 {
1167 .encoded = "[]",
1168 .decoded = QLIT_QLIST(((QLitObject[]){
1169 { }
1170 })),
1171 },
1172 {
1173 .encoded = "[{}]",
1174 .decoded = QLIT_QLIST(((QLitObject[]){
1175 QLIT_QDICT(((QLitDictEntry[]){
1176 {},
1177 })),
1178 {},
1179 })),
1180 },
1181 { }
1182 };
1183
1184 for (i = 0; test_cases[i].encoded; i++) {
1185 QObject *obj;
1186 QString *str;
1187
1188 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1189 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1190
1191 str = qobject_to_json(obj);
1192 qobject_unref(obj);
1193
1194 obj = qobject_from_json(qstring_get_str(str), &error_abort);
1195 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1196 qobject_unref(obj);
1197 qobject_unref(str);
1198 }
1199 }
1200
1201 static void simple_whitespace(void)
1202 {
1203 int i;
1204 struct {
1205 const char *encoded;
1206 QLitObject decoded;
1207 } test_cases[] = {
1208 {
1209 .encoded = " [ 43 , 42 ]",
1210 .decoded = QLIT_QLIST(((QLitObject[]){
1211 QLIT_QNUM(43),
1212 QLIT_QNUM(42),
1213 { }
1214 })),
1215 },
1216 {
1217 .encoded = "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1218 .decoded = QLIT_QLIST(((QLitObject[]){
1219 QLIT_QNUM(43),
1220 QLIT_QDICT(((QLitDictEntry[]){
1221 { "h", QLIT_QSTR("b") },
1222 { }})),
1223 QLIT_QLIST(((QLitObject[]){
1224 { }})),
1225 QLIT_QNUM(42),
1226 { }
1227 })),
1228 },
1229 {
1230 .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1231 .decoded = QLIT_QLIST(((QLitObject[]){
1232 QLIT_QNUM(43),
1233 QLIT_QDICT(((QLitDictEntry[]){
1234 { "h", QLIT_QSTR("b") },
1235 { "a", QLIT_QNUM(32) },
1236 { }})),
1237 QLIT_QLIST(((QLitObject[]){
1238 { }})),
1239 QLIT_QNUM(42),
1240 { }
1241 })),
1242 },
1243 { }
1244 };
1245
1246 for (i = 0; test_cases[i].encoded; i++) {
1247 QObject *obj;
1248 QString *str;
1249
1250 obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1251 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1252
1253 str = qobject_to_json(obj);
1254 qobject_unref(obj);
1255
1256 obj = qobject_from_json(qstring_get_str(str), &error_abort);
1257 g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1258
1259 qobject_unref(obj);
1260 qobject_unref(str);
1261 }
1262 }
1263
1264 static void simple_interpolation(void)
1265 {
1266 QObject *embedded_obj;
1267 QObject *obj;
1268 QLitObject decoded = QLIT_QLIST(((QLitObject[]){
1269 QLIT_QNUM(1),
1270 QLIT_QNUM(2),
1271 QLIT_QLIST(((QLitObject[]){
1272 QLIT_QNUM(32),
1273 QLIT_QNUM(42),
1274 {}})),
1275 {}}));
1276
1277 embedded_obj = qobject_from_json("[32, 42]", &error_abort);
1278 g_assert(embedded_obj != NULL);
1279
1280 obj = qobject_from_jsonf_nofail("[%d, 2, %p]", 1, embedded_obj);
1281 g_assert(qlit_equal_qobject(&decoded, obj));
1282
1283 qobject_unref(obj);
1284 }
1285
1286 static void empty_input(void)
1287 {
1288 QObject *obj = qobject_from_json("", &error_abort);
1289 g_assert(obj == NULL);
1290 }
1291
1292 static void blank_input(void)
1293 {
1294 QObject *obj = qobject_from_json("\n ", &error_abort);
1295 g_assert(obj == NULL);
1296 }
1297
1298 static void junk_input(void)
1299 {
1300 /* Note: junk within strings is covered elsewhere */
1301 Error *err = NULL;
1302 QObject *obj;
1303
1304 obj = qobject_from_json("@", &err);
1305 g_assert(!err); /* BUG */
1306 g_assert(obj == NULL);
1307
1308 obj = qobject_from_json("{\x01", &err);
1309 g_assert(!err); /* BUG */
1310 g_assert(obj == NULL);
1311
1312 obj = qobject_from_json("[0\xFF]", &err);
1313 error_free_or_abort(&err);
1314 g_assert(obj == NULL);
1315
1316 obj = qobject_from_json("00", &err);
1317 g_assert(!err); /* BUG */
1318 g_assert(obj == NULL);
1319
1320 obj = qobject_from_json("[1e", &err);
1321 g_assert(!err); /* BUG */
1322 g_assert(obj == NULL);
1323
1324 obj = qobject_from_json("truer", &err);
1325 error_free_or_abort(&err);
1326 g_assert(obj == NULL);
1327 }
1328
1329 static void unterminated_string(void)
1330 {
1331 Error *err = NULL;
1332 QObject *obj = qobject_from_json("\"abc", &err);
1333 g_assert(!err); /* BUG */
1334 g_assert(obj == NULL);
1335 }
1336
1337 static void unterminated_sq_string(void)
1338 {
1339 Error *err = NULL;
1340 QObject *obj = qobject_from_json("'abc", &err);
1341 g_assert(!err); /* BUG */
1342 g_assert(obj == NULL);
1343 }
1344
1345 static void unterminated_escape(void)
1346 {
1347 Error *err = NULL;
1348 QObject *obj = qobject_from_json("\"abc\\\"", &err);
1349 g_assert(!err); /* BUG */
1350 g_assert(obj == NULL);
1351 }
1352
1353 static void unterminated_array(void)
1354 {
1355 Error *err = NULL;
1356 QObject *obj = qobject_from_json("[32", &err);
1357 g_assert(!err); /* BUG */
1358 g_assert(obj == NULL);
1359 }
1360
1361 static void unterminated_array_comma(void)
1362 {
1363 Error *err = NULL;
1364 QObject *obj = qobject_from_json("[32,", &err);
1365 g_assert(!err); /* BUG */
1366 g_assert(obj == NULL);
1367 }
1368
1369 static void invalid_array_comma(void)
1370 {
1371 Error *err = NULL;
1372 QObject *obj = qobject_from_json("[32,}", &err);
1373 error_free_or_abort(&err);
1374 g_assert(obj == NULL);
1375 }
1376
1377 static void unterminated_dict(void)
1378 {
1379 Error *err = NULL;
1380 QObject *obj = qobject_from_json("{'abc':32", &err);
1381 g_assert(!err); /* BUG */
1382 g_assert(obj == NULL);
1383 }
1384
1385 static void unterminated_dict_comma(void)
1386 {
1387 Error *err = NULL;
1388 QObject *obj = qobject_from_json("{'abc':32,", &err);
1389 g_assert(!err); /* BUG */
1390 g_assert(obj == NULL);
1391 }
1392
1393 static void invalid_dict_comma(void)
1394 {
1395 Error *err = NULL;
1396 QObject *obj = qobject_from_json("{'abc':32,}", &err);
1397 error_free_or_abort(&err);
1398 g_assert(obj == NULL);
1399 }
1400
1401 static void unterminated_literal(void)
1402 {
1403 Error *err = NULL;
1404 QObject *obj = qobject_from_json("nul", &err);
1405 error_free_or_abort(&err);
1406 g_assert(obj == NULL);
1407 }
1408
1409 static char *make_nest(char *buf, size_t cnt)
1410 {
1411 memset(buf, '[', cnt - 1);
1412 buf[cnt - 1] = '{';
1413 buf[cnt] = '}';
1414 memset(buf + cnt + 1, ']', cnt - 1);
1415 buf[2 * cnt] = 0;
1416 return buf;
1417 }
1418
1419 static void limits_nesting(void)
1420 {
1421 Error *err = NULL;
1422 enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
1423 char buf[2 * (max_nesting + 1) + 1];
1424 QObject *obj;
1425
1426 obj = qobject_from_json(make_nest(buf, max_nesting), &error_abort);
1427 g_assert(obj != NULL);
1428 qobject_unref(obj);
1429
1430 obj = qobject_from_json(make_nest(buf, max_nesting + 1), &err);
1431 error_free_or_abort(&err);
1432 g_assert(obj == NULL);
1433 }
1434
1435 static void multiple_values(void)
1436 {
1437 Error *err = NULL;
1438 QObject *obj;
1439
1440 /* BUG this leaks the syntax tree for "false" */
1441 obj = qobject_from_json("false true", &err);
1442 g_assert(qbool_get_bool(qobject_to(QBool, obj)));
1443 g_assert(!err);
1444 qobject_unref(obj);
1445
1446 /* BUG simultaneously succeeds and fails */
1447 /* BUG calls json_parser_parse() with errp pointing to non-null */
1448 obj = qobject_from_json("} true", &err);
1449 g_assert(qbool_get_bool(qobject_to(QBool, obj)));
1450 error_free_or_abort(&err);
1451 qobject_unref(obj);
1452 }
1453
1454 int main(int argc, char **argv)
1455 {
1456 g_test_init(&argc, &argv, NULL);
1457
1458 g_test_add_func("/literals/string/escaped", escaped_string);
1459 g_test_add_func("/literals/string/quotes", string_with_quotes);
1460 g_test_add_func("/literals/string/utf8", utf8_string);
1461
1462 g_test_add_func("/literals/number/simple", simple_number);
1463 g_test_add_func("/literals/number/large", large_number);
1464 g_test_add_func("/literals/number/float", float_number);
1465
1466 g_test_add_func("/literals/keyword", keyword_literal);
1467
1468 g_test_add_func("/literals/interpolation/valid", interpolation_valid);
1469 g_test_add_func("/literals/interpolation/unkown", interpolation_unknown);
1470 g_test_add_func("/literals/interpolation/string", interpolation_string);
1471
1472 g_test_add_func("/dicts/simple_dict", simple_dict);
1473 g_test_add_func("/dicts/large_dict", large_dict);
1474 g_test_add_func("/lists/simple_list", simple_list);
1475
1476 g_test_add_func("/mixed/simple_whitespace", simple_whitespace);
1477 g_test_add_func("/mixed/interpolation", simple_interpolation);
1478
1479 g_test_add_func("/errors/empty", empty_input);
1480 g_test_add_func("/errors/blank", blank_input);
1481 g_test_add_func("/errors/junk", junk_input);
1482 g_test_add_func("/errors/unterminated/string", unterminated_string);
1483 g_test_add_func("/errors/unterminated/escape", unterminated_escape);
1484 g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string);
1485 g_test_add_func("/errors/unterminated/array", unterminated_array);
1486 g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma);
1487 g_test_add_func("/errors/unterminated/dict", unterminated_dict);
1488 g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma);
1489 g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
1490 g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
1491 g_test_add_func("/errors/unterminated/literal", unterminated_literal);
1492 g_test_add_func("/errors/limits/nesting", limits_nesting);
1493 g_test_add_func("/errors/multiple_values", multiple_values);
1494
1495 return g_test_run();
1496 }