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