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