target/mips: Simplify decode_opc_mxu() ifdef'ry
[qemu/ar7.git] / tests / check-qjson.c
blobc845f91d43773083c78f00e3bab0587c89713c1d
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  */
14 #include "qemu/osdep.h"
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"
26 static QString *from_json_str(const char *jstr, bool single, Error **errp)
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));
32     g_free(qjstr);
33     return ret;
36 static char *to_json_str(QString *str)
38     GString *json = qobject_to_json(QOBJECT(str));
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);
49 static void escaped_string(void)
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;
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     }
108 static void string_with_quotes(void)
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;
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     }
130 static void utf8_string(void)
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;
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;
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             }
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);
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     }
792 static void int_number(void)
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;
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);
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);
833         qobject_unref(qnum);
834     }
837 static void uint_number(void)
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;
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);
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);
870         qobject_unref(qnum);
871     }
874 static void float_number(void)
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;
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));
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);
909         qobject_unref(qnum);
910     }
913 static void keyword_literal(void)
915     QObject *obj;
916     QBool *qbool;
917     QNull *null;
918     GString *str;
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);
925     str = qobject_to_json(obj);
926     g_assert_cmpstr(str->str, ==, "true");
927     g_string_free(str, true);
929     qobject_unref(qbool);
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);
936     str = qobject_to_json(obj);
937     g_assert_cmpstr(str->str, ==, "false");
938     g_string_free(str, true);
940     qobject_unref(qbool);
942     obj = qobject_from_json("null", &error_abort);
943     g_assert(obj != NULL);
944     g_assert(qobject_type(obj) == QTYPE_QNULL);
946     null = qnull();
947     g_assert(QOBJECT(null) == obj);
949     qobject_unref(obj);
950     qobject_unref(null);
953 static void interpolation_valid(void)
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;
971     /* bool */
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);
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);
984     /* number */
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);
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);
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);
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);
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);
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);
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);
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);
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);
1022     /* string */
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);
1028     /* object */
1030     qobj = qobject_from_jsonf_nofail("%p", value_p);
1031     g_assert(qobj == value_p);
1034 static void interpolation_unknown(void)
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'*");
1045 static void interpolation_string(void)
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*");
1056 static void simple_dict(void)
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     };
1085     for (i = 0; test_cases[i].encoded; i++) {
1086         QObject *obj;
1087         GString *str;
1089         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1090         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1092         str = qobject_to_json(obj);
1093         qobject_unref(obj);
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     }
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)
1115     int i;
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     }
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, "}");
1141 static void large_dict(void)
1143     GString *gstr = g_string_new("");
1144     QObject *obj;
1146     gen_test_json(gstr, 10, 100);
1147     obj = qobject_from_json(gstr->str, &error_abort);
1148     g_assert(obj != NULL);
1150     qobject_unref(obj);
1151     g_string_free(gstr, true);
1154 static void simple_list(void)
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     };
1194     for (i = 0; test_cases[i].encoded; i++) {
1195         QObject *obj;
1196         GString *str;
1198         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1199         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1201         str = qobject_to_json(obj);
1202         qobject_unref(obj);
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     }
1211 static void simple_whitespace(void)
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     };
1256     for (i = 0; test_cases[i].encoded; i++) {
1257         QObject *obj;
1258         GString *str;
1260         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
1261         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1263         str = qobject_to_json(obj);
1264         qobject_unref(obj);
1266         obj = qobject_from_json(str->str, &error_abort);
1267         g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
1269         qobject_unref(obj);
1270         g_string_free(str, true);
1271     }
1274 static void simple_interpolation(void)
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             {}}));
1287     embedded_obj = qobject_from_json("[32, 42]", &error_abort);
1288     g_assert(embedded_obj != NULL);
1290     obj = qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj);
1291     g_assert(qlit_equal_qobject(&decoded, obj));
1293     qobject_unref(obj);
1296 static void empty_input(void)
1298     Error *err = NULL;
1299     QObject *obj;
1301     obj = qobject_from_json("", &err);
1302     error_free_or_abort(&err);
1303     g_assert(obj == NULL);
1306 static void blank_input(void)
1308     Error *err = NULL;
1309     QObject *obj;
1311     obj = qobject_from_json("\n ", &err);
1312     error_free_or_abort(&err);
1313     g_assert(obj == NULL);
1316 static void junk_input(void)
1318     /* Note: junk within strings is covered elsewhere */
1319     Error *err = NULL;
1320     QObject *obj;
1322     obj = qobject_from_json("@", &err);
1323     error_free_or_abort(&err);
1324     g_assert(obj == NULL);
1326     obj = qobject_from_json("{\x01", &err);
1327     error_free_or_abort(&err);
1328     g_assert(obj == NULL);
1330     obj = qobject_from_json("[0\xFF]", &err);
1331     error_free_or_abort(&err);
1332     g_assert(obj == NULL);
1334     obj = qobject_from_json("00", &err);
1335     error_free_or_abort(&err);
1336     g_assert(obj == NULL);
1338     obj = qobject_from_json("[1e", &err);
1339     error_free_or_abort(&err);
1340     g_assert(obj == NULL);
1342     obj = qobject_from_json("truer", &err);
1343     error_free_or_abort(&err);
1344     g_assert(obj == NULL);
1347 static void unterminated_string(void)
1349     Error *err = NULL;
1350     QObject *obj = qobject_from_json("\"abc", &err);
1351     error_free_or_abort(&err);
1352     g_assert(obj == NULL);
1355 static void unterminated_sq_string(void)
1357     Error *err = NULL;
1358     QObject *obj = qobject_from_json("'abc", &err);
1359     error_free_or_abort(&err);
1360     g_assert(obj == NULL);
1363 static void unterminated_escape(void)
1365     Error *err = NULL;
1366     QObject *obj = qobject_from_json("\"abc\\\"", &err);
1367     error_free_or_abort(&err);
1368     g_assert(obj == NULL);
1371 static void unterminated_array(void)
1373     Error *err = NULL;
1374     QObject *obj = qobject_from_json("[32", &err);
1375     error_free_or_abort(&err);
1376     g_assert(obj == NULL);
1379 static void unterminated_array_comma(void)
1381     Error *err = NULL;
1382     QObject *obj = qobject_from_json("[32,", &err);
1383     error_free_or_abort(&err);
1384     g_assert(obj == NULL);
1387 static void invalid_array_comma(void)
1389     Error *err = NULL;
1390     QObject *obj = qobject_from_json("[32,}", &err);
1391     error_free_or_abort(&err);
1392     g_assert(obj == NULL);
1395 static void unterminated_dict(void)
1397     Error *err = NULL;
1398     QObject *obj = qobject_from_json("{'abc':32", &err);
1399     error_free_or_abort(&err);
1400     g_assert(obj == NULL);
1403 static void unterminated_dict_comma(void)
1405     Error *err = NULL;
1406     QObject *obj = qobject_from_json("{'abc':32,", &err);
1407     error_free_or_abort(&err);
1408     g_assert(obj == NULL);
1411 static void invalid_dict_comma(void)
1413     Error *err = NULL;
1414     QObject *obj = qobject_from_json("{'abc':32,}", &err);
1415     error_free_or_abort(&err);
1416     g_assert(obj == NULL);
1419 static void invalid_dict_key(void)
1421     Error *err = NULL;
1422     QObject *obj = qobject_from_json("{32:'abc'}", &err);
1423     error_free_or_abort(&err);
1424     g_assert(obj == NULL);
1427 static void unterminated_literal(void)
1429     Error *err = NULL;
1430     QObject *obj = qobject_from_json("nul", &err);
1431     error_free_or_abort(&err);
1432     g_assert(obj == NULL);
1435 static char *make_nest(char *buf, size_t cnt)
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;
1445 static void limits_nesting(void)
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;
1452     obj = qobject_from_json(make_nest(buf, max_nesting), &error_abort);
1453     g_assert(obj != NULL);
1454     qobject_unref(obj);
1456     obj = qobject_from_json(make_nest(buf, max_nesting + 1), &err);
1457     error_free_or_abort(&err);
1458     g_assert(obj == NULL);
1461 static void multiple_values(void)
1463     Error *err = NULL;
1464     QObject *obj;
1466     obj = qobject_from_json("false true", &err);
1467     error_free_or_abort(&err);
1468     g_assert(obj == NULL);
1470     obj = qobject_from_json("} true", &err);
1471     error_free_or_abort(&err);
1472     g_assert(obj == NULL);
1475 int main(int argc, char **argv)
1477     g_test_init(&argc, &argv, NULL);
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);
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);
1487     g_test_add_func("/literals/keyword", keyword_literal);
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);
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);
1497     g_test_add_func("/mixed/simple_whitespace", simple_whitespace);
1498     g_test_add_func("/mixed/interpolation", simple_interpolation);
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);
1517     return g_test_run();