1 /*-
2 * Copyright (c) 2017 Varnish Software AS
3 * All rights reserved.
4 *
5 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6 *
7 * SPDX-License-Identifier: BSD-2-Clause
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include "config.h"
32
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38
39 #include "vdef.h"
40
41 #include "vas.h"
42 #include "miniobj.h"
43 #include "vqueue.h"
44 #include "vjsn.h"
45
46 const char VJSN_OBJECT[] = "object";
47 const char VJSN_ARRAY[] = "array";
48 const char VJSN_NUMBER[] = "number";
49 const char VJSN_STRING[] = "string";
50 const char VJSN_TRUE[] = "true";
51 const char VJSN_FALSE[] = "false";
52 const char VJSN_NULL[] = "null";
53
54 #define VJSN_EXPECT(js, xxx, ret) \
55 do { \
56 AZ(js->err); \
57 if (*((js)->ptr) != xxx) { \
58 js->err = "Expected " #xxx " not found."; \
59 return (ret); \
60 } else { \
61 *js->ptr++ = '\0'; \
62 } \
63 } while (0)
64
65 static struct vjsn_val *vjsn_value(struct vjsn *);
66
67 static struct vjsn_val *
vjsn_val_new(const char * type)68 vjsn_val_new(const char *type)
69 {
70 struct vjsn_val *jsv;
71
72 ALLOC_OBJ(jsv, VJSN_VAL_MAGIC);
73 AN(jsv);
74 VTAILQ_INIT(&jsv->children);
75 jsv->type = type;
76 return (jsv);
77 }
78
79 static void
vjsn_val_delete(struct vjsn_val * jsv)80 vjsn_val_delete(struct vjsn_val *jsv)
81 {
82 struct vjsn_val *jsve;
83
84 CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
85 do {
86 jsve = VTAILQ_FIRST(&jsv->children);
87 if (jsve != NULL) {
88 VTAILQ_REMOVE(&jsv->children, jsve, list);
89 vjsn_val_delete(jsve);
90 }
91 } while (jsve != NULL);
92 FREE_OBJ(jsv);
93 }
94
95 void
vjsn_delete(struct vjsn ** jp)96 vjsn_delete(struct vjsn **jp)
97 {
98 struct vjsn *js;
99
100 TAKE_OBJ_NOTNULL(js, jp, VJSN_MAGIC);
101 if (js->value != NULL)
102 vjsn_val_delete(js->value);
103 free(js->raw);
104 FREE_OBJ(js);
105 }
106
107 static void
vjsn_skip_ws(struct vjsn * js)108 vjsn_skip_ws(struct vjsn *js)
109 {
110 char c;
111
112 while (1) {
113 c = js->ptr[0];
114 if (c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20) {
115 *js->ptr++ = '\0';
116 continue;
117 }
118 #ifdef VJSN_COMMENTS
119 if (c == '/' && js->ptr[1] == '*') {
120 js->ptr += 2;
121 while (js->ptr[0] != '*' || js->ptr[1] != '/')
122 js->ptr++;
123 js->ptr += 2;
124 continue;
125 }
126 #endif
127 return;
128 }
129 }
130
131 static unsigned
vjsn_unumber(struct vjsn * js)132 vjsn_unumber(struct vjsn *js)
133 {
134 unsigned u = 0;
135 char c;
136 int i;
137
138 VJSN_EXPECT(js, '\\', 0);
139 VJSN_EXPECT(js, 'u', 0);
140 for (i = 0; i < 4; i++) {
141 u <<= 4;
142 c = *js->ptr;
143 if (c >= '0' && c <= '9')
144 u |= c - '0'; /*lint !e737 */
145 else if (c >= 'A' && c <= 'F')
146 u |= c - '7'; /*lint !e737 */
147 else if (c >= 'a' && c <= 'f')
148 u |= c - 'W'; /*lint !e737 */
149 else {
150 js->err = "Illegal \\uXXXX sequence";
151 return (0);
152 }
153 js->ptr++;
154 }
155 return (u);
156 }
157
158 static void
vjsn_unicode(struct vjsn * js,char ** d)159 vjsn_unicode(struct vjsn *js, char **d)
160 {
161 unsigned u1, u2;
162
163 u1 = vjsn_unumber(js);
164 if (js->err)
165 return;
166
167 if (u1 >= 0xdc00 && u1 <= 0xdfff) {
168 js->err = "Lone second UTF-16 Surrogate";
169 return;
170 }
171 if (u1 >= 0xd800 && u1 <= 0xdc00) {
172 u2 = vjsn_unumber(js);
173 if (u2 < 0xdc00 || u2 > 0xdfff) {
174 js->err = "Bad UTF-16 Surrogate pair";
175 return;
176 }
177 u1 -= 0xd800;
178 u2 -= 0xdc00;
179 u1 <<= 10;
180 u1 |= u2;
181 u1 |= 0x10000;
182 }
183 assert(u1 < 0x110000);
184 /*lint -save -e734 -e713 */
185 if (u1 < 0x80)
186 *(*d)++ = u1;
187 else if (u1 < 0x800) {
188 *(*d)++ = 0xc0 + u1 / 64;
189 *(*d)++ = 0x80 + u1 % 64;
190 } else if (u1 < 0x10000) {
191 *(*d)++ = 0xe0 + u1 / 4096;
192 *(*d)++ = 0x80 + u1 / 64 % 64;
193 *(*d)++ = 0x80 + u1 % 64;
194 } else {
195 *(*d)++ = 0xf0 + u1 / 262144;
196 *(*d)++ = 0x80 + u1 / 4096 % 64;
197 *(*d)++ = 0x80 + u1 / 64 % 64;
198 *(*d)++ = 0x80 + u1 % 64;
199 }
200 /*lint -restore */
201 }
202
203 static char *
vjsn_string(struct vjsn * js,char ** e)204 vjsn_string(struct vjsn *js, char **e)
205 {
206 char *p, *b;
207
208 AN(e);
209 vjsn_skip_ws(js);
210 VJSN_EXPECT(js, '"', NULL);
211 b = p = js->ptr;
212 while (*js->ptr != '"') {
213 if (*js->ptr == '\0') {
214 js->err = "Unterminated string";
215 return (NULL);
216 }
217 if ((unsigned char)(*js->ptr) <= 0x1f) {
218 js->err = "Unescaped control char in string";
219 return (NULL);
220 }
221 if (*js->ptr != '\\') {
222 *p++ = *js->ptr++;
223 continue;
224 }
225 switch (js->ptr[1]) {
226 case '\\':
227 case '/':
228 case '"': *p++ = js->ptr[1]; js->ptr += 2; break;
229 case 'b': *p++ = 0x08; js->ptr += 2; break;
230 case 'f': *p++ = 0x0c; js->ptr += 2; break;
231 case 't': *p++ = 0x09; js->ptr += 2; break;
232 case 'n': *p++ = 0x0a; js->ptr += 2; break;
233 case 'r': *p++ = 0x0d; js->ptr += 2; break;
234 case 'u':
235 vjsn_unicode(js, &p);
236 if (js->err != NULL)
237 return (NULL);
238 break;
239 default:
240 js->err = "Bad string escape";
241 return (NULL);
242 }
243 }
244 VJSN_EXPECT(js, '"', NULL);
245 *p = '\0';
246 *e = p;
247 return (b);
248 }
249
250 static struct vjsn_val *
vjsn_object(struct vjsn * js)251 vjsn_object(struct vjsn *js)
252 {
253 struct vjsn_val *jsv, *jsve;
254 char *s, *e;
255
256 VJSN_EXPECT(js, '{', NULL);
257
258 jsv = vjsn_val_new(VJSN_OBJECT);
259 AN(jsv);
260
261 vjsn_skip_ws(js);
262 if (*js->ptr != '}') {
263 while (1) {
264 s = vjsn_string(js, &e);
265 if (js->err != NULL)
266 return (jsv);
267 vjsn_skip_ws(js);
268 VJSN_EXPECT(js, ':', jsv);
269 jsve = vjsn_value(js);
270 if (js->err != NULL) {
271 if (jsve != NULL)
272 vjsn_val_delete(jsve);
273 return (jsv);
274 }
275 CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
276 jsve->name = s;
277 jsve->name_e = e;
278 VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
279 vjsn_skip_ws(js);
280 if (*js->ptr == '}')
281 break;
282 VJSN_EXPECT(js, ',', jsv);
283 }
284 }
285 VJSN_EXPECT(js, '}', jsv);
286 return (jsv);
287 }
288
289 static struct vjsn_val *
vjsn_array(struct vjsn * js)290 vjsn_array(struct vjsn *js)
291 {
292 struct vjsn_val *jsv, *jsve;
293
294 VJSN_EXPECT(js, '[', NULL);
295
296 jsv = vjsn_val_new(VJSN_ARRAY);
297 AN(jsv);
298
299 vjsn_skip_ws(js);
300 if (*js->ptr != ']') {
301 while (1) {
302 jsve = vjsn_value(js);
303 if (js->err != NULL) {
304 if (jsve != NULL)
305 vjsn_val_delete(jsve);
306 return (jsv);
307 }
308 CHECK_OBJ_NOTNULL(jsve, VJSN_VAL_MAGIC);
309 VTAILQ_INSERT_TAIL(&jsv->children, jsve, list);
310 vjsn_skip_ws(js);
311 if (*js->ptr == ']')
312 break;
313 VJSN_EXPECT(js, ',', jsv);
314 }
315 }
316 VJSN_EXPECT(js, ']', jsv);
317 return (jsv);
318 }
319
320 static struct vjsn_val *
vjsn_number(struct vjsn * js)321 vjsn_number(struct vjsn *js)
322 {
323 struct vjsn_val *jsv;
324
325 jsv = vjsn_val_new(VJSN_NUMBER);
326 AN(jsv);
327
328 jsv->value = js->ptr;
329
330 if (*js->ptr == '-')
331 js->ptr++;
332 if (*js->ptr < '0' || *js->ptr > '9') {
333 js->err = "Bad number";
334 return (jsv);
335 }
336 if (*js->ptr == '0' && js->ptr[1] >= '0' && js->ptr[1] <= '9') {
337 js->err = "Bad number";
338 return (jsv);
339 }
340 while (*js->ptr >= '0' && *js->ptr <= '9')
341 js->ptr++;
342 if (*js->ptr == '.') {
343 js->ptr++;
344 if (*js->ptr < '0' || *js->ptr > '9') {
345 js->err = "Bad number";
346 return (jsv);
347 }
348 while (*js->ptr >= '0' && *js->ptr <= '9')
349 js->ptr++;
350 }
351 if (*js->ptr == 'e' || *js->ptr == 'E') {
352 js->ptr++;
353 if (*js->ptr == '-' || *js->ptr == '+')
354 js->ptr++;
355 if (*js->ptr < '0' || *js->ptr > '9') {
356 js->err = "Bad number";
357 return (jsv);
358 }
359 while (*js->ptr >= '0' && *js->ptr <= '9')
360 js->ptr++;
361 }
362 return (jsv);
363 }
364
365 static struct vjsn_val *
vjsn_value(struct vjsn * js)366 vjsn_value(struct vjsn *js)
367 {
368 struct vjsn_val *jsv;
369
370 AZ(js->err);
371 vjsn_skip_ws(js);
372 if (*js->ptr == '{')
373 return (vjsn_object(js));
374 if (*js->ptr== '[')
375 return (vjsn_array(js));
376 if (*js->ptr== '"') {
377 jsv = vjsn_val_new(VJSN_STRING);
378 jsv->value = vjsn_string(js, &jsv->value_e);
379 if (js->err != NULL)
380 return (jsv);
381 AN(jsv->value);
382 return (jsv);
383 }
384 if (!strncmp(js->ptr, "true", 4)) {
385 js->ptr += 4;
386 return (vjsn_val_new(VJSN_TRUE));
387 }
388 if (!strncmp(js->ptr, "false", 5)) {
389 js->ptr += 5;
390 return (vjsn_val_new(VJSN_FALSE));
391 }
392 if (!strncmp(js->ptr, "null", 4)) {
393 js->ptr += 4;
394 return (vjsn_val_new(VJSN_NULL));
395 }
396 if (*js->ptr == '-' || (*js->ptr >= '0' && *js->ptr <= '9'))
397 return (vjsn_number(js));
398 js->err = "Unrecognized value";
399 return (NULL);
400 }
401
402 struct vjsn *
vjsn_parse_end(const char * from,const char * to,const char ** err)403 vjsn_parse_end(const char *from, const char *to, const char **err)
404 {
405 struct vjsn *js;
406 char *p, *e;
407 size_t sz;
408
409 AN(from);
410
411 AN(err);
412 *err = NULL;
413
414 if (to == NULL)
415 to = strchr(from, '\0');
416 AN(to);
417
418 sz = to - from;
419
420 p = malloc(sz + 1L);
421 AN(p);
422 memcpy(p, from, sz);
423 p[sz] = '\0';
424 e = p + sz;
425
426 ALLOC_OBJ(js, VJSN_MAGIC);
427 AN(js);
428 js->raw = p;
429 js->ptr = p;
430
431 js->value = vjsn_value(js);
432 if (js->err != NULL) {
433 *err = js->err;
434 vjsn_delete(&js);
435 return (NULL);
436 }
437
438 vjsn_skip_ws(js);
439 if (js->ptr != e) {
440 *err = "Garbage after value";
441 vjsn_delete(&js);
442 return (NULL);
443 }
444 return (js);
445 }
446
447 struct vjsn *
vjsn_parse(const char * src,const char ** err)448 vjsn_parse(const char *src, const char **err)
449 {
450
451 return (vjsn_parse_end(src, NULL, err));
452 }
453
454 struct vjsn_val *
vjsn_child(const struct vjsn_val * vv,const char * key)455 vjsn_child(const struct vjsn_val *vv, const char *key)
456 {
457 struct vjsn_val *vc;
458
459 CHECK_OBJ_NOTNULL(vv, VJSN_VAL_MAGIC);
460 AN(key);
461 VTAILQ_FOREACH(vc, &vv->children, list) {
462 if (vc->name != NULL && !strcmp(vc->name, key))
463 return (vc);
464 }
465 return (NULL);
466 }
467
468 static void
vjsn_dump_i(const struct vjsn_val * jsv,FILE * fo,int indent)469 vjsn_dump_i(const struct vjsn_val *jsv, FILE *fo, int indent)
470 {
471 struct vjsn_val *jsve;
472
473 CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
474 printf("%*s", indent, "");
475 if (jsv->name != NULL)
476 printf("[\"%s\"]: ", jsv->name);
477 printf("{%s}", jsv->type);
478 if (jsv->value != NULL) {
479 if (strlen(jsv->value) < 20)
480 printf(" <%s", jsv->value);
481 else
482 printf(" <%.10s[...#%zu]",
483 jsv->value, strlen(jsv->value + 10));
484 printf(">");
485 }
486 printf("\n");
487 VTAILQ_FOREACH(jsve, &jsv->children, list)
488 vjsn_dump_i(jsve, fo, indent + 2);
489 }
490
491 void
vjsn_dump_val(const struct vjsn_val * jsv,FILE * fo)492 vjsn_dump_val(const struct vjsn_val *jsv, FILE *fo)
493 {
494 CHECK_OBJ_NOTNULL(jsv, VJSN_VAL_MAGIC);
495 vjsn_dump_i(jsv, fo, 0);
496 }
497
498 void
vjsn_dump(const struct vjsn * js,FILE * fo)499 vjsn_dump(const struct vjsn *js, FILE *fo)
500 {
501
502 CHECK_OBJ_NOTNULL(js, VJSN_MAGIC);
503 AN(fo);
504 vjsn_dump_i(js->value, fo, 0);
505 }
506
507 #ifdef VJSN_TEST
508
509 /*
510 * Test-cases by Nicolas Seriot
511 *
512 * See: http://seriot.ch/parsing_json.php
513 *
514 * MIT License
515 *
516 * Copyright (c) 2016 Nicolas Seriot
517 *
518 * Permission is hereby granted, free of charge, to any person obtaining a copy
519 * of this software and associated documentation files (the "Software"), to deal
520 * in the Software without restriction, including without limitation the rights
521 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
522 * copies of the Software, and to permit persons to whom the Software is
523 * furnished to do so, subject to the following conditions:
524 *
525 * The above copyright notice and this permission notice shall be included in
526 * all copies or substantial portions of the Software.
527 *
528 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
529 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
530 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
531 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
532 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
533 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
534 * SOFTWARE.
535 *
536 * We skip tests containing NUL, because we're lazy (The code will actually
537 * pass these tests if you provide for a way to pass the true length of the
538 * input to it, and we skip really huge tests, because we are only limited
539 * by available memory.
540 *
541 * To produce the C-data-structures:
542 *
543 * Clone https://github.com/nst/JSONTestSuite.git
544 *
545 * And run this python in test_parsing:
546
547 import glob
548
549 skip = {}
550
551 def emit(fin):
552 if fin in skip:
553 return
554 x = bytearray(open(fin).read())
555 if 0 in x:
556 return
557 if len(x) > 1000:
558 return
559 t = '\t"'
560 for i in x:
561 t += "\\x%02x" % i
562 if len(t) > 64:
563 print(t + '"')
564 t = '\t"'
565 print(t + '",')
566
567 print("const char *good[] = {")
568 l = list(glob.glob("y_*"))
569 l.sort()
570 for f in l:
571 emit(f)
572 print("\tNULL")
573 print("};")
574
575 print("const char *bad[] = {")
576 l = list(glob.glob("n_*"))
577 l.sort()
578 for f in l:
579 emit(f)
580 print("\tNULL")
581 print("};")
582 */
583
584 static const char *good[] = {
585 "\x5b\x5b\x5d\x20\x20\x20\x5d",
586 "\x5b\x22\x22\x5d",
587 "\x5b\x5d",
588 "\x5b\x22\x61\x22\x5d",
589 "\x5b\x66\x61\x6c\x73\x65\x5d",
590 "\x5b\x6e\x75\x6c\x6c\x2c\x20\x31\x2c\x20\x22\x31\x22\x2c\x20\x7b"
591 "\x7d\x5d",
592 "\x5b\x6e\x75\x6c\x6c\x5d",
593 "\x5b\x31\x0a\x5d",
594 "\x20\x5b\x31\x5d",
595 "\x5b\x31\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c"
596 "\x6c\x2c\x32\x5d",
597 "\x5b\x32\x5d\x20",
598 "\x5b\x31\x32\x33\x65\x36\x35\x5d",
599 "\x5b\x30\x65\x2b\x31\x5d",
600 "\x5b\x30\x65\x31\x5d",
601 "\x5b\x20\x34\x5d",
602 "\x5b\x2d\x30\x2e\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
603 "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
604 "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
605 "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
606 "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30"
607 "\x30\x31\x5d\x0a",
608 "\x5b\x32\x30\x65\x31\x5d",
609 "\x5b\x2d\x30\x5d",
610 "\x5b\x2d\x31\x32\x33\x5d",
611 "\x5b\x2d\x31\x5d",
612 "\x5b\x2d\x30\x5d",
613 "\x5b\x31\x45\x32\x32\x5d",
614 "\x5b\x31\x45\x2d\x32\x5d",
615 "\x5b\x31\x45\x2b\x32\x5d",
616 "\x5b\x31\x32\x33\x65\x34\x35\x5d",
617 "\x5b\x31\x32\x33\x2e\x34\x35\x36\x65\x37\x38\x5d",
618 "\x5b\x31\x65\x2d\x32\x5d",
619 "\x5b\x31\x65\x2b\x32\x5d",
620 "\x5b\x31\x32\x33\x5d",
621 "\x5b\x31\x32\x33\x2e\x34\x35\x36\x37\x38\x39\x5d",
622 "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x2c\x20\x22\x64"
623 "\x66\x67\x22\x3a\x22\x66\x67\x68\x22\x7d",
624 "\x7b\x22\x61\x73\x64\x22\x3a\x22\x73\x64\x66\x22\x7d",
625 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x63\x22"
626 "\x7d",
627 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x22\x61\x22\x3a\x22\x62\x22"
628 "\x7d",
629 "\x7b\x7d",
630 "\x7b\x22\x22\x3a\x30\x7d",
631 "\x7b\x22\x66\x6f\x6f\x5c\x75\x30\x30\x30\x30\x62\x61\x72\x22\x3a"
632 "\x20\x34\x32\x7d",
633 "\x7b\x20\x22\x6d\x69\x6e\x22\x3a\x20\x2d\x31\x2e\x30\x65\x2b\x32"
634 "\x38\x2c\x20\x22\x6d\x61\x78\x22\x3a\x20\x31\x2e\x30\x65\x2b\x32"
635 "\x38\x20\x7d",
636 "\x7b\x22\x78\x22\x3a\x5b\x7b\x22\x69\x64\x22\x3a\x20\x22\x78\x78"
637 "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
638 "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
639 "\x78\x78\x78\x78\x78\x78\x22\x7d\x5d\x2c\x20\x22\x69\x64\x22\x3a"
640 "\x20\x22\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
641 "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78"
642 "\x78\x78\x78\x78\x78\x78\x78\x78\x78\x78\x22\x7d",
643 "\x7b\x22\x61\x22\x3a\x5b\x5d\x7d",
644 "\x7b\x22\x74\x69\x74\x6c\x65\x22\x3a\x22\x5c\x75\x30\x34\x31\x66"
645 "\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x33\x62\x5c\x75\x30\x34"
646 "\x34\x32\x5c\x75\x30\x34\x33\x65\x5c\x75\x30\x34\x34\x30\x5c\x75"
647 "\x30\x34\x33\x30\x20\x5c\x75\x30\x34\x31\x37\x5c\x75\x30\x34\x33"
648 "\x35\x5c\x75\x30\x34\x33\x63\x5c\x75\x30\x34\x33\x62\x5c\x75\x30"
649 "\x34\x33\x35\x5c\x75\x30\x34\x33\x61\x5c\x75\x30\x34\x33\x65\x5c"
650 "\x75\x30\x34\x33\x66\x5c\x75\x30\x34\x33\x30\x22\x20\x7d",
651 "\x7b\x0a\x22\x61\x22\x3a\x20\x22\x62\x22\x0a\x7d",
652 "\x5b\x22\x5c\x75\x30\x30\x36\x30\x5c\x75\x30\x31\x32\x61\x5c\x75"
653 "\x31\x32\x41\x42\x22\x5d",
654 "\x5b\x22\x5c\x75\x44\x38\x30\x31\x5c\x75\x64\x63\x33\x37\x22\x5d"
655 "",
656 "\x5b\x22\x5c\x75\x64\x38\x33\x64\x5c\x75\x64\x65\x33\x39\x5c\x75"
657 "\x64\x38\x33\x64\x5c\x75\x64\x63\x38\x64\x22\x5d",
658 "\x5b\x22\x5c\x22\x5c\x5c\x5c\x2f\x5c\x62\x5c\x66\x5c\x6e\x5c\x72"
659 "\x5c\x74\x22\x5d",
660 "\x5b\x22\x5c\x5c\x75\x30\x30\x30\x30\x22\x5d",
661 "\x5b\x22\x5c\x22\x22\x5d",
662 "\x5b\x22\x61\x2f\x2a\x62\x2a\x2f\x63\x2f\x2a\x64\x2f\x2f\x65\x22"
663 "\x5d",
664 "\x5b\x22\x5c\x5c\x61\x22\x5d",
665 "\x5b\x22\x5c\x5c\x6e\x22\x5d",
666 "\x5b\x22\x5c\x75\x30\x30\x31\x32\x22\x5d",
667 "\x5b\x22\x5c\x75\x46\x46\x46\x46\x22\x5d",
668 "\x5b\x22\x61\x73\x64\x22\x5d",
669 "\x5b\x20\x22\x61\x73\x64\x22\x5d",
670 "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x46\x22\x5d"
671 "",
672 "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x41\x30\x6c\x69\x6e\x65\x22"
673 "\x5d",
674 "\x5b\x22\xf4\x8f\xbf\xbf\x22\x5d",
675 "\x5b\x22\xef\xbf\xbf\x22\x5d",
676 "\x5b\x22\x5c\x75\x30\x30\x30\x30\x22\x5d",
677 "\x5b\x22\x5c\x75\x30\x30\x32\x63\x22\x5d",
678 "\x5b\x22\xcf\x80\x22\x5d",
679 "\x5b\x22\xf0\x9b\xbf\xbf\x22\x5d",
680 "\x5b\x22\x61\x73\x64\x20\x22\x5d",
681 "\x22\x20\x22",
682 "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x31\x65\x22\x5d"
683 "",
684 "\x5b\x22\x5c\x75\x30\x38\x32\x31\x22\x5d",
685 "\x5b\x22\x5c\x75\x30\x31\x32\x33\x22\x5d",
686 "\x5b\x22\xe2\x80\xa8\x22\x5d",
687 "\x5b\x22\xe2\x80\xa9\x22\x5d",
688 "\x5b\x22\x5c\x75\x30\x30\x36\x31\x5c\x75\x33\x30\x61\x66\x5c\x75"
689 "\x33\x30\x45\x41\x5c\x75\x33\x30\x62\x39\x22\x5d",
690 "\x5b\x22\x6e\x65\x77\x5c\x75\x30\x30\x30\x41\x6c\x69\x6e\x65\x22"
691 "\x5d",
692 "\x5b\x22\x7f\x22\x5d",
693 "\x5b\x22\x5c\x75\x41\x36\x36\x44\x22\x5d",
694 "\x5b\x22\x5c\x75\x30\x30\x35\x43\x22\x5d",
695 "\x5b\x22\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82\x22\x5d",
696 "\x5b\x22\x5c\x75\x44\x42\x46\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
697 "",
698 "\x5b\x22\x5c\x75\x44\x38\x33\x46\x5c\x75\x44\x46\x46\x45\x22\x5d"
699 "",
700 "\x5b\x22\x5c\x75\x32\x30\x30\x42\x22\x5d",
701 "\x5b\x22\x5c\x75\x32\x30\x36\x34\x22\x5d",
702 "\x5b\x22\x5c\x75\x46\x44\x44\x30\x22\x5d",
703 "\x5b\x22\x5c\x75\x46\x46\x46\x45\x22\x5d",
704 "\x5b\x22\x5c\x75\x30\x30\x32\x32\x22\x5d",
705 "\x5b\x22\xe2\x82\xac\xf0\x9d\x84\x9e\x22\x5d",
706 "\x5b\x22\x61\x7f\x61\x22\x5d",
707 "\x66\x61\x6c\x73\x65",
708 "\x34\x32",
709 "\x2d\x30\x2e\x31",
710 "\x6e\x75\x6c\x6c",
711 "\x22\x61\x73\x64\x22",
712 "\x74\x72\x75\x65",
713 "\x22\x22",
714 "\x5b\x22\x61\x22\x5d\x0a",
715 "\x5b\x74\x72\x75\x65\x5d",
716 "\x20\x5b\x5d\x20",
717 NULL
718 };
719 static const char *bad[] = {
720 "\x5b\x31\x20\x74\x72\x75\x65\x5d",
721 "\x5b\x61\xe5\x5d",
722 "\x5b\x22\x22\x3a\x20\x31\x5d",
723 "\x5b\x22\x22\x5d\x2c",
724 "\x5b\x2c\x31\x5d",
725 "\x5b\x31\x2c\x2c\x32\x5d",
726 "\x5b\x22\x78\x22\x2c\x2c\x5d",
727 "\x5b\x22\x78\x22\x5d\x5d",
728 "\x5b\x22\x22\x2c\x5d",
729 "\x5b\x22\x78\x22",
730 "\x5b\x78",
731 "\x5b\x33\x5b\x34\x5d\x5d",
732 "\x5b\xff\x5d",
733 "\x5b\x31\x3a\x32\x5d",
734 "\x5b\x2c\x5d",
735 "\x5b\x2d\x5d",
736 "\x5b\x20\x20\x20\x2c\x20\x22\x22\x5d",
737 "\x5b\x22\x61\x22\x2c\x0a\x34\x0a\x2c\x31\x2c",
738 "\x5b\x31\x2c\x5d",
739 "\x5b\x31\x2c\x2c\x5d",
740 "\x5b\x22\x0b\x61\x22\x5c\x66\x5d",
741 "\x5b\x2a\x5d",
742 "\x5b\x22\x22",
743 "\x5b\x31\x2c",
744 "\x5b\x31\x2c\x0a\x31\x0a\x2c\x31",
745 "\x5b\x7b\x7d",
746 "\x5b\x66\x61\x6c\x73\x5d",
747 "\x5b\x6e\x75\x6c\x5d",
748 "\x5b\x74\x72\x75\x5d",
749 "\x5b\x2b\x2b\x31\x32\x33\x34\x5d",
750 "\x5b\x2b\x31\x5d",
751 "\x5b\x2b\x49\x6e\x66\x5d",
752 "\x5b\x2d\x30\x31\x5d",
753 "\x5b\x2d\x31\x2e\x30\x2e\x5d",
754 "\x5b\x2d\x32\x2e\x5d",
755 "\x5b\x2d\x4e\x61\x4e\x5d",
756 "\x5b\x2e\x2d\x31\x5d",
757 "\x5b\x2e\x32\x65\x2d\x33\x5d",
758 "\x5b\x30\x2e\x31\x2e\x32\x5d",
759 "\x5b\x30\x2e\x33\x65\x2b\x5d",
760 "\x5b\x30\x2e\x33\x65\x5d",
761 "\x5b\x30\x2e\x65\x31\x5d",
762 "\x5b\x30\x45\x2b\x5d",
763 "\x5b\x30\x45\x5d",
764 "\x5b\x30\x65\x2b\x5d",
765 "\x5b\x30\x65\x5d",
766 "\x5b\x31\x2e\x30\x65\x2b\x5d",
767 "\x5b\x31\x2e\x30\x65\x2d\x5d",
768 "\x5b\x31\x2e\x30\x65\x5d",
769 "\x5b\x31\x20\x30\x30\x30\x2e\x30\x5d",
770 "\x5b\x31\x65\x45\x32\x5d",
771 "\x5b\x32\x2e\x65\x2b\x33\x5d",
772 "\x5b\x32\x2e\x65\x2d\x33\x5d",
773 "\x5b\x32\x2e\x65\x33\x5d",
774 "\x5b\x39\x2e\x65\x2b\x5d",
775 "\x5b\x49\x6e\x66\x5d",
776 "\x5b\x4e\x61\x4e\x5d",
777 "\x5b\xef\xbc\x91\x5d",
778 "\x5b\x31\x2b\x32\x5d",
779 "\x5b\x30\x78\x31\x5d",
780 "\x5b\x30\x78\x34\x32\x5d",
781 "\x5b\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
782 "\x5b\x30\x65\x2b\x2d\x31\x5d",
783 "\x5b\x2d\x31\x32\x33\x2e\x31\x32\x33\x66\x6f\x6f\x5d",
784 "\x5b\x31\x32\x33\xe5\x5d",
785 "\x5b\x31\x65\x31\xe5\x5d",
786 "\x5b\x30\xe5\x5d\x0a",
787 "\x5b\x2d\x49\x6e\x66\x69\x6e\x69\x74\x79\x5d",
788 "\x5b\x2d\x66\x6f\x6f\x5d",
789 "\x5b\x2d\x20\x31\x5d",
790 "\x5b\x2d\x30\x31\x32\x5d",
791 "\x5b\x2d\x2e\x31\x32\x33\x5d",
792 "\x5b\x2d\x31\x78\x5d",
793 "\x5b\x31\x65\x61\x5d",
794 "\x5b\x31\x65\xe5\x5d",
795 "\x5b\x31\x2e\x5d",
796 "\x5b\x2e\x31\x32\x33\x5d",
797 "\x5b\x31\x2e\x32\x61\x2d\x33\x5d",
798 "\x5b\x31\x2e\x38\x30\x31\x31\x36\x37\x30\x30\x33\x33\x33\x37\x36"
799 "\x35\x31\x34\x48\x2d\x33\x30\x38\x5d",
800 "\x5b\x30\x31\x32\x5d",
801 "\x5b\x22\x78\x22\x2c\x20\x74\x72\x75\x74\x68\x5d",
802 "\x7b\x5b\x3a\x20\x22\x78\x22\x7d\x0a",
803 "\x7b\x22\x78\x22\x2c\x20\x6e\x75\x6c\x6c\x7d",
804 "\x7b\x22\x78\x22\x3a\x3a\x22\x62\x22\x7d",
805 "\x7b\xf0\x9f\x87\xa8\xf0\x9f\x87\xad\x7d",
806 "\x7b\x22\x61\x22\x3a\x22\x61\x22\x20\x31\x32\x33\x7d",
807 "\x7b\x6b\x65\x79\x3a\x20\x27\x76\x61\x6c\x75\x65\x27\x7d",
808 "\x7b\x22\xb9\x22\x3a\x22\x30\x22\x2c\x7d",
809 "\x7b\x22\x61\x22\x20\x62\x7d",
810 "\x7b\x3a\x22\x62\x22\x7d",
811 "\x7b\x22\x61\x22\x20\x22\x62\x22\x7d",
812 "\x7b\x22\x61\x22\x3a",
813 "\x7b\x22\x61\x22",
814 "\x7b\x31\x3a\x31\x7d",
815 "\x7b\x39\x39\x39\x39\x45\x39\x39\x39\x39\x3a\x31\x7d",
816 "\x7b\x6e\x75\x6c\x6c\x3a\x6e\x75\x6c\x6c\x2c\x6e\x75\x6c\x6c\x3a"
817 "\x6e\x75\x6c\x6c\x7d",
818 "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x2c\x2c\x2c\x2c\x7d",
819 "\x7b\x27\x61\x27\x3a\x30\x7d",
820 "\x7b\x22\x69\x64\x22\x3a\x30\x2c\x7d",
821 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f",
822 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2a\x2a\x2f\x2f",
823 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f\x2f",
824 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x2f",
825 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x2c\x2c\x22\x63\x22\x3a\x22\x64"
826 "\x22\x7d",
827 "\x7b\x61\x3a\x20\x22\x62\x22\x7d",
828 "\x7b\x22\x61\x22\x3a\x22\x61",
829 "\x7b\x20\x22\x66\x6f\x6f\x22\x20\x3a\x20\x22\x62\x61\x72\x22\x2c"
830 "\x20\x22\x61\x22\x20\x7d",
831 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23",
832 "\x20",
833 "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x22\x5d",
834 "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x22\x5d",
835 "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x22\x5d",
836 "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x31\x78\x22\x5d",
837 "\x5b\xc3\xa9\x5d",
838 "\x5b\x22\x5c\x78\x30\x30\x22\x5d",
839 "\x5b\x22\x5c\x5c\x5c\x22\x5d",
840 "\x5b\x22\x5c\x09\x22\x5d",
841 "\x5b\x22\x5c\xf0\x9f\x8c\x80\x22\x5d",
842 "\x5b\x22\x5c\x22\x5d",
843 "\x5b\x22\x5c\x75\x30\x30\x41\x22\x5d",
844 "\x5b\x22\x5c\x75\x44\x38\x33\x34\x5c\x75\x44\x64\x22\x5d",
845 "\x5b\x22\x5c\x75\x44\x38\x30\x30\x5c\x75\x44\x38\x30\x30\x5c\x78"
846 "\x22\x5d",
847 "\x5b\x22\x5c\x75\xe5\x22\x5d",
848 "\x5b\x22\x5c\x61\x22\x5d",
849 "\x5b\x22\x5c\x75\x71\x71\x71\x71\x22\x5d",
850 "\x5b\x22\x5c\xe5\x22\x5d",
851 "\x5b\x5c\x75\x30\x30\x32\x30\x22\x61\x73\x64\x22\x5d",
852 "\x5b\x5c\x6e\x5d",
853 "\x22",
854 "\x5b\x27\x73\x69\x6e\x67\x6c\x65\x20\x71\x75\x6f\x74\x65\x27\x5d"
855 "",
856 "\x61\x62\x63",
857 "\x5b\x22\x5c",
858 "\x5b\x22\x6e\x65\x77\x0a\x6c\x69\x6e\x65\x22\x5d",
859 "\x5b\x22\x09\x22\x5d",
860 "\x22\x5c\x55\x41\x36\x36\x44\x22",
861 "\x22\x22\x78",
862 "\x5b\xe2\x81\xa0\x5d",
863 "\xef\xbb\xbf",
864 "\x3c\x2e\x3e",
865 "\x5b\x3c\x6e\x75\x6c\x6c\x3e\x5d",
866 "\x5b\x31\x5d\x78",
867 "\x5b\x31\x5d\x5d",
868 "\x5b\x22\x61\x73\x64\x5d",
869 "\x61\xc3\xa5",
870 "\x5b\x54\x72\x75\x65\x5d",
871 "\x31\x5d",
872 "\x7b\x22\x78\x22\x3a\x20\x74\x72\x75\x65\x2c",
873 "\x5b\x5d\x5b\x5d",
874 "\x5d",
875 "\xef\xbb\x7b\x7d",
876 "\xe5",
877 "\x5b",
878 "",
879 "\x32\x40",
880 "\x7b\x7d\x7d",
881 "\x7b\x22\x22\x3a",
882 "\x7b\x22\x61\x22\x3a\x2f\x2a\x63\x6f\x6d\x6d\x65\x6e\x74\x2a\x2f"
883 "\x22\x62\x22\x7d",
884 "\x7b\x22\x61\x22\x3a\x20\x74\x72\x75\x65\x7d\x20\x22\x78\x22",
885 "\x5b\x27",
886 "\x5b\x2c",
887 "\x5b\x7b",
888 "\x5b\x22\x61",
889 "\x5b\x22\x61\x22",
890 "\x7b",
891 "\x7b\x5d",
892 "\x7b\x2c",
893 "\x7b\x5b",
894 "\x7b\x22\x61",
895 "\x7b\x27\x61\x27",
896 "\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b\x5b\x22\x5c\x7b"
897 "",
898 "\xe9",
899 "\x2a",
900 "\x7b\x22\x61\x22\x3a\x22\x62\x22\x7d\x23\x7b\x7d",
901 "\x5b\x5c\x75\x30\x30\x30\x41\x22\x22\x5d",
902 "\x5b\x31",
903 "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x6e\x75\x6c",
904 "\x5b\x20\x74\x72\x75\x65\x2c\x20\x66\x61\x6c\x73",
905 "\x5b\x20\x66\x61\x6c\x73\x65\x2c\x20\x74\x72\x75",
906 "\x7b\x22\x61\x73\x64\x22\x3a\x22\x61\x73\x64\x22",
907 "\xc3\xa5",
908 "\x5b\xe2\x81\xa0\x5d",
909 "\x5b\x0c\x5d",
910 NULL
911 };
912
913 static void
test_good(const char * j)914 test_good(const char *j)
915 {
916 struct vjsn *js;
917 const char *err;
918
919 js = vjsn_parse(j, &err);
920 if (js == NULL || err != NULL) {
921 fprintf(stderr, "Parse error: %s\n%s\n", err, j);
922 exit(1);
923 }
924 printf("GOOD: %s\n", j);
925 vjsn_dump(js, stdout);
926 vjsn_delete(&js);
927 }
928
929 static void
test_bad(const char * j)930 test_bad(const char *j)
931 {
932 struct vjsn *js;
933 const char *err;
934
935 js = vjsn_parse(j, &err);
936 if (js != NULL || err == NULL) {
937 fprintf(stderr, "Parse succeeded %s\n", j);
938 exit(1);
939 }
940 printf("BAD: %s %s\n", err, j);
941 }
942
943 int
main(int argc,char ** argv)944 main(int argc, char **argv)
945 {
946 const char **s;
947
948 (void)argc;
949 (void)argv;
950 for (s = good; *s != NULL; s++)
951 test_good(*s);
952 for (s = bad; *s != NULL; s++)
953 test_bad(*s);
954
955 /*
956 * This is part of Nicolas i(ndeterminate) test set, for reasons I
957 * do not fully grasp, but we want it to test bad.
958 */
959 test_bad("\"\\uDFAA\"");
960 printf("Tests done\n");
961 return (0);
962 }
963
964 #endif
965