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