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