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