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