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