1 /*
2  * Read and write JSON.
3  *
4  * Copyright (c) 2014  Marko Kreen
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <usual/json.h>
20 #include <usual/cxextra.h>
21 #include <usual/cbtree.h>
22 #include <usual/misc.h>
23 #include <usual/utf8.h>
24 #include <usual/ctype.h>
25 #include <usual/bytemap.h>
26 #include <usual/string.h>
27 #include <math.h>
28 
29 #define TYPE_BITS	3
30 #define TYPE_MASK	((1 << TYPE_BITS) - 1)
31 #define UNATTACHED	((struct JsonValue *)(1 << TYPE_BITS))
32 
33 #define JSON_MAX_KEY	(1024*1024)
34 
35 #define NUMBER_BUF	100
36 
37 #define JSON_MAXINT	((1LL << 53) - 1)
38 #define JSON_MININT	(-(1LL << 53) + 1)
39 
40 /*
41  * Common struct for all JSON values
42  */
43 struct JsonValue {
44 	/* actual value for simple types */
45 	union {
46 		double v_float;			/* float */
47 		int64_t v_int;			/* int */
48 		bool v_bool;			/* bool */
49 		size_t v_size;			/* str/list/dict */
50 	} u;
51 
52 	/* pointer to next elem and type in low bits */
53 	uintptr_t v_next_and_type;
54 };
55 
56 /*
57  * List container.
58  */
59 struct ValueList {
60 	struct JsonValue *first;
61 	struct JsonValue *last;
62 	struct JsonValue **array;
63 };
64 
65 /*
66  * Extra data for list/dict.
67  */
68 struct JsonContainer {
69 	/* parent container */
70 	struct JsonValue *c_parent;
71 
72 	/* main context for child alloc */
73 	struct JsonContext *c_ctx;
74 
75 	/* child elements */
76 	union {
77 		struct CBTree *c_dict;
78 		struct ValueList c_list;
79 	} u;
80 };
81 
82 #define DICT_EXTRA (offsetof(struct JsonContainer, u.c_dict) + sizeof(struct CBTree *))
83 #define LIST_EXTRA (sizeof(struct JsonContainer))
84 
85 /*
86  * Allocation context.
87  */
88 struct JsonContext {
89 	CxMem *pool;
90 	unsigned int options;
91 
92 	/* parse state */
93 	struct JsonValue *parent;
94 	struct JsonValue *cur_key;
95 	struct JsonValue *top;
96 	const char *lasterr;
97 	char errbuf[128];
98 	int64_t linenr;
99 };
100 
101 struct RenderState {
102 	struct MBuf *dst;
103 	unsigned int options;
104 };
105 
106 /*
107  * Parser states
108  */
109 enum ParseState {
110 	S_INITIAL_VALUE = 1,
111 	S_LIST_VALUE,
112 	S_LIST_VALUE_OR_CLOSE,
113 	S_LIST_COMMA_OR_CLOSE,
114 	S_DICT_KEY,
115 	S_DICT_KEY_OR_CLOSE,
116 	S_DICT_COLON,
117 	S_DICT_VALUE,
118 	S_DICT_COMMA_OR_CLOSE,
119 	S_PARENT,
120 	S_DONE,
121 	MAX_STATES,
122 };
123 
124 /*
125  * Tokens that change state.
126  */
127 enum TokenTypes {
128 	T_STRING,
129 	T_OTHER,
130 	T_COMMA,
131 	T_COLON,
132 	T_OPEN_DICT,
133 	T_OPEN_LIST,
134 	T_CLOSE_DICT,
135 	T_CLOSE_LIST,
136 	MAX_TOKENS
137 };
138 
139 /*
140  * 4-byte ints for small string tokens.
141  */
142 
143 #define C_NULL FOURCC('n','u','l','l')
144 #define C_TRUE FOURCC('t','r','u','e')
145 #define C_ALSE FOURCC('a','l','s','e')
146 
147 /*
148  * Signature for render functions.
149  */
150 typedef bool (*render_func_t)(struct RenderState *rs, struct JsonValue *jv);
151 
152 static bool render_any(struct RenderState *rs, struct JsonValue *jv);
153 
154 /*
155  * Header manipulation
156  */
157 
get_type(struct JsonValue * jv)158 static inline enum JsonValueType get_type(struct JsonValue *jv)
159 {
160 	return jv->v_next_and_type & TYPE_MASK;
161 }
162 
has_type(struct JsonValue * jv,enum JsonValueType type)163 static inline bool has_type(struct JsonValue *jv, enum JsonValueType type)
164 {
165 	if (!jv)
166 		return false;
167 	return get_type(jv) == type;
168 }
169 
get_next(struct JsonValue * jv)170 static inline struct JsonValue *get_next(struct JsonValue *jv)
171 {
172 	return (struct JsonValue *)(jv->v_next_and_type & ~(uintptr_t)TYPE_MASK);
173 }
174 
set_next(struct JsonValue * jv,struct JsonValue * next)175 static inline void set_next(struct JsonValue *jv, struct JsonValue *next)
176 {
177 	jv->v_next_and_type = (uintptr_t)next | get_type(jv);
178 }
179 
is_unattached(struct JsonValue * jv)180 static inline bool is_unattached(struct JsonValue *jv)
181 {
182 	return get_next(jv) == UNATTACHED;
183 }
184 
get_extra(struct JsonValue * jv)185 static inline void *get_extra(struct JsonValue *jv)
186 {
187 	return (void *)(jv + 1);
188 }
189 
get_cstring(struct JsonValue * jv)190 static inline char *get_cstring(struct JsonValue *jv)
191 {
192 	enum JsonValueType type = get_type(jv);
193 	if (type != JSON_STRING)
194 		return NULL;
195 	return get_extra(jv);
196 }
197 
198 /*
199  * Collection header manipulation.
200  */
201 
get_container(struct JsonValue * jv)202 static inline struct JsonContainer *get_container(struct JsonValue *jv)
203 {
204 	enum JsonValueType type = get_type(jv);
205 	if (type != JSON_DICT && type != JSON_LIST)
206 		return NULL;
207 	return get_extra(jv);
208 }
209 
set_parent(struct JsonValue * jv,struct JsonValue * parent)210 static inline void set_parent(struct JsonValue *jv, struct JsonValue *parent)
211 {
212 	struct JsonContainer *c = get_container(jv);
213 	if (c)
214 		c->c_parent = parent;
215 }
216 
get_context(struct JsonValue * jv)217 static inline struct JsonContext *get_context(struct JsonValue *jv)
218 {
219 	struct JsonContainer *c = get_container(jv);
220 	return c ? c->c_ctx : NULL;
221 }
222 
get_dict_tree(struct JsonValue * jv)223 static inline struct CBTree *get_dict_tree(struct JsonValue *jv)
224 {
225 	struct JsonContainer *c;
226 	if (has_type(jv, JSON_DICT)) {
227 		c = get_container(jv);
228 		return c->u.c_dict;
229 	}
230 	return NULL;
231 }
232 
get_list_vlist(struct JsonValue * jv)233 static inline struct ValueList *get_list_vlist(struct JsonValue *jv)
234 {
235 	struct JsonContainer *c;
236 	if (has_type(jv, JSON_LIST)) {
237 		c = get_container(jv);
238 		return &c->u.c_list;
239 	}
240 	return NULL;
241 }
242 
243 /*
244  * Random helpers
245  */
246 
247 /* copy and return final pointer */
plain_copy(char * dst,const char * src,const char * endptr)248 static inline char *plain_copy(char *dst, const char *src, const char *endptr)
249 {
250 	if (src < endptr) {
251 		memcpy(dst, src, endptr - src);
252 		return dst + (endptr - src);
253 	}
254 	return dst;
255 }
256 
257 /* error message on context */
258 _PRINTF(2,0)
format_err(struct JsonContext * ctx,const char * errmsg,va_list ap)259 static void format_err(struct JsonContext *ctx, const char *errmsg, va_list ap)
260 {
261 	char buf[119];
262 	if (ctx->lasterr)
263 		return;
264 	vsnprintf(buf, sizeof(buf), errmsg, ap);
265 	snprintf(ctx->errbuf, sizeof(ctx->errbuf), "Line #%" PRIi64 ": %s", ctx->linenr, buf);
266 	ctx->lasterr = ctx->errbuf;
267 }
268 
269 /* set message and return false */
270 _PRINTF(2,3)
err_false(struct JsonContext * ctx,const char * errmsg,...)271 static bool err_false(struct JsonContext *ctx, const char *errmsg, ...)
272 {
273 	va_list ap;
274 	va_start(ap, errmsg);
275 	format_err(ctx, errmsg, ap);
276 	va_end(ap);
277 	return false;
278 }
279 
280 /* set message and return NULL */
281 _PRINTF(2,3)
err_null(struct JsonContext * ctx,const char * errmsg,...)282 static void *err_null(struct JsonContext *ctx, const char *errmsg, ...)
283 {
284 	va_list ap;
285 	va_start(ap, errmsg);
286 	format_err(ctx, errmsg, ap);
287 	va_end(ap);
288 	return NULL;
289 }
290 
291 /* callback for cbtree, returns key bytes */
get_key_data_cb(void * dictptr,void * keyptr,const void ** dst_p)292 static size_t get_key_data_cb(void *dictptr, void *keyptr, const void **dst_p)
293 {
294 	struct JsonValue *key = keyptr;
295 	*dst_p = get_cstring(key);
296 	return key->u.v_size;
297 }
298 
299 /* add elemnt to list */
real_list_append(struct JsonValue * list,struct JsonValue * elem)300 static void real_list_append(struct JsonValue *list, struct JsonValue *elem)
301 {
302 	struct ValueList *vlist;
303 
304 	vlist = get_list_vlist(list);
305 	if (vlist->last) {
306 		set_next(vlist->last, elem);
307 	} else {
308 		vlist->first = elem;
309 	}
310 	vlist->last = elem;
311 	vlist->array = NULL;
312 
313 	list->u.v_size++;
314 }
315 
316 /* add key to tree */
real_dict_add_key(struct JsonContext * ctx,struct JsonValue * dict,struct JsonValue * key)317 static bool real_dict_add_key(struct JsonContext *ctx, struct JsonValue *dict, struct JsonValue *key)
318 {
319 	struct CBTree *tree;
320 
321 	tree = get_dict_tree(dict);
322 	if (!tree)
323 		return err_false(ctx, "Expect dict");
324 
325 	if (json_value_size(key) > JSON_MAX_KEY)
326 		return err_false(ctx, "Too large key");
327 
328 	dict->u.v_size++;
329 	if (!cbtree_insert(tree, key))
330 		return err_false(ctx, "Key insertion failed");
331 
332 	return true;
333 }
334 
335 /* create basic value struct, link to stuctures */
mk_value(struct JsonContext * ctx,enum JsonValueType type,size_t extra,bool attach)336 static struct JsonValue *mk_value(struct JsonContext *ctx, enum JsonValueType type, size_t extra, bool attach)
337 {
338 	struct JsonValue *val;
339 	struct JsonContainer *col = NULL;
340 
341 	if (!ctx)
342 		return NULL;
343 
344 	val = cx_alloc(ctx->pool, sizeof(struct JsonValue) + extra);
345 	if (!val)
346 		return err_null(ctx, "No memory");
347 	if ((uintptr_t)val & TYPE_MASK)
348 		return err_null(ctx, "Unaligned pointer");
349 
350 	/* initial value */
351 	val->v_next_and_type = type;
352 	val->u.v_int = 0;
353 
354 	if (type == JSON_DICT || type == JSON_LIST) {
355 		col = get_container(val);
356 		col->c_ctx = ctx;
357 		col->c_parent = NULL;
358 		if (type == JSON_DICT) {
359 			col->u.c_dict = cbtree_create(get_key_data_cb, NULL, val, ctx->pool);
360 			if (!col->u.c_dict)
361 				return err_null(ctx, "No memory");
362 		} else {
363 			memset(&col->u.c_list, 0, sizeof(col->u.c_list));
364 		}
365 	}
366 
367 	/* independent JsonValue? */
368 	if (!attach) {
369 		set_next(val, UNATTACHED);
370 		return val;
371 	}
372 
373 	/* attach to parent */
374 	if (col)
375 		col->c_parent = ctx->parent;
376 
377 	/* attach to previous value */
378 	if (has_type(ctx->parent, JSON_DICT)) {
379 		if (ctx->cur_key) {
380 			set_next(ctx->cur_key, val);
381 			ctx->cur_key = NULL;
382 		} else {
383 			ctx->cur_key = val;
384 		}
385 	} else if (has_type(ctx->parent, JSON_LIST)) {
386 		real_list_append(ctx->parent, val);
387 	} else if (!ctx->top) {
388 		ctx->top = val;
389 	} else {
390 		return err_null(ctx, "Only one top element is allowed");
391 	}
392 	return val;
393 }
394 
prepare_array(struct JsonValue * list)395 static void prepare_array(struct JsonValue *list)
396 {
397 	struct JsonContainer *c;
398 	struct JsonValue *val;
399 	struct ValueList *vlist;
400 	size_t i;
401 
402 	vlist = get_list_vlist(list);
403 	if (vlist->array)
404 		return;
405 	c = get_container(list);
406 	vlist->array = cx_alloc(c->c_ctx->pool, list->u.v_size * sizeof(struct JsonValue *));
407 	if (!vlist->array)
408 		return;
409 	val = vlist->first;
410 	for (i = 0; i < list->u.v_size && val; i++) {
411 		vlist->array[i] = val;
412 		val = get_next(val);
413 	}
414 }
415 
416 /*
417  * Parsing code starts
418  */
419 
420 /* create and change context */
open_container(struct JsonContext * ctx,enum JsonValueType type,unsigned int extra)421 static bool open_container(struct JsonContext *ctx, enum JsonValueType type, unsigned int extra)
422 {
423 	struct JsonValue *jv;
424 
425 	jv = mk_value(ctx, type, extra, true);
426 	if (!jv)
427 		return false;
428 
429 	ctx->parent = jv;
430 	ctx->cur_key = NULL;
431 	return true;
432 }
433 
434 /* close and change context */
close_container(struct JsonContext * ctx,enum ParseState state)435 static enum ParseState close_container(struct JsonContext *ctx, enum ParseState state)
436 {
437 	struct JsonContainer *c;
438 
439 	if (state != S_PARENT)
440 		return (int)err_false(ctx, "close_container bug");
441 
442 	c = get_container(ctx->parent);
443 	if (!c)
444 		return (int)err_false(ctx, "invalid parent");
445 
446 	ctx->parent = c->c_parent;
447 	ctx->cur_key = NULL;
448 
449 	if (has_type(ctx->parent, JSON_DICT)) {
450 		return S_DICT_COMMA_OR_CLOSE;
451 	} else if (has_type(ctx->parent, JSON_LIST)) {
452 		return S_LIST_COMMA_OR_CLOSE;
453 	}
454 	return S_DONE;
455 }
456 
457 /* parse 4-char token */
parse_char4(struct JsonContext * ctx,const char ** src_p,const char * end,uint32_t t_exp,enum JsonValueType type,bool val)458 static bool parse_char4(struct JsonContext *ctx, const char **src_p, const char *end,
459 			        uint32_t t_exp, enum JsonValueType type, bool val)
460 {
461 	const char *src;
462 	uint32_t t_got;
463 	struct JsonValue *jv;
464 
465 	src = *src_p;
466 	if (src + 4 > end)
467 		return err_false(ctx, "Unexpected end of token");
468 
469 	memcpy(&t_got, src, 4);
470 	if (t_exp != t_got)
471 		return err_false(ctx, "Invalid token");
472 
473 	jv = mk_value(ctx, type, 0, true);
474 	if (!jv)
475 		return false;
476 	jv->u.v_bool = val;
477 
478 	*src_p += 4;
479 	return true;
480 }
481 
482 /* parse int or float */
parse_number(struct JsonContext * ctx,const char ** src_p,const char * end)483 static bool parse_number(struct JsonContext *ctx, const char **src_p, const char *end)
484 {
485 	const char *start, *src;
486 	enum JsonValueType type = JSON_INT;
487 	char *tokend = NULL;
488 	char buf[NUMBER_BUF];
489 	size_t len;
490 	struct JsonValue *jv;
491 	double v_float = 0;
492 	int64_t v_int = 0;
493 
494 	/* scan & copy */
495 	start = src = *src_p;
496 	for (; src < end; src++) {
497 		if (*src >= '0' && *src <= '9') {
498 		} else if (*src == '+' || *src == '-') {
499 		} else if (*src == '.' || *src == 'e' || *src == 'E') {
500 			type = JSON_FLOAT;
501 		} else {
502 			break;
503 		}
504 	}
505 	len = src - start;
506 	if (len >= NUMBER_BUF)
507 		goto failed;
508 	memcpy(buf, start, len);
509 	buf[len] = 0;
510 
511 	/* now parse */
512 	errno = 0;
513 	tokend = buf;
514 	if (type == JSON_FLOAT) {
515 		v_float = strtod_dot(buf, &tokend);
516 		if (*tokend != 0 || errno || !isfinite(v_float))
517 			goto failed;
518 	} else if (len < 8) {
519 		v_int = strtol(buf, &tokend, 10);
520 		if (*tokend != 0 || errno)
521 			goto failed;
522 	} else {
523 		v_int = strtoll(buf, &tokend, 10);
524 		if (*tokend != 0 || errno || v_int < JSON_MININT || v_int > JSON_MAXINT)
525 			goto failed;
526 	}
527 
528 	/* create value struct */
529 	jv = mk_value(ctx, type, 0, true);
530 	if (!jv)
531 		return false;
532 	if (type == JSON_FLOAT) {
533 		jv->u.v_float = v_float;
534 	} else {
535 		jv->u.v_int = v_int;
536 	}
537 
538 	*src_p = src;
539 	return true;
540 failed:
541 	if (!errno)
542 		errno = EINVAL;
543 	return err_false(ctx, "Number parse failed");
544 }
545 
546 /*
547  * String parsing
548  */
549 
parse_hex(const char * s,const char * end)550 static int parse_hex(const char *s, const char *end)
551 {
552 	int v = 0, c, i, x;
553 	if (s + 4 > end)
554 		return -1;
555 	for (i = 0; i < 4; i++) {
556 		c = s[i];
557 		if (c >= '0' && c <= '9') {
558 			x = c - '0';
559 		} else if (c >= 'a' && c <= 'f') {
560 			x = c - 'a' + 10;
561 		} else if (c >= 'A' && c <= 'F') {
562 			x = c - 'A' + 10;
563 		} else {
564 			return -1;
565 		}
566 		v = (v << 4) | x;
567 	}
568 	return v;
569 }
570 
571 /* process \uXXXX escapes, merge surrogates */
parse_uescape(struct JsonContext * ctx,char ** dst_p,char * dstend,const char ** src_p,const char * end)572 static bool parse_uescape(struct JsonContext *ctx, char **dst_p, char *dstend,
573 			  const char **src_p, const char *end)
574 {
575 	int c, c2;
576 	const char *src = *src_p;
577 
578 	c = parse_hex(src, end);
579 	if (c <= 0)
580 		return err_false(ctx, "Invalid hex escape");
581 	src += 4;
582 
583 	if (c >= 0xD800 && c <= 0xDFFF) {
584 		/* first surrogate */
585 		if (c >= 0xDC00)
586 			return err_false(ctx, "Invalid UTF16 escape");
587 		if (src + 6 > end)
588 			return err_false(ctx, "Invalid UTF16 escape");
589 
590 		/* second surrogate */
591 		if (src[0] != '\\' || src[1] != 'u')
592 			return err_false(ctx, "Invalid UTF16 escape");
593 		c2 = parse_hex(src + 2, end);
594 		if (c2 < 0xDC00 || c2 > 0xDFFF)
595 			return err_false(ctx, "Invalid UTF16 escape");
596 		c = 0x10000 + ((c & 0x3FF) << 10) + (c2 & 0x3FF);
597 		src += 6;
598 	}
599 
600 	/* now write char */
601 	if (!utf8_put_char(c, dst_p, dstend))
602 		return err_false(ctx, "Invalid UTF16 escape");
603 
604 	*src_p = src;
605 	return true;
606 }
607 
608 #define meta_string(c) (((c) == '"' || (c) == '\\' || (c) == '\0' || \
609 			 (c) == '\n' || ((c) & 0x80) != 0) ? 1 : 0)
610 static const uint8_t string_examine_chars[] = INTMAP256_CONST(meta_string);
611 
612 /* look for string end, validate contents */
scan_string(struct JsonContext * ctx,const char * src,const char * end,const char ** str_end_p,bool * hasesc_p,int64_t * nlines_p)613 static bool scan_string(struct JsonContext *ctx, const char *src, const char *end,
614 			const char **str_end_p, bool *hasesc_p, int64_t *nlines_p)
615 {
616 	bool hasesc = false;
617 	int64_t lines = 0;
618 	unsigned int n;
619 	bool check_utf8 = true;
620 
621 	if (ctx->options & JSON_PARSE_IGNORE_ENCODING)
622 		check_utf8 = false;
623 
624 	while (src < end) {
625 		if (!string_examine_chars[(uint8_t)*src]) {
626 			src++;
627 		} else if (*src == '"') {
628 			/* string end */
629 			*hasesc_p = hasesc;
630 			*str_end_p = src;
631 			*nlines_p = lines;
632 			return true;
633 		} else if (*src == '\\') {
634 			hasesc = true;
635 			src++;
636 			if (src < end && (*src == '\\' || *src == '"'))
637 				src++;
638 		} else if (*src & 0x80) {
639 			n = utf8_validate_seq(src, end);
640 			if (n) {
641 				src += n;
642 			} else if (check_utf8) {
643 				goto badutf;
644 			} else {
645 				src++;
646 			}
647 		} else if (*src == '\n') {
648 			lines++;
649 			src++;
650 		} else {
651 			goto badutf;
652 		}
653 	}
654 	return err_false(ctx, "Unexpected end of string");
655 
656 badutf:
657 	return err_false(ctx, "Invalid UTF8 sequence");
658 }
659 
660 /* string boundaries are known, copy and unescape */
process_escapes(struct JsonContext * ctx,const char * src,const char * end,char * dst,char * dstend)661 static char *process_escapes(struct JsonContext *ctx,
662 			     const char *src, const char *end,
663 			     char *dst, char *dstend)
664 {
665 	const char *esc;
666 
667 	/* process escapes */
668 	while (src < end) {
669 		esc = memchr(src, '\\', end - src);
670 		if (!esc) {
671 			dst = plain_copy(dst, src, end);
672 			break;
673 		}
674 		dst = plain_copy(dst, src, esc);
675 		src = esc + 1;
676 		switch (*src++) {
677 		case '"': *dst++ = '"'; break;
678 		case '\\': *dst++ = '\\'; break;
679 		case '/': *dst++ = '/'; break;
680 		case 'b': *dst++ = '\b'; break;
681 		case 'f': *dst++ = '\f'; break;
682 		case 'n': *dst++ = '\n'; break;
683 		case 'r': *dst++ = '\r'; break;
684 		case 't': *dst++ = '\t'; break;
685 		case 'u':
686 			if (!parse_uescape(ctx, &dst, dstend, &src, end))
687 				return NULL;
688 			break;
689 		default:
690 			return err_null(ctx, "Invalid escape code");
691 		}
692 	}
693 	return dst;
694 }
695 
696 /* 2-phase string processing */
parse_string(struct JsonContext * ctx,const char ** src_p,const char * end)697 static bool parse_string(struct JsonContext *ctx, const char **src_p, const char *end)
698 {
699 	const char *start, *strend = NULL;
700 	bool hasesc = false;
701 	char *dst, *dstend;
702 	size_t len;
703 	struct JsonValue *jv;
704 	int64_t lines = 0;
705 
706 	/* find string boundaries, validate */
707 	start = *src_p;
708 	if (!scan_string(ctx, start, end, &strend, &hasesc, &lines))
709 		return false;
710 
711 	/* create value struct */
712 	len = strend - start;
713 	jv = mk_value(ctx, JSON_STRING, len + 1, true);
714 	if (!jv)
715 		return false;
716 	dst = get_cstring(jv);
717 	dstend = dst + len;
718 
719 	/* copy & process escapes */
720 	if (hasesc) {
721 		dst = process_escapes(ctx, start, strend, dst, dstend);
722 		if (!dst)
723 			return false;
724 	} else {
725 		dst = plain_copy(dst, start, strend);
726 	}
727 
728 	*dst = '\0';
729 	jv->u.v_size = dst - get_cstring(jv);
730 	ctx->linenr += lines;
731 	*src_p = strend + 1;
732 	return true;
733 }
734 
735 /*
736  * Helpers for relaxed parsing
737  */
738 
skip_comment(struct JsonContext * ctx,const char ** src_p,const char * end)739 static bool skip_comment(struct JsonContext *ctx, const char **src_p, const char *end)
740 {
741 	const char *s, *start;
742 	char c;
743 	size_t lnr;
744 
745 	s = start = *src_p;
746 	if (s >= end)
747 		return false;
748 	c = *s++;
749 	if (c == '/') {
750 		s = memchr(s, '\n', end - s);
751 		if (s) {
752 			ctx->linenr++;
753 			*src_p = s + 1;
754 		} else {
755 			*src_p = end;
756 		}
757 		return true;
758 	} else if (c == '*') {
759 		for (lnr = 0; s + 2 <= end; s++) {
760 			if (s[0] == '*' && s[1] == '/') {
761 				ctx->linenr += lnr;
762 				*src_p = s + 2;
763 				return true;
764 			} else if (s[0] == '\n') {
765 				lnr++;
766 			}
767 		}
768 	}
769 	return false;
770 }
771 
skip_extra_comma(struct JsonContext * ctx,const char ** src_p,const char * end,enum ParseState state)772 static bool skip_extra_comma(struct JsonContext *ctx, const char **src_p, const char *end, enum ParseState state)
773 {
774 	bool skip = false;
775 	const char *src = *src_p;
776 
777 	while (src < end && isspace(*src)) {
778 		if (*src == '\n')
779 			ctx->linenr++;
780 		src++;
781 	}
782 
783 	if (src < end) {
784 		if (*src == '}') {
785 			if (state == S_DICT_COMMA_OR_CLOSE || state == S_DICT_KEY_OR_CLOSE)
786 				skip = true;
787 		} else if (*src == ']') {
788 			if (state == S_LIST_COMMA_OR_CLOSE || state == S_LIST_VALUE_OR_CLOSE)
789 				skip = true;
790 		}
791 	}
792 	*src_p = src;
793 	return skip;
794 }
795 
796 /*
797  * Main parser
798  */
799 
800 /* oldstate + token -> newstate */
801 static const unsigned char STATE_STEPS[MAX_STATES][MAX_TOKENS] = {
802 [S_INITIAL_VALUE] = {
803 	[T_OPEN_LIST] = S_LIST_VALUE_OR_CLOSE,
804 	[T_OPEN_DICT] = S_DICT_KEY_OR_CLOSE,
805 	[T_STRING] = S_DONE,
806 	[T_OTHER] = S_DONE },
807 [S_LIST_VALUE] = {
808 	[T_OPEN_LIST] = S_LIST_VALUE_OR_CLOSE,
809 	[T_OPEN_DICT] = S_DICT_KEY_OR_CLOSE,
810 	[T_STRING] = S_LIST_COMMA_OR_CLOSE,
811 	[T_OTHER] = S_LIST_COMMA_OR_CLOSE },
812 [S_LIST_VALUE_OR_CLOSE] = {
813 	[T_OPEN_LIST] = S_LIST_VALUE_OR_CLOSE,
814 	[T_OPEN_DICT] = S_DICT_KEY_OR_CLOSE,
815 	[T_STRING] = S_LIST_COMMA_OR_CLOSE,
816 	[T_OTHER] = S_LIST_COMMA_OR_CLOSE,
817 	[T_CLOSE_LIST] = S_PARENT },
818 [S_LIST_COMMA_OR_CLOSE] = {
819 	[T_COMMA] = S_LIST_VALUE,
820 	[T_CLOSE_LIST] = S_PARENT },
821 [S_DICT_KEY] = {
822 	[T_STRING] = S_DICT_COLON },
823 [S_DICT_KEY_OR_CLOSE] = {
824 	[T_STRING] = S_DICT_COLON,
825 	[T_CLOSE_DICT] = S_PARENT },
826 [S_DICT_COLON] = {
827 	[T_COLON] = S_DICT_VALUE },
828 [S_DICT_VALUE] = {
829 	[T_OPEN_LIST] = S_LIST_VALUE_OR_CLOSE,
830 	[T_OPEN_DICT] = S_DICT_KEY_OR_CLOSE,
831 	[T_STRING] = S_DICT_COMMA_OR_CLOSE,
832 	[T_OTHER] = S_DICT_COMMA_OR_CLOSE },
833 [S_DICT_COMMA_OR_CLOSE] = {
834 	[T_COMMA] = S_DICT_KEY,
835 	[T_CLOSE_DICT] = S_PARENT },
836 };
837 
838 #define MAPSTATE(state, tok) do { \
839 	int newstate = STATE_STEPS[state][tok]; \
840 	if (!newstate) \
841 		return err_false(ctx, "Unexpected symbol: '%c'", c); \
842 	state = newstate; \
843 } while (0)
844 
845 /* actual parser */
parse_tokens(struct JsonContext * ctx,const char * src,const char * end)846 static bool parse_tokens(struct JsonContext *ctx, const char *src, const char *end)
847 {
848 	char c;
849 	enum ParseState state = S_INITIAL_VALUE;
850 	bool relaxed = ctx->options & JSON_PARSE_RELAXED;
851 
852 	while (src < end) {
853 		c = *src++;
854 		switch (c) {
855 		case '\n':
856 			ctx->linenr++;
857 		case ' ': case '\t': case '\r': case '\f': case '\v':
858 			/* common case - many spaces */
859 			while (src < end && *src == ' ') src++;
860 			break;
861 		case '"':
862 			MAPSTATE(state, T_STRING);
863 			if (!parse_string(ctx, &src, end))
864 				goto failed;
865 			break;
866 		case 'n':
867 			MAPSTATE(state, T_OTHER);
868 			src--;
869 			if (!parse_char4(ctx, &src, end, C_NULL, JSON_NULL, 0))
870 				goto failed;
871 			continue;
872 		case 't':
873 			MAPSTATE(state, T_OTHER);
874 			src--;
875 			if (!parse_char4(ctx, &src, end, C_TRUE, JSON_BOOL, 1))
876 				goto failed;
877 			break;
878 		case 'f':
879 			MAPSTATE(state, T_OTHER);
880 			if (!parse_char4(ctx, &src, end, C_ALSE, JSON_BOOL, 0))
881 				goto failed;
882 			break;
883 		case '-':
884 		case '0': case '1': case '2': case '3': case '4':
885 		case '5': case '6': case '7': case '8': case '9':
886 			MAPSTATE(state, T_OTHER);
887 			src--;
888 			if (!parse_number(ctx, &src, end))
889 				goto failed;
890 			break;
891 		case '[':
892 			MAPSTATE(state, T_OPEN_LIST);
893 			if (!open_container(ctx, JSON_LIST, LIST_EXTRA))
894 				goto failed;
895 			break;
896 		case '{':
897 			MAPSTATE(state, T_OPEN_DICT);
898 			if (!open_container(ctx, JSON_DICT, DICT_EXTRA))
899 				goto failed;
900 			break;
901 		case ']':
902 			MAPSTATE(state, T_CLOSE_LIST);
903 			state = close_container(ctx, state);
904 			if (!state)
905 				goto failed;
906 			break;
907 		case '}':
908 			MAPSTATE(state, T_CLOSE_DICT);
909 			state = close_container(ctx, state);
910 			if (!state)
911 				goto failed;
912 			break;
913 		case ':':
914 			MAPSTATE(state, T_COLON);
915 			if (!real_dict_add_key(ctx, ctx->parent, ctx->cur_key))
916 				goto failed;
917 			break;
918 		case ',':
919 			if (relaxed && skip_extra_comma(ctx, &src, end, state))
920 				continue;
921 			MAPSTATE(state, T_COMMA);
922 			break;
923 		case '/':
924 			if (relaxed && skip_comment(ctx, &src, end))
925 				continue;
926 			/* fallthrough */
927 		default:
928 			return err_false(ctx, "Invalid symbol: '%c'", c);
929 		}
930 	}
931 	if (state != S_DONE)
932 		return err_false(ctx, "Container still open");
933 	return true;
934 failed:
935 	return false;
936 }
937 
938 /* parser public api */
json_parse(struct JsonContext * ctx,const char * json,size_t len)939 struct JsonValue *json_parse(struct JsonContext *ctx, const char *json, size_t len)
940 {
941 	const char *end = json + len;
942 
943 	/* reset parser */
944 	ctx->linenr = 1;
945 	ctx->parent = NULL;
946 	ctx->cur_key = NULL;
947 	ctx->lasterr = NULL;
948 	ctx->top = NULL;
949 
950 	if (!parse_tokens(ctx, json, end))
951 		return NULL;
952 
953 	return ctx->top;
954 }
955 
956 /*
957  * Render value as JSON string.
958  */
959 
render_null(struct RenderState * rs,struct JsonValue * jv)960 static bool render_null(struct RenderState *rs, struct JsonValue *jv)
961 {
962 	return mbuf_write(rs->dst, "null", 4);
963 }
964 
render_bool(struct RenderState * rs,struct JsonValue * jv)965 static bool render_bool(struct RenderState *rs, struct JsonValue *jv)
966 {
967 	if (jv->u.v_bool)
968 		return mbuf_write(rs->dst, "true", 4);
969 	return mbuf_write(rs->dst, "false", 5);
970 }
971 
render_int(struct RenderState * rs,struct JsonValue * jv)972 static bool render_int(struct RenderState *rs, struct JsonValue *jv)
973 {
974 	char buf[NUMBER_BUF];
975 	int len;
976 
977 	len = snprintf(buf, sizeof(buf), "%" PRIi64, jv->u.v_int);
978 	if (len < 0 || len >= NUMBER_BUF)
979 		return false;
980 	return mbuf_write(rs->dst, buf, len);
981 }
982 
render_float(struct RenderState * rs,struct JsonValue * jv)983 static bool render_float(struct RenderState *rs, struct JsonValue *jv)
984 {
985 	char buf[NUMBER_BUF + 2];
986 	int len;
987 
988 	len = dtostr_dot(buf, NUMBER_BUF, jv->u.v_float);
989 	if (len < 0 || len >= NUMBER_BUF)
990 		return false;
991 	if (!memchr(buf, '.', len) && !memchr(buf, 'e', len)) {
992 	    buf[len++] = '.';
993 	    buf[len++] = '0';
994 	}
995 	return mbuf_write(rs->dst, buf, len);
996 }
997 
escape_char(struct MBuf * dst,unsigned int c)998 static bool escape_char(struct MBuf *dst, unsigned int c)
999 {
1000 	char ec;
1001 	char buf[10];
1002 
1003 	/* start escape */
1004 	if (!mbuf_write_byte(dst, '\\'))
1005 		return false;
1006 
1007 	/* escape same char */
1008 	if (c == '"' || c == '\\')
1009 		return mbuf_write_byte(dst, c);
1010 
1011 	/* low-ascii mess */
1012 	switch (c) {
1013 	case '\b': ec = 'b'; break;
1014 	case '\f': ec = 'f'; break;
1015 	case '\n': ec = 'n'; break;
1016 	case '\r': ec = 'r'; break;
1017 	case '\t': ec = 't'; break;
1018 	default:
1019 		snprintf(buf, sizeof(buf), "u%04x", c);
1020 		return mbuf_write(dst, buf, 5);
1021 	}
1022 	return mbuf_write_byte(dst, ec);
1023 }
1024 
render_string(struct RenderState * rs,struct JsonValue * jv)1025 static bool render_string(struct RenderState *rs, struct JsonValue *jv)
1026 {
1027 	const char *s, *last;
1028 	const char *val = get_cstring(jv);
1029 	size_t len = jv->u.v_size;
1030 	const char *end = val + len;
1031 	unsigned int c;
1032 
1033 	/* start quote */
1034 	if (!mbuf_write_byte(rs->dst, '"'))
1035 		return false;
1036 
1037 	for (s = last = val; s < end; s++) {
1038 		if (*s == '"' || *s == '\\' || (unsigned char)*s < 0x20 ||
1039 			/* Valid in JSON, but not in JS:
1040 			   \u2028 - Line separator
1041 			   \u2029 - Paragraph separator */
1042 			((unsigned char)s[0] == 0xE2 && (unsigned char)s[1] == 0x80 &&
1043 			 ((unsigned char)s[2] == 0xA8 || (unsigned char)s[2] == 0xA9)))
1044 		{
1045 			/* flush */
1046 			if (last < s) {
1047 				if (!mbuf_write(rs->dst, last, s - last))
1048 					return false;
1049 			}
1050 
1051 			if ((unsigned char)s[0] == 0xE2) {
1052 				c = 0x2028 + ((unsigned char)s[2] - 0xA8);
1053 				last = s + 3;
1054 			} else {
1055 				c = (unsigned char)*s;
1056 				last = s + 1;
1057 			}
1058 
1059 			/* output escaped char */
1060 			if (!escape_char(rs->dst, c))
1061 				return false;
1062 		}
1063 	}
1064 
1065 	/* flush */
1066 	if (last < s) {
1067 		if (!mbuf_write(rs->dst, last, s - last))
1068 			return false;
1069 	}
1070 
1071 	/* final quote */
1072 	if (!mbuf_write_byte(rs->dst, '"'))
1073 		return false;
1074 
1075 	return true;
1076 }
1077 
1078 /*
1079  * Render complex values
1080  */
1081 
1082 struct ElemWriterState {
1083 	struct RenderState *rs;
1084 	char sep;
1085 };
1086 
list_elem_writer(void * arg,struct JsonValue * elem)1087 static bool list_elem_writer(void *arg, struct JsonValue *elem)
1088 {
1089 	struct ElemWriterState *state = arg;
1090 
1091 	if (state->sep && !mbuf_write_byte(state->rs->dst, state->sep))
1092 		return false;
1093 	state->sep = ',';
1094 
1095 	return render_any(state->rs, elem);
1096 }
1097 
render_list(struct RenderState * rs,struct JsonValue * list)1098 static bool render_list(struct RenderState *rs, struct JsonValue *list)
1099 {
1100 	struct ElemWriterState state;
1101 
1102 	state.rs = rs;
1103 	state.sep = 0;
1104 
1105 	if (!mbuf_write_byte(rs->dst, '['))
1106 		return false;
1107 	if (!json_list_iter(list, list_elem_writer, &state))
1108 		return false;
1109 	if (!mbuf_write_byte(rs->dst, ']'))
1110 		return false;
1111 	return true;
1112 }
1113 
dict_elem_writer(void * ctx,struct JsonValue * key,struct JsonValue * val)1114 static bool dict_elem_writer(void *ctx, struct JsonValue *key, struct JsonValue *val)
1115 {
1116 	struct ElemWriterState *state = ctx;
1117 
1118 	if (state->sep && !mbuf_write_byte(state->rs->dst, state->sep))
1119 		return false;
1120 	state->sep = ',';
1121 
1122 	if (!render_any(state->rs, key))
1123 		return false;
1124 	if (!mbuf_write_byte(state->rs->dst, ':'))
1125 		return false;
1126 	return render_any(state->rs, val);
1127 }
1128 
render_dict(struct RenderState * rs,struct JsonValue * dict)1129 static bool render_dict(struct RenderState *rs, struct JsonValue *dict)
1130 {
1131 	struct ElemWriterState state;
1132 
1133 	state.rs = rs;
1134 	state.sep = 0;
1135 
1136 	if (!mbuf_write_byte(rs->dst, '{'))
1137 		return false;
1138 	if (!json_dict_iter(dict, dict_elem_writer, &state))
1139 		return false;
1140 	if (!mbuf_write_byte(rs->dst, '}'))
1141 		return false;
1142 
1143 	return true;
1144 }
1145 
render_invalid(struct RenderState * rs,struct JsonValue * jv)1146 static bool render_invalid(struct RenderState *rs, struct JsonValue *jv)
1147 {
1148 	return false;
1149 }
1150 
1151 /*
1152  * Public api
1153  */
1154 
render_any(struct RenderState * rs,struct JsonValue * jv)1155 static bool render_any(struct RenderState *rs, struct JsonValue *jv)
1156 {
1157 	static const render_func_t rfunc_map[] = {
1158 		render_invalid, render_null, render_bool, render_int,
1159 		render_float, render_string, render_list, render_dict,
1160 	};
1161 	return rfunc_map[get_type(jv)](rs, jv);
1162 }
1163 
json_render(struct MBuf * dst,struct JsonValue * jv)1164 bool json_render(struct MBuf *dst, struct JsonValue *jv)
1165 {
1166 	struct RenderState rs;
1167 
1168 	rs.dst = dst;
1169 	rs.options = 0;
1170 	return render_any(&rs, jv);
1171 }
1172 
1173 /*
1174  * Examine single value
1175  */
1176 
json_value_type(struct JsonValue * jv)1177 enum JsonValueType json_value_type(struct JsonValue *jv)
1178 {
1179 	return get_type(jv);
1180 }
1181 
json_value_size(struct JsonValue * jv)1182 size_t json_value_size(struct JsonValue *jv)
1183 {
1184 	if (has_type(jv, JSON_STRING) ||
1185 	    has_type(jv, JSON_LIST) ||
1186 	    has_type(jv, JSON_DICT))
1187 		return jv->u.v_size;
1188 	return 0;
1189 }
1190 
json_value_as_bool(struct JsonValue * jv,bool * dst_p)1191 bool json_value_as_bool(struct JsonValue *jv, bool *dst_p)
1192 {
1193 	if (!has_type(jv, JSON_BOOL))
1194 		return false;
1195 	*dst_p = jv->u.v_bool;
1196 	return true;
1197 }
1198 
json_value_as_int(struct JsonValue * jv,int64_t * dst_p)1199 bool json_value_as_int(struct JsonValue *jv, int64_t *dst_p)
1200 {
1201 	if (!has_type(jv, JSON_INT))
1202 		return false;
1203 	*dst_p = jv->u.v_int;
1204 	return true;
1205 }
1206 
json_value_as_float(struct JsonValue * jv,double * dst_p)1207 bool json_value_as_float(struct JsonValue *jv, double *dst_p)
1208 {
1209 	if (!has_type(jv, JSON_FLOAT)) {
1210 		if (has_type(jv, JSON_INT)) {
1211 			*dst_p = jv->u.v_int;
1212 			return true;
1213 		}
1214 		return false;
1215 	}
1216 	*dst_p = jv->u.v_float;
1217 	return true;
1218 }
1219 
json_value_as_string(struct JsonValue * jv,const char ** dst_p,size_t * size_p)1220 bool json_value_as_string(struct JsonValue *jv, const char **dst_p, size_t *size_p)
1221 {
1222 	if (!has_type(jv, JSON_STRING))
1223 		return false;
1224 	*dst_p = get_cstring(jv);
1225 	if (size_p)
1226 		*size_p = jv->u.v_size;
1227 	return true;
1228 }
1229 
1230 /*
1231  * Load value from dict.
1232  */
1233 
dict_getter(struct JsonValue * dict,const char * key,unsigned int klen,struct JsonValue ** val_p,enum JsonValueType req_type,bool req_value)1234 static int dict_getter(struct JsonValue *dict,
1235 		       const char *key, unsigned int klen,
1236 		       struct JsonValue **val_p,
1237 		       enum JsonValueType req_type, bool req_value)
1238 {
1239 	struct JsonValue *val, *kjv;
1240 	struct CBTree *tree;
1241 
1242 	tree = get_dict_tree(dict);
1243 	if (!tree)
1244 		return false;
1245 
1246 	kjv = cbtree_lookup(tree, key, klen);
1247 	if (!kjv) {
1248 		if (req_value)
1249 			return false;
1250 		*val_p = NULL;
1251 		return true;
1252 	}
1253 	val = get_next(kjv);
1254 	if (!req_value && json_value_is_null(val)) {
1255 		*val_p = NULL;
1256 		return true;
1257 	}
1258 	if (!has_type(val, req_type))
1259 		return false;
1260 	*val_p = val;
1261 	return true;
1262 }
1263 
json_dict_get_value(struct JsonValue * dict,const char * key,struct JsonValue ** val_p)1264 bool json_dict_get_value(struct JsonValue *dict, const char *key, struct JsonValue **val_p)
1265 {
1266 	struct CBTree *tree;
1267 	struct JsonValue *kjv;
1268 	size_t klen;
1269 
1270 	tree = get_dict_tree(dict);
1271 	if (!tree)
1272 		return false;
1273 
1274 	klen = strlen(key);
1275 	kjv = cbtree_lookup(tree, key, klen);
1276 	if (!kjv)
1277 		return false;
1278 	*val_p = get_next(kjv);
1279 	return true;
1280 }
1281 
json_dict_is_null(struct JsonValue * dict,const char * key)1282 bool json_dict_is_null(struct JsonValue *dict, const char *key)
1283 {
1284 	struct JsonValue *val;
1285 	if (!json_dict_get_value(dict, key, &val))
1286 		return true;
1287 	return has_type(val, JSON_NULL);
1288 }
1289 
json_dict_get_bool(struct JsonValue * dict,const char * key,bool * dst_p)1290 bool json_dict_get_bool(struct JsonValue *dict, const char *key, bool *dst_p)
1291 {
1292 	struct JsonValue *val;
1293 
1294 	if (!dict_getter(dict, key, strlen(key), &val, JSON_BOOL, true))
1295 		return false;
1296 	return json_value_as_bool(val, dst_p);
1297 }
1298 
json_dict_get_int(struct JsonValue * dict,const char * key,int64_t * dst_p)1299 bool json_dict_get_int(struct JsonValue *dict, const char *key, int64_t *dst_p)
1300 {
1301 	struct JsonValue *val;
1302 
1303 	if (!dict_getter(dict, key, strlen(key), &val, JSON_INT, true))
1304 		return false;
1305 	return json_value_as_int(val, dst_p);
1306 }
1307 
json_dict_get_float(struct JsonValue * dict,const char * key,double * dst_p)1308 bool json_dict_get_float(struct JsonValue *dict, const char *key, double *dst_p)
1309 {
1310 	struct JsonValue *val;
1311 
1312 	if (!dict_getter(dict, key, strlen(key), &val, JSON_FLOAT, true))
1313 		return false;
1314 	return json_value_as_float(val, dst_p);
1315 }
1316 
json_dict_get_string(struct JsonValue * dict,const char * key,const char ** dst_p,size_t * len_p)1317 bool json_dict_get_string(struct JsonValue *dict, const char *key, const char **dst_p, size_t *len_p)
1318 {
1319 	struct JsonValue *val;
1320 
1321 	if (!dict_getter(dict, key, strlen(key), &val, JSON_STRING, true))
1322 		return false;
1323 	return json_value_as_string(val, dst_p, len_p);
1324 }
1325 
json_dict_get_list(struct JsonValue * dict,const char * key,struct JsonValue ** dst_p)1326 bool json_dict_get_list(struct JsonValue *dict, const char *key, struct JsonValue **dst_p)
1327 {
1328 	return dict_getter(dict, key, strlen(key), dst_p, JSON_LIST, true);
1329 }
1330 
json_dict_get_dict(struct JsonValue * dict,const char * key,struct JsonValue ** dst_p)1331 bool json_dict_get_dict(struct JsonValue *dict, const char *key, struct JsonValue **dst_p)
1332 {
1333 	return dict_getter(dict, key, strlen(key), dst_p, JSON_DICT, true);
1334 }
1335 
1336 /*
1337  * Load optional dict element.
1338  */
1339 
json_dict_get_opt_bool(struct JsonValue * dict,const char * key,bool * dst_p)1340 bool json_dict_get_opt_bool(struct JsonValue *dict, const char *key, bool *dst_p)
1341 {
1342 	struct JsonValue *val;
1343 
1344 	if (!dict_getter(dict, key, strlen(key), &val, JSON_BOOL, false))
1345 		return false;
1346 	return !val || json_value_as_bool(val, dst_p);
1347 }
1348 
json_dict_get_opt_int(struct JsonValue * dict,const char * key,int64_t * dst_p)1349 bool json_dict_get_opt_int(struct JsonValue *dict, const char *key, int64_t *dst_p)
1350 {
1351 	struct JsonValue *val;
1352 
1353 	if (!dict_getter(dict, key, strlen(key), &val, JSON_INT, false))
1354 		return false;
1355 	return !val || json_value_as_int(val, dst_p);
1356 }
1357 
json_dict_get_opt_float(struct JsonValue * dict,const char * key,double * dst_p)1358 bool json_dict_get_opt_float(struct JsonValue *dict, const char *key, double *dst_p)
1359 {
1360 	struct JsonValue *val;
1361 
1362 	if (!dict_getter(dict, key, strlen(key), &val, JSON_FLOAT, false))
1363 		return false;
1364 	return !val || json_value_as_float(val, dst_p);
1365 }
1366 
json_dict_get_opt_string(struct JsonValue * dict,const char * key,const char ** dst_p,size_t * len_p)1367 bool json_dict_get_opt_string(struct JsonValue *dict, const char *key, const char **dst_p, size_t *len_p)
1368 {
1369 	struct JsonValue *val;
1370 
1371 	if (!dict_getter(dict, key, strlen(key), &val, JSON_STRING, false))
1372 		return false;
1373 	return !val || json_value_as_string(val, dst_p, len_p);
1374 }
1375 
json_dict_get_opt_list(struct JsonValue * dict,const char * key,struct JsonValue ** dst_p)1376 bool json_dict_get_opt_list(struct JsonValue *dict, const char *key, struct JsonValue **dst_p)
1377 {
1378 	struct JsonValue *val;
1379 
1380 	if (!dict_getter(dict, key, strlen(key), &val, JSON_LIST, false))
1381 		return false;
1382 	if (val)
1383 		*dst_p = val;
1384 	return true;
1385 }
1386 
json_dict_get_opt_dict(struct JsonValue * dict,const char * key,struct JsonValue ** dst_p)1387 bool json_dict_get_opt_dict(struct JsonValue *dict, const char *key, struct JsonValue **dst_p)
1388 {
1389 	struct JsonValue *val;
1390 
1391 	if (!dict_getter(dict, key, strlen(key), &val, JSON_DICT, false))
1392 		return false;
1393 	if (val)
1394 		*dst_p = val;
1395 	return true;
1396 }
1397 
1398 /*
1399  * Load value from list.
1400  */
1401 
json_list_get_value(struct JsonValue * list,size_t index,struct JsonValue ** val_p)1402 bool json_list_get_value(struct JsonValue *list, size_t index, struct JsonValue **val_p)
1403 {
1404 	struct JsonValue *val;
1405 	struct ValueList *vlist;
1406 	size_t i;
1407 
1408 	vlist = get_list_vlist(list);
1409 	if (!vlist)
1410 		return false;
1411 
1412 	if (index >= list->u.v_size)
1413 		return false;
1414 
1415 	if (!vlist->array && list->u.v_size > 10)
1416 		prepare_array(list);
1417 
1418 	/* direct fetch */
1419 	if (vlist->array) {
1420 		*val_p = vlist->array[index];
1421 		return true;
1422 	}
1423 
1424 	/* walk */
1425 	val = vlist->first;
1426 	for (i = 0; val; i++) {
1427 		if (i == index) {
1428 			*val_p = val;
1429 			return true;
1430 		}
1431 		val = get_next(val);
1432 	}
1433 	return false;
1434 }
1435 
json_list_is_null(struct JsonValue * list,size_t n)1436 bool json_list_is_null(struct JsonValue *list, size_t n)
1437 {
1438 	struct JsonValue *jv;
1439 	if (!json_list_get_value(list, n, &jv))
1440 		return true;
1441 	return has_type(jv, JSON_NULL);
1442 }
1443 
json_list_get_bool(struct JsonValue * list,size_t index,bool * val_p)1444 bool json_list_get_bool(struct JsonValue *list, size_t index, bool *val_p)
1445 {
1446 	struct JsonValue *jv;
1447 	if (!json_list_get_value(list, index, &jv))
1448 		return false;
1449 	return json_value_as_bool(jv, val_p);
1450 }
1451 
json_list_get_int(struct JsonValue * list,size_t index,int64_t * val_p)1452 bool json_list_get_int(struct JsonValue *list, size_t index, int64_t *val_p)
1453 {
1454 	struct JsonValue *jv;
1455 	if (!json_list_get_value(list, index, &jv))
1456 		return false;
1457 	return json_value_as_int(jv, val_p);
1458 }
1459 
json_list_get_float(struct JsonValue * list,size_t index,double * val_p)1460 bool json_list_get_float(struct JsonValue *list, size_t index, double *val_p)
1461 {
1462 	struct JsonValue *jv;
1463 	if (!json_list_get_value(list, index, &jv))
1464 		return false;
1465 	return json_value_as_float(jv, val_p);
1466 }
1467 
json_list_get_string(struct JsonValue * list,size_t index,const char ** val_p,size_t * len_p)1468 bool json_list_get_string(struct JsonValue *list, size_t index, const char **val_p, size_t *len_p)
1469 {
1470 	struct JsonValue *jv;
1471 	if (!json_list_get_value(list, index, &jv))
1472 		return false;
1473 	return json_value_as_string(jv, val_p, len_p);
1474 }
1475 
json_list_get_list(struct JsonValue * list,size_t index,struct JsonValue ** val_p)1476 bool json_list_get_list(struct JsonValue *list, size_t index, struct JsonValue **val_p)
1477 {
1478 	struct JsonValue *jv;
1479 	if (!json_list_get_value(list, index, &jv))
1480 		return false;
1481 	if (!has_type(jv, JSON_LIST))
1482 		return false;
1483 	*val_p = jv;
1484 	return true;
1485 }
1486 
json_list_get_dict(struct JsonValue * list,size_t index,struct JsonValue ** val_p)1487 bool json_list_get_dict(struct JsonValue *list, size_t index, struct JsonValue **val_p)
1488 {
1489 	struct JsonValue *jv;
1490 	if (!json_list_get_value(list, index, &jv))
1491 		return false;
1492 	if (!has_type(jv, JSON_DICT))
1493 		return false;
1494 	*val_p = jv;
1495 	return true;
1496 }
1497 
1498 /*
1499  * Iterate over list and dict values.
1500  */
1501 
1502 struct DictIterState {
1503 	json_dict_iter_callback_f cb_func;
1504 	void *cb_arg;
1505 };
1506 
dict_iter_helper(void * arg,void * jv)1507 static bool dict_iter_helper(void *arg, void *jv)
1508 {
1509 	struct DictIterState *state = arg;
1510 	struct JsonValue *key = jv;
1511 	struct JsonValue *val = get_next(key);
1512 
1513 	return state->cb_func(state->cb_arg, key, val);
1514 }
1515 
json_dict_iter(struct JsonValue * dict,json_dict_iter_callback_f cb_func,void * cb_arg)1516 bool json_dict_iter(struct JsonValue *dict, json_dict_iter_callback_f cb_func, void *cb_arg)
1517 {
1518 	struct DictIterState state;
1519 	struct CBTree *tree;
1520 
1521 	tree = get_dict_tree(dict);
1522 	if (!tree)
1523 		return false;
1524 
1525 	state.cb_func = cb_func;
1526 	state.cb_arg = cb_arg;
1527 	return cbtree_walk(tree, dict_iter_helper, &state);
1528 }
1529 
json_list_iter(struct JsonValue * list,json_list_iter_callback_f cb_func,void * cb_arg)1530 bool json_list_iter(struct JsonValue *list, json_list_iter_callback_f cb_func, void *cb_arg)
1531 {
1532 	struct JsonValue *elem;
1533 	struct ValueList *vlist;
1534 
1535 	vlist = get_list_vlist(list);
1536 	if (!vlist)
1537 		return false;
1538 
1539 	for (elem = vlist->first; elem; elem = get_next(elem)) {
1540 		if (!cb_func(cb_arg, elem))
1541 			return false;
1542 	}
1543 	return true;
1544 }
1545 
1546 /*
1547  * Create new values.
1548  */
1549 
json_new_null(struct JsonContext * ctx)1550 struct JsonValue *json_new_null(struct JsonContext *ctx)
1551 {
1552 	return mk_value(ctx, JSON_NULL, 0, false);
1553 }
1554 
json_new_bool(struct JsonContext * ctx,bool val)1555 struct JsonValue *json_new_bool(struct JsonContext *ctx, bool val)
1556 {
1557 	struct JsonValue *jv;
1558 
1559 	jv = mk_value(ctx, JSON_BOOL, 0, false);
1560 	if (jv)
1561 		jv->u.v_bool = val;
1562 	return jv;
1563 }
1564 
json_new_int(struct JsonContext * ctx,int64_t val)1565 struct JsonValue *json_new_int(struct JsonContext *ctx, int64_t val)
1566 {
1567 	struct JsonValue *jv;
1568 
1569 	if (val < JSON_MININT || val > JSON_MAXINT) {
1570 		errno = ERANGE;
1571 		return NULL;
1572 	}
1573 
1574 	jv = mk_value(ctx, JSON_INT, 0, false);
1575 	if (jv)
1576 		jv->u.v_int = val;
1577 	return jv;
1578 }
1579 
json_new_float(struct JsonContext * ctx,double val)1580 struct JsonValue *json_new_float(struct JsonContext *ctx, double val)
1581 {
1582 	struct JsonValue *jv;
1583 
1584 	/* check if value survives JSON roundtrip */
1585 	if (!isfinite(val))
1586 		return false;
1587 
1588 	jv = mk_value(ctx, JSON_FLOAT, 0, false);
1589 	if (jv)
1590 		jv->u.v_float = val;
1591 	return jv;
1592 }
1593 
json_new_string(struct JsonContext * ctx,const char * val)1594 struct JsonValue *json_new_string(struct JsonContext *ctx, const char *val)
1595 {
1596 	struct JsonValue *jv;
1597 	size_t len;
1598 
1599 	len = strlen(val);
1600 	if (!utf8_validate_string(val, val + len))
1601 		return NULL;
1602 
1603 	jv = mk_value(ctx, JSON_STRING, len + 1, false);
1604 	if (jv) {
1605 		memcpy(get_cstring(jv), val, len + 1);
1606 		jv->u.v_size = len;
1607 	}
1608 	return jv;
1609 }
1610 
json_new_list(struct JsonContext * ctx)1611 struct JsonValue *json_new_list(struct JsonContext *ctx)
1612 {
1613 	return mk_value(ctx, JSON_LIST, LIST_EXTRA, false);
1614 }
1615 
json_new_dict(struct JsonContext * ctx)1616 struct JsonValue *json_new_dict(struct JsonContext *ctx)
1617 {
1618 	return mk_value(ctx, JSON_DICT, DICT_EXTRA, false);
1619 }
1620 
1621 /*
1622  * Add to containers
1623  */
1624 
json_list_append(struct JsonValue * list,struct JsonValue * val)1625 bool json_list_append(struct JsonValue *list, struct JsonValue *val)
1626 {
1627 	if (!val)
1628 		return false;
1629 	if (!has_type(list, JSON_LIST))
1630 		return false;
1631 	if (!is_unattached(val))
1632 		return false;
1633 	set_parent(val, list);
1634 	set_next(val, NULL);
1635 	real_list_append(list, val);
1636 	return true;
1637 }
1638 
json_list_append_null(struct JsonValue * list)1639 bool json_list_append_null(struct JsonValue *list)
1640 {
1641 	struct JsonValue *v;
1642 
1643 	v = json_new_null(get_context(list));
1644 	return json_list_append(list, v);
1645 }
1646 
json_list_append_bool(struct JsonValue * list,bool val)1647 bool json_list_append_bool(struct JsonValue *list, bool val)
1648 {
1649 	struct JsonValue *v;
1650 
1651 	v = json_new_bool(get_context(list), val);
1652 	return json_list_append(list, v);
1653 }
1654 
json_list_append_int(struct JsonValue * list,int64_t val)1655 bool json_list_append_int(struct JsonValue *list, int64_t val)
1656 {
1657 	struct JsonValue *v;
1658 
1659 	v = json_new_int(get_context(list), val);
1660 	return json_list_append(list, v);
1661 }
1662 
json_list_append_float(struct JsonValue * list,double val)1663 bool json_list_append_float(struct JsonValue *list, double val)
1664 {
1665 	struct JsonValue *v;
1666 
1667 	v = json_new_float(get_context(list), val);
1668 	return json_list_append(list, v);
1669 }
1670 
json_list_append_string(struct JsonValue * list,const char * val)1671 bool json_list_append_string(struct JsonValue *list, const char *val)
1672 {
1673 	struct JsonValue *v;
1674 
1675 	v = json_new_string(get_context(list), val);
1676 	return json_list_append(list, v);
1677 }
1678 
json_dict_put(struct JsonValue * dict,const char * key,struct JsonValue * val)1679 bool json_dict_put(struct JsonValue *dict, const char *key, struct JsonValue *val)
1680 {
1681 	struct JsonValue *kjv;
1682 	struct JsonContainer *c;
1683 
1684 	if (!key || !val)
1685 		return false;
1686 	if (!has_type(dict, JSON_DICT))
1687 		return false;
1688 	if (!is_unattached(val))
1689 		return false;
1690 
1691 	c = get_container(dict);
1692 	kjv = json_new_string(c->c_ctx, key);
1693 	if (!kjv)
1694 		return false;
1695 
1696 	if (!real_dict_add_key(c->c_ctx, dict, kjv))
1697 		return false;
1698 
1699 	set_next(kjv, val);
1700 	set_next(val, NULL);
1701 
1702 	set_parent(val, dict);
1703 
1704 	return true;
1705 }
1706 
json_dict_put_null(struct JsonValue * dict,const char * key)1707 bool json_dict_put_null(struct JsonValue *dict, const char *key)
1708 {
1709 	struct JsonValue *v;
1710 
1711 	v = json_new_null(get_context(dict));
1712 	return json_dict_put(dict, key, v);
1713 }
1714 
json_dict_put_bool(struct JsonValue * dict,const char * key,bool val)1715 bool json_dict_put_bool(struct JsonValue *dict, const char *key, bool val)
1716 {
1717 	struct JsonValue *v;
1718 
1719 	v = json_new_bool(get_context(dict), val);
1720 	return json_dict_put(dict, key, v);
1721 }
1722 
json_dict_put_int(struct JsonValue * dict,const char * key,int64_t val)1723 bool json_dict_put_int(struct JsonValue *dict, const char *key, int64_t val)
1724 {
1725 	struct JsonValue *v;
1726 
1727 	v = json_new_int(get_context(dict), val);
1728 	return json_dict_put(dict, key, v);
1729 }
1730 
json_dict_put_float(struct JsonValue * dict,const char * key,double val)1731 bool json_dict_put_float(struct JsonValue *dict, const char *key, double val)
1732 {
1733 	struct JsonValue *v;
1734 
1735 	v = json_new_float(get_context(dict), val);
1736 	return json_dict_put(dict, key, v);
1737 }
1738 
json_dict_put_string(struct JsonValue * dict,const char * key,const char * val)1739 bool json_dict_put_string(struct JsonValue *dict, const char *key, const char *val)
1740 {
1741 	struct JsonValue *v;
1742 
1743 	v = json_new_string(get_context(dict), val);
1744 	return json_dict_put(dict, key, v);
1745 }
1746 
1747 /*
1748  * Main context management
1749  */
1750 
json_new_context(const void * cx,size_t initial_mem)1751 struct JsonContext *json_new_context(const void *cx, size_t initial_mem)
1752 {
1753 	struct JsonContext *ctx;
1754 	CxMem *pool;
1755 
1756 	pool = cx_new_pool(cx, initial_mem, 8);
1757 	if (!pool)
1758 		return NULL;
1759 	ctx = cx_alloc0(pool, sizeof(*ctx));
1760 	if (!ctx) {
1761 		cx_destroy(pool);
1762 		return NULL;
1763 	}
1764 	ctx->pool = pool;
1765 	return ctx;
1766 }
1767 
json_free_context(struct JsonContext * ctx)1768 void json_free_context(struct JsonContext *ctx)
1769 {
1770 	if (ctx) {
1771 		CxMem *pool = ctx->pool;
1772 		memset(ctx, 0, sizeof(*ctx));
1773 		cx_destroy(pool);
1774 	}
1775 }
1776 
json_strerror(struct JsonContext * ctx)1777 const char *json_strerror(struct JsonContext *ctx)
1778 {
1779 	return ctx->lasterr;
1780 }
1781 
json_set_options(struct JsonContext * ctx,unsigned int options)1782 void json_set_options(struct JsonContext *ctx, unsigned int options)
1783 {
1784 	ctx->options = options;
1785 }
1786