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