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