]> Git Repo - qemu.git/blob - tests/check-qjson.c
tests: tcg: mips: Move source files to new locations
[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   <[email protected]>
7  *  Markus Armbruster <[email protected]>
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                 qobject_unref(str);
784             }
785         }
786     }
787 }
788
789 static void simple_number(void)
790 {
791     int i;
792     struct {
793         const char *encoded;
794         int64_t decoded;
795         int skip;
796     } test_cases[] = {
797         { "0", 0 },
798         { "1234", 1234 },
799         { "1", 1 },
800         { "-32", -32 },
801         { "-0", 0, .skip = 1 },
802         { },
803     };
804
805     for (i = 0; test_cases[i].encoded; i++) {
806         QNum *qnum;
807         int64_t val;
808
809         qnum = qobject_to(QNum,
810                           qobject_from_json(test_cases[i].encoded,
811                                             &error_abort));
812         g_assert(qnum);
813         g_assert(qnum_get_try_int(qnum, &val));
814         g_assert_cmpint(val, ==, test_cases[i].decoded);
815         if (test_cases[i].skip == 0) {
816             QString *str;
817
818             str = qobject_to_json(QOBJECT(qnum));
819             g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
820             qobject_unref(str);
821         }
822
823         qobject_unref(qnum);
824     }
825 }
826
827 static void large_number(void)
828 {
829     const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
830     const char *gtu64 = "18446744073709551616"; /* 2^64 */
831     const char *lti64 = "-9223372036854775809"; /* -2^63 - 1 */
832     QNum *qnum;
833     QString *str;
834     uint64_t val;
835     int64_t ival;
836
837     qnum = qobject_to(QNum, qobject_from_json(maxu64, &error_abort));
838     g_assert(qnum);
839     g_assert_cmpuint(qnum_get_uint(qnum), ==, 18446744073709551615U);
840     g_assert(!qnum_get_try_int(qnum, &ival));
841
842     str = qobject_to_json(QOBJECT(qnum));
843     g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
844     qobject_unref(str);
845     qobject_unref(qnum);
846
847     qnum = qobject_to(QNum, qobject_from_json(gtu64, &error_abort));
848     g_assert(qnum);
849     g_assert_cmpfloat(qnum_get_double(qnum), ==, 18446744073709552e3);
850     g_assert(!qnum_get_try_uint(qnum, &val));
851     g_assert(!qnum_get_try_int(qnum, &ival));
852
853     str = qobject_to_json(QOBJECT(qnum));
854     g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
855     qobject_unref(str);
856     qobject_unref(qnum);
857
858     qnum = qobject_to(QNum, qobject_from_json(lti64, &error_abort));
859     g_assert(qnum);
860     g_assert_cmpfloat(qnum_get_double(qnum), ==, -92233720368547758e2);
861     g_assert(!qnum_get_try_uint(qnum, &val));
862     g_assert(!qnum_get_try_int(qnum, &ival));
863
864     str = qobject_to_json(QOBJECT(qnum));
865     g_assert_cmpstr(qstring_get_str(str), ==, "-9223372036854775808");
866     qobject_unref(str);
867     qobject_unref(qnum);
868 }
869
870 static void float_number(void)
871 {
872     int i;
873     struct {
874         const char *encoded;
875         double decoded;
876         int skip;
877     } test_cases[] = {
878         { "32.43", 32.43 },
879         { "0.222", 0.222 },
880         { "-32.12313", -32.12313 },
881         { "-32.20e-10", -32.20e-10, .skip = 1 },
882         { },
883     };
884
885     for (i = 0; test_cases[i].encoded; i++) {
886         QObject *obj;
887         QNum *qnum;
888
889         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
890         qnum = qobject_to(QNum, obj);
891         g_assert(qnum);
892         g_assert(qnum_get_double(qnum) == test_cases[i].decoded);
893
894         if (test_cases[i].skip == 0) {
895             QString *str;
896
897             str = qobject_to_json(obj);
898             g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
899             qobject_unref(str);
900         }
901
902         qobject_unref(qnum);
903     }
904 }
905
906 static void keyword_literal(void)
907 {
908     QObject *obj;
909     QBool *qbool;
910     QNull *null;
911     QString *str;
912
913     obj = qobject_from_json("true", &error_abort);
914     qbool = qobject_to(QBool, obj);
915     g_assert(qbool);
916     g_assert(qbool_get_bool(qbool) == true);
917
918     str = qobject_to_json(obj);
919     g_assert(strcmp(qstring_get_str(str), "true") == 0);
920     qobject_unref(str);
921
922     qobject_unref(qbool);
923
924     obj = qobject_from_json("false", &error_abort);
925     qbool = qobject_to(QBool, obj);
926     g_assert(qbool);
927     g_assert(qbool_get_bool(qbool) == false);
928
929     str = qobject_to_json(obj);
930     g_assert(strcmp(qstring_get_str(str), "false") == 0);
931     qobject_unref(str);
932
933     qobject_unref(qbool);
934
935     obj = qobject_from_json("null", &error_abort);
936     g_assert(obj != NULL);
937     g_assert(qobject_type(obj) == QTYPE_QNULL);
938
939     null = qnull();
940     g_assert(QOBJECT(null) == obj);
941
942     qobject_unref(obj);
943     qobject_unref(null);
944 }
945
946 static void interpolation_valid(void)
947 {
948     long long value_lld = 0x123456789abcdefLL;
949     int64_t value_d64 = value_lld;
950     long value_ld = (long)value_lld;
951     int value_d = (int)value_lld;
952     unsigned long long value_llu = 0xfedcba9876543210ULL;
953     uint64_t value_u64 = value_llu;
954     unsigned long value_lu = (unsigned long)value_llu;
955     unsigned value_u = (unsigned)value_llu;
956     double value_f = 2.323423423;
957     const char *value_s = "hello world";
958     QObject *value_p = QOBJECT(qnull());
959     QBool *qbool;
960     QNum *qnum;
961     QString *qstr;
962     QObject *qobj;
963
964     /* bool */
965
966     qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", false));
967     g_assert(qbool);
968     g_assert(qbool_get_bool(qbool) == false);
969     qobject_unref(qbool);
970
971     /* Test that non-zero values other than 1 get collapsed to true */
972     qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", 2));
973     g_assert(qbool);
974     g_assert(qbool_get_bool(qbool) == true);
975     qobject_unref(qbool);
976
977     /* number */
978
979     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%d", value_d));
980     g_assert_cmpint(qnum_get_int(qnum), ==, value_d);
981     qobject_unref(qnum);
982
983     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%ld", value_ld));
984     g_assert_cmpint(qnum_get_int(qnum), ==, value_ld);
985     qobject_unref(qnum);
986
987     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lld", value_lld));
988     g_assert_cmpint(qnum_get_int(qnum), ==, value_lld);
989     qobject_unref(qnum);
990
991     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%" PRId64, value_d64));
992     g_assert_cmpint(qnum_get_int(qnum), ==, value_lld);
993     qobject_unref(qnum);
994
995     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%u", value_u));
996     g_assert_cmpuint(qnum_get_uint(qnum), ==, value_u);
997     qobject_unref(qnum);
998
999     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lu", value_lu));
1000     g_assert_cmpuint(qnum_get_uint(qnum), ==, value_lu);
1001     qobject_unref(qnum);
1002
1003     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%llu", value_llu));
1004     g_assert_cmpuint(qnum_get_uint(qnum), ==, value_llu);
1005     qobject_unref(qnum);
1006
1007     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%" PRIu64, value_u64));
1008     g_assert_cmpuint(qnum_get_uint(qnum), ==, value_llu);
1009     qobject_unref(qnum);
1010
1011     qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%f", value_f));
1012     g_assert(qnum_get_double(qnum) == value_f);
1013     qobject_unref(qnum);
1014
1015     /* string */
1016
1017     qstr = qobject_to(QString,
1018                      qobject_from_jsonf_nofail("%s", value_s));
1019     g_assert_cmpstr(qstring_get_try_str(qstr), ==, value_s);
1020     qobject_unref(qstr);
1021
1022     /* object */
1023
1024     qobj = qobject_from_jsonf_nofail("%p", value_p);
1025     g_assert(qobj == value_p);
1026 }
1027
1028 static void interpolation_unknown(void)
1029 {
1030     if (g_test_subprocess()) {
1031         qobject_from_jsonf_nofail("%x", 666);
1032     }
1033     g_test_trap_subprocess(NULL, 0, 0);
1034     g_test_trap_assert_failed();
1035     g_test_trap_assert_stderr("*Unexpected error*"
1036                               "invalid interpolation '%x'*");
1037 }
1038
1039 static void interpolation_string(void)
1040 {
1041     if (g_test_subprocess()) {
1042         qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
1043     }
1044     g_test_trap_subprocess(NULL, 0, 0);
1045     g_test_trap_assert_failed();
1046     g_test_trap_assert_stderr("*Unexpected error*"
1047                               "can't interpolate into string*");
1048 }
1049
1050 static void simple_dict(void)
1051 {
1052     int i;
1053     struct {
1054         const char *encoded;
1055         QLitObject decoded;
1056     } test_cases[] = {
1057         {
1058             .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
1059             .decoded = QLIT_QDICT(((QLitDictEntry[]){
1060                         { "foo", QLIT_QNUM(42) },
1061                         { "bar", QLIT_QSTR("hello world") },
1062                         { }
1063                     })),
1064         }, {
1065             .encoded = "{}",
1066             .decoded = QLIT_QDICT(((QLitDictEntry[]){
1067                         { }
1068                     })),
1069         }, {
1070             .encoded = "{\"foo\": 43}",
1071             .decoded = QLIT_QDICT(((QLitDictEntry[]){
1072                         { "foo", QLIT_QNUM(43) },
1073                         { }
1074                     })),
1075         },
1076         { }
1077     };
1078
1079     for (i = 0; test_cases[i].encoded; i++) {
1080         QObject *obj;
1081         QString *str;
1082
1083         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1084         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1085
1086         str = qobject_to_json(obj);
1087         qobject_unref(obj);
1088
1089         obj = qobject_from_json(qstring_get_str(str), &error_abort);
1090         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1091         qobject_unref(obj);
1092         qobject_unref(str);
1093     }
1094 }
1095
1096 /*
1097  * this generates json of the form:
1098  * a(0,m) = [0, 1, ..., m-1]
1099  * a(n,m) = {
1100  *            'key0': a(0,m),
1101  *            'key1': a(1,m),
1102  *            ...
1103  *            'key(n-1)': a(n-1,m)
1104  *          }
1105  */
1106 static void gen_test_json(GString *gstr, int nest_level_max,
1107                           int elem_count)
1108 {
1109     int i;
1110
1111     g_assert(gstr);
1112     if (nest_level_max == 0) {
1113         g_string_append(gstr, "[");
1114         for (i = 0; i < elem_count; i++) {
1115             g_string_append_printf(gstr, "%d", i);
1116             if (i < elem_count - 1) {
1117                 g_string_append_printf(gstr, ", ");
1118             }
1119         }
1120         g_string_append(gstr, "]");
1121         return;
1122     }
1123
1124     g_string_append(gstr, "{");
1125     for (i = 0; i < nest_level_max; i++) {
1126         g_string_append_printf(gstr, "'key%d': ", i);
1127         gen_test_json(gstr, i, elem_count);
1128         if (i < nest_level_max - 1) {
1129             g_string_append(gstr, ",");
1130         }
1131     }
1132     g_string_append(gstr, "}");
1133 }
1134
1135 static void large_dict(void)
1136 {
1137     GString *gstr = g_string_new("");
1138     QObject *obj;
1139
1140     gen_test_json(gstr, 10, 100);
1141     obj = qobject_from_json(gstr->str, &error_abort);
1142     g_assert(obj != NULL);
1143
1144     qobject_unref(obj);
1145     g_string_free(gstr, true);
1146 }
1147
1148 static void simple_list(void)
1149 {
1150     int i;
1151     struct {
1152         const char *encoded;
1153         QLitObject decoded;
1154     } test_cases[] = {
1155         {
1156             .encoded = "[43,42]",
1157             .decoded = QLIT_QLIST(((QLitObject[]){
1158                         QLIT_QNUM(43),
1159                         QLIT_QNUM(42),
1160                         { }
1161                     })),
1162         },
1163         {
1164             .encoded = "[43]",
1165             .decoded = QLIT_QLIST(((QLitObject[]){
1166                         QLIT_QNUM(43),
1167                         { }
1168                     })),
1169         },
1170         {
1171             .encoded = "[]",
1172             .decoded = QLIT_QLIST(((QLitObject[]){
1173                         { }
1174                     })),
1175         },
1176         {
1177             .encoded = "[{}]",
1178             .decoded = QLIT_QLIST(((QLitObject[]){
1179                         QLIT_QDICT(((QLitDictEntry[]){
1180                                     {},
1181                                         })),
1182                         {},
1183                             })),
1184         },
1185         { }
1186     };
1187
1188     for (i = 0; test_cases[i].encoded; i++) {
1189         QObject *obj;
1190         QString *str;
1191
1192         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1193         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1194
1195         str = qobject_to_json(obj);
1196         qobject_unref(obj);
1197
1198         obj = qobject_from_json(qstring_get_str(str), &error_abort);
1199         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1200         qobject_unref(obj);
1201         qobject_unref(str);
1202     }
1203 }
1204
1205 static void simple_whitespace(void)
1206 {
1207     int i;
1208     struct {
1209         const char *encoded;
1210         QLitObject decoded;
1211     } test_cases[] = {
1212         {
1213             .encoded = " [ 43 , 42 ]",
1214             .decoded = QLIT_QLIST(((QLitObject[]){
1215                         QLIT_QNUM(43),
1216                         QLIT_QNUM(42),
1217                         { }
1218                     })),
1219         },
1220         {
1221             .encoded = "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
1222             .decoded = QLIT_QLIST(((QLitObject[]){
1223                         QLIT_QNUM(43),
1224                         QLIT_QDICT(((QLitDictEntry[]){
1225                                     { "h", QLIT_QSTR("b") },
1226                                     { }})),
1227                         QLIT_QLIST(((QLitObject[]){
1228                                     { }})),
1229                         QLIT_QNUM(42),
1230                         { }
1231                     })),
1232         },
1233         {
1234             .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
1235             .decoded = QLIT_QLIST(((QLitObject[]){
1236                         QLIT_QNUM(43),
1237                         QLIT_QDICT(((QLitDictEntry[]){
1238                                     { "h", QLIT_QSTR("b") },
1239                                     { "a", QLIT_QNUM(32) },
1240                                     { }})),
1241                         QLIT_QLIST(((QLitObject[]){
1242                                     { }})),
1243                         QLIT_QNUM(42),
1244                         { }
1245                     })),
1246         },
1247         { }
1248     };
1249
1250     for (i = 0; test_cases[i].encoded; i++) {
1251         QObject *obj;
1252         QString *str;
1253
1254         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1255         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1256
1257         str = qobject_to_json(obj);
1258         qobject_unref(obj);
1259
1260         obj = qobject_from_json(qstring_get_str(str), &error_abort);
1261         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1262
1263         qobject_unref(obj);
1264         qobject_unref(str);
1265     }
1266 }
1267
1268 static void simple_interpolation(void)
1269 {
1270     QObject *embedded_obj;
1271     QObject *obj;
1272     QLitObject decoded = QLIT_QLIST(((QLitObject[]){
1273             QLIT_QNUM(1),
1274             QLIT_QSTR("100%"),
1275             QLIT_QLIST(((QLitObject[]){
1276                         QLIT_QNUM(32),
1277                         QLIT_QNUM(42),
1278                         {}})),
1279             {}}));
1280
1281     embedded_obj = qobject_from_json("[32, 42]", &error_abort);
1282     g_assert(embedded_obj != NULL);
1283
1284     obj = qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj);
1285     g_assert(qlit_equal_qobject(&decoded, obj));
1286
1287     qobject_unref(obj);
1288 }
1289
1290 static void empty_input(void)
1291 {
1292     Error *err = NULL;
1293     QObject *obj;
1294
1295     obj = qobject_from_json("", &err);
1296     error_free_or_abort(&err);
1297     g_assert(obj == NULL);
1298 }
1299
1300 static void blank_input(void)
1301 {
1302     Error *err = NULL;
1303     QObject *obj;
1304
1305     obj = qobject_from_json("\n ", &err);
1306     error_free_or_abort(&err);
1307     g_assert(obj == NULL);
1308 }
1309
1310 static void junk_input(void)
1311 {
1312     /* Note: junk within strings is covered elsewhere */
1313     Error *err = NULL;
1314     QObject *obj;
1315
1316     obj = qobject_from_json("@", &err);
1317     error_free_or_abort(&err);
1318     g_assert(obj == NULL);
1319
1320     obj = qobject_from_json("{\x01", &err);
1321     error_free_or_abort(&err);
1322     g_assert(obj == NULL);
1323
1324     obj = qobject_from_json("[0\xFF]", &err);
1325     error_free_or_abort(&err);
1326     g_assert(obj == NULL);
1327
1328     obj = qobject_from_json("00", &err);
1329     error_free_or_abort(&err);
1330     g_assert(obj == NULL);
1331
1332     obj = qobject_from_json("[1e", &err);
1333     error_free_or_abort(&err);
1334     g_assert(obj == NULL);
1335
1336     obj = qobject_from_json("truer", &err);
1337     error_free_or_abort(&err);
1338     g_assert(obj == NULL);
1339 }
1340
1341 static void unterminated_string(void)
1342 {
1343     Error *err = NULL;
1344     QObject *obj = qobject_from_json("\"abc", &err);
1345     error_free_or_abort(&err);
1346     g_assert(obj == NULL);
1347 }
1348
1349 static void unterminated_sq_string(void)
1350 {
1351     Error *err = NULL;
1352     QObject *obj = qobject_from_json("'abc", &err);
1353     error_free_or_abort(&err);
1354     g_assert(obj == NULL);
1355 }
1356
1357 static void unterminated_escape(void)
1358 {
1359     Error *err = NULL;
1360     QObject *obj = qobject_from_json("\"abc\\\"", &err);
1361     error_free_or_abort(&err);
1362     g_assert(obj == NULL);
1363 }
1364
1365 static void unterminated_array(void)
1366 {
1367     Error *err = NULL;
1368     QObject *obj = qobject_from_json("[32", &err);
1369     error_free_or_abort(&err);
1370     g_assert(obj == NULL);
1371 }
1372
1373 static void unterminated_array_comma(void)
1374 {
1375     Error *err = NULL;
1376     QObject *obj = qobject_from_json("[32,", &err);
1377     error_free_or_abort(&err);
1378     g_assert(obj == NULL);
1379 }
1380
1381 static void invalid_array_comma(void)
1382 {
1383     Error *err = NULL;
1384     QObject *obj = qobject_from_json("[32,}", &err);
1385     error_free_or_abort(&err);
1386     g_assert(obj == NULL);
1387 }
1388
1389 static void unterminated_dict(void)
1390 {
1391     Error *err = NULL;
1392     QObject *obj = qobject_from_json("{'abc':32", &err);
1393     error_free_or_abort(&err);
1394     g_assert(obj == NULL);
1395 }
1396
1397 static void unterminated_dict_comma(void)
1398 {
1399     Error *err = NULL;
1400     QObject *obj = qobject_from_json("{'abc':32,", &err);
1401     error_free_or_abort(&err);
1402     g_assert(obj == NULL);
1403 }
1404
1405 static void invalid_dict_comma(void)
1406 {
1407     Error *err = NULL;
1408     QObject *obj = qobject_from_json("{'abc':32,}", &err);
1409     error_free_or_abort(&err);
1410     g_assert(obj == NULL);
1411 }
1412
1413 static void unterminated_literal(void)
1414 {
1415     Error *err = NULL;
1416     QObject *obj = qobject_from_json("nul", &err);
1417     error_free_or_abort(&err);
1418     g_assert(obj == NULL);
1419 }
1420
1421 static char *make_nest(char *buf, size_t cnt)
1422 {
1423     memset(buf, '[', cnt - 1);
1424     buf[cnt - 1] = '{';
1425     buf[cnt] = '}';
1426     memset(buf + cnt + 1, ']', cnt - 1);
1427     buf[2 * cnt] = 0;
1428     return buf;
1429 }
1430
1431 static void limits_nesting(void)
1432 {
1433     Error *err = NULL;
1434     enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
1435     char buf[2 * (max_nesting + 1) + 1];
1436     QObject *obj;
1437
1438     obj = qobject_from_json(make_nest(buf, max_nesting), &error_abort);
1439     g_assert(obj != NULL);
1440     qobject_unref(obj);
1441
1442     obj = qobject_from_json(make_nest(buf, max_nesting + 1), &err);
1443     error_free_or_abort(&err);
1444     g_assert(obj == NULL);
1445 }
1446
1447 static void multiple_values(void)
1448 {
1449     Error *err = NULL;
1450     QObject *obj;
1451
1452     obj = qobject_from_json("false true", &err);
1453     error_free_or_abort(&err);
1454     g_assert(obj == NULL);
1455
1456     obj = qobject_from_json("} true", &err);
1457     error_free_or_abort(&err);
1458     g_assert(obj == NULL);
1459 }
1460
1461 int main(int argc, char **argv)
1462 {
1463     g_test_init(&argc, &argv, NULL);
1464
1465     g_test_add_func("/literals/string/escaped", escaped_string);
1466     g_test_add_func("/literals/string/quotes", string_with_quotes);
1467     g_test_add_func("/literals/string/utf8", utf8_string);
1468
1469     g_test_add_func("/literals/number/simple", simple_number);
1470     g_test_add_func("/literals/number/large", large_number);
1471     g_test_add_func("/literals/number/float", float_number);
1472
1473     g_test_add_func("/literals/keyword", keyword_literal);
1474
1475     g_test_add_func("/literals/interpolation/valid", interpolation_valid);
1476     g_test_add_func("/literals/interpolation/unkown", interpolation_unknown);
1477     g_test_add_func("/literals/interpolation/string", interpolation_string);
1478
1479     g_test_add_func("/dicts/simple_dict", simple_dict);
1480     g_test_add_func("/dicts/large_dict", large_dict);
1481     g_test_add_func("/lists/simple_list", simple_list);
1482
1483     g_test_add_func("/mixed/simple_whitespace", simple_whitespace);
1484     g_test_add_func("/mixed/interpolation", simple_interpolation);
1485
1486     g_test_add_func("/errors/empty", empty_input);
1487     g_test_add_func("/errors/blank", blank_input);
1488     g_test_add_func("/errors/junk", junk_input);
1489     g_test_add_func("/errors/unterminated/string", unterminated_string);
1490     g_test_add_func("/errors/unterminated/escape", unterminated_escape);
1491     g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string);
1492     g_test_add_func("/errors/unterminated/array", unterminated_array);
1493     g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma);
1494     g_test_add_func("/errors/unterminated/dict", unterminated_dict);
1495     g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma);
1496     g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
1497     g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
1498     g_test_add_func("/errors/unterminated/literal", unterminated_literal);
1499     g_test_add_func("/errors/limits/nesting", limits_nesting);
1500     g_test_add_func("/errors/multiple_values", multiple_values);
1501
1502     return g_test_run();
1503 }
This page took 0.111455 seconds and 4 git commands to generate.