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