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