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