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