Statistics
| Branch: | Revision:

root / tests / check-qjson.c @ f487b677

History | View | Annotate | Download (45 kB)

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