1 /*
2  * Copyright (c) 2019-2021 Joris Vink <joris@coders.se>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <sys/types.h>
18 
19 #include <float.h>
20 #include <inttypes.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 
26 #include "kore.h"
27 
28 static int	json_guess_type(u_int8_t, u_int32_t *);
29 static int	json_next(struct kore_json *, u_int8_t *);
30 static int	json_peek(struct kore_json *, u_int8_t *);
31 
32 static int	json_consume_whitespace(struct kore_json *);
33 static int	json_next_byte(struct kore_json *, u_int8_t *, int);
34 
35 static char	*json_get_string(struct kore_json *);
36 
37 static int	json_parse_array(struct kore_json *, struct kore_json_item *);
38 static int	json_parse_object(struct kore_json *, struct kore_json_item *);
39 static int	json_parse_string(struct kore_json *, struct kore_json_item *);
40 static int	json_parse_number(struct kore_json *, struct kore_json_item *);
41 static int	json_parse_literal(struct kore_json *, struct kore_json_item *);
42 
43 static struct kore_json_item	*json_item_alloc(int, const char *,
44 				    struct kore_json_item *);
45 static struct kore_json_item	*json_find_item(struct kore_json_item *,
46 				    char **, u_int32_t, int);
47 
48 static u_int8_t		json_null_literal[] = { 'n', 'u', 'l', 'l' };
49 static u_int8_t		json_true_literal[] = { 't', 'r', 'u', 'e' };
50 static u_int8_t		json_false_literal[] = { 'f', 'a', 'l', 's', 'e' };
51 
52 static const char *json_errtab[] = {
53 	"no error",
54 	"invalid JSON object",
55 	"invalid JSON array",
56 	"invalid JSON string",
57 	"invalid JSON number",
58 	"invalid JSON literal",
59 	"too many nested items",
60 	"end of stream while parsing JSON",
61 	"invalid JSON",
62 	"invalid search query specified",
63 	"item not found",
64 	"item found, but not expected value"
65 };
66 
67 void
kore_json_init(struct kore_json * json,const void * data,size_t len)68 kore_json_init(struct kore_json *json, const void *data, size_t len)
69 {
70 	memset(json, 0, sizeof(*json));
71 
72 	json->data = data;
73 	json->length = len;
74 
75 	kore_buf_init(&json->tmpbuf, 1024);
76 }
77 
78 int
kore_json_parse(struct kore_json * json)79 kore_json_parse(struct kore_json *json)
80 {
81 	u_int8_t	ch;
82 	u_int32_t	type;
83 
84 	if (json->root)
85 		return (KORE_RESULT_OK);
86 
87 	if (json_consume_whitespace(json) == -1) {
88 		json->error = KORE_JSON_ERR_INVALID_JSON;
89 		return (KORE_RESULT_ERROR);
90 	}
91 
92 	if (!json_peek(json, &ch))
93 		return (KORE_RESULT_ERROR);
94 
95 	if (!json_guess_type(ch, &type)) {
96 		json->error = KORE_JSON_ERR_INVALID_JSON;
97 		return (KORE_RESULT_ERROR);
98 	}
99 
100 	json->root = json_item_alloc(type, NULL, NULL);
101 
102 	if (!json->root->parse(json, json->root)) {
103 		if (json->error == 0)
104 			json->error = KORE_JSON_ERR_INVALID_JSON;
105 		return (KORE_RESULT_ERROR);
106 	}
107 
108 	/* Don't allow garbage at the end. */
109 	(void)json_consume_whitespace(json);
110 	if (json->offset != json->length) {
111 		json->error = KORE_JSON_ERR_INVALID_JSON;
112 		return (KORE_RESULT_ERROR);
113 	}
114 
115 	return (KORE_RESULT_OK);
116 }
117 
118 struct kore_json_item *
kore_json_find(struct kore_json_item * root,const char * path,u_int32_t type)119 kore_json_find(struct kore_json_item *root, const char *path, u_int32_t type)
120 {
121 	struct kore_json_item	*item;
122 	char			*copy;
123 	char			*tokens[KORE_JSON_DEPTH_MAX + 1];
124 
125 	copy = kore_strdup(path);
126 
127 	if (!kore_split_string(copy, "/", tokens, KORE_JSON_DEPTH_MAX)) {
128 		kore_free(copy);
129 		return (NULL);
130 	}
131 
132 	item = json_find_item(root, tokens, type, 0);
133 	kore_free(copy);
134 
135 	return (item);
136 }
137 
138 void
kore_json_cleanup(struct kore_json * json)139 kore_json_cleanup(struct kore_json *json)
140 {
141 	if (json == NULL)
142 		return;
143 
144 	kore_buf_cleanup(&json->tmpbuf);
145 	kore_json_item_free(json->root);
146 }
147 
148 const char *
kore_json_strerror(struct kore_json * json)149 kore_json_strerror(struct kore_json *json)
150 {
151 	if (json->error >= 0 && json->error <= KORE_JSON_ERR_LAST)
152 		return (json_errtab[json->error]);
153 
154 	return ("unknown JSON error");
155 }
156 
157 struct kore_json_item *
kore_json_create_item(struct kore_json_item * parent,const char * name,u_int32_t type,...)158 kore_json_create_item(struct kore_json_item *parent, const char *name,
159     u_int32_t type, ...)
160 {
161 	const char			*p;
162 	va_list				args;
163 	struct kore_json_item		*item;
164 
165 	item = kore_calloc(1, sizeof(*item));
166 	item->type = type;
167 
168 	va_start(args, type);
169 
170 	switch (item->type) {
171 	case KORE_JSON_TYPE_OBJECT:
172 		TAILQ_INIT(&item->data.items);
173 		break;
174 	case KORE_JSON_TYPE_ARRAY:
175 		TAILQ_INIT(&item->data.items);
176 		break;
177 	case KORE_JSON_TYPE_STRING:
178 		p = va_arg(args, const char *);
179 		item->data.string = kore_strdup(p);
180 		break;
181 	case KORE_JSON_TYPE_NUMBER:
182 		item->data.number = va_arg(args, double);
183 		break;
184 	case KORE_JSON_TYPE_INTEGER:
185 		item->data.s64 = va_arg(args, int64_t);
186 		break;
187 	case KORE_JSON_TYPE_INTEGER_U64:
188 		item->data.u64 = va_arg(args, u_int64_t);
189 		break;
190 	case KORE_JSON_TYPE_LITERAL:
191 		item->data.literal = va_arg(args, int);
192 		break;
193 	default:
194 		fatal("%s: unknown type %d", __func__, item->type);
195 	}
196 
197 	if (name)
198 		item->name = kore_strdup(name);
199 
200 	if (parent) {
201 		if (parent->type != KORE_JSON_TYPE_OBJECT &&
202 		    parent->type != KORE_JSON_TYPE_ARRAY) {
203 			fatal("%s: invalid parent type (%d)",
204 			    __func__, parent->type);
205 		}
206 
207 		TAILQ_INSERT_TAIL(&parent->data.items, item, list);
208 	}
209 
210 	va_end(args);
211 
212 	return (item);
213 }
214 
215 void
kore_json_item_tobuf(struct kore_json_item * item,struct kore_buf * buf)216 kore_json_item_tobuf(struct kore_json_item *item, struct kore_buf *buf)
217 {
218 	struct kore_json_item	*nitem;
219 
220 	if (item->name)
221 		kore_buf_appendf(buf, "\"%s\":", item->name);
222 
223 	switch (item->type) {
224 	case KORE_JSON_TYPE_OBJECT:
225 		kore_buf_appendf(buf, "{");
226 		TAILQ_FOREACH(nitem, &item->data.items, list) {
227 			kore_json_item_tobuf(nitem, buf);
228 
229 			if (TAILQ_NEXT(nitem, list))
230 				kore_buf_appendf(buf, ",");
231 		}
232 		kore_buf_appendf(buf, "}");
233 		break;
234 	case KORE_JSON_TYPE_ARRAY:
235 		kore_buf_appendf(buf, "[");
236 		TAILQ_FOREACH(nitem, &item->data.items, list) {
237 			kore_json_item_tobuf(nitem, buf);
238 
239 			if (TAILQ_NEXT(nitem, list))
240 				kore_buf_appendf(buf, ",");
241 		}
242 		kore_buf_appendf(buf, "]");
243 		break;
244 	case KORE_JSON_TYPE_STRING:
245 		kore_buf_appendf(buf, "\"%s\"", item->data.string);
246 		break;
247 	case KORE_JSON_TYPE_NUMBER:
248 		kore_buf_appendf(buf, "%f", item->data.number);
249 		break;
250 	case KORE_JSON_TYPE_INTEGER:
251 		kore_buf_appendf(buf, "%" PRId64, item->data.s64);
252 		break;
253 	case KORE_JSON_TYPE_INTEGER_U64:
254 		kore_buf_appendf(buf, "%" PRIu64, item->data.u64);
255 		break;
256 	case KORE_JSON_TYPE_LITERAL:
257 		switch (item->data.literal) {
258 		case KORE_JSON_TRUE:
259 			kore_buf_append(buf,
260 			    json_true_literal, sizeof(json_true_literal));
261 			break;
262 		case KORE_JSON_FALSE:
263 			kore_buf_append(buf,
264 			    json_false_literal, sizeof(json_false_literal));
265 			break;
266 		case KORE_JSON_NULL:
267 			kore_buf_append(buf,
268 			    json_null_literal, sizeof(json_null_literal));
269 			break;
270 		default:
271 			fatal("%s: unknown literal %d", __func__,
272 			    item->data.literal);
273 		}
274 		break;
275 	default:
276 		fatal("%s: unknown type %d", __func__, item->type);
277 	}
278 }
279 
280 static struct kore_json_item *
json_find_item(struct kore_json_item * object,char ** tokens,u_int32_t type,int pos)281 json_find_item(struct kore_json_item *object, char **tokens,
282     u_int32_t type, int pos)
283 {
284 	char			*p, *str;
285 	struct kore_json_item	*item, *nitem;
286 	int			err, idx, spot;
287 
288 	if (tokens[pos] == NULL)
289 		return (NULL);
290 
291 	if (object->type != KORE_JSON_TYPE_OBJECT &&
292 	    object->type != KORE_JSON_TYPE_ARRAY)
293 		return (NULL);
294 
295 	if ((str = strchr(tokens[pos], '[')) != NULL) {
296 		*(str)++ = '\0';
297 
298 		if ((p = strchr(str, ']')) == NULL)
299 			return (NULL);
300 
301 		*p = '\0';
302 
303 		spot = kore_strtonum(str, 10, 0, USHRT_MAX, &err);
304 		if (err != KORE_RESULT_OK)
305 			return (NULL);
306 	} else {
307 		spot = -1;
308 	}
309 
310 	item = NULL;
311 
312 	TAILQ_FOREACH(item, &object->data.items, list) {
313 		if (item->name && strcmp(item->name, tokens[pos]))
314 			continue;
315 
316 		if (item->type == KORE_JSON_TYPE_ARRAY && spot != -1) {
317 			idx = 0;
318 			nitem = NULL;
319 			TAILQ_FOREACH(nitem, &item->data.items, list) {
320 				if (idx++ == spot)
321 					break;
322 			}
323 
324 			if (nitem == NULL)
325 				return (NULL);
326 
327 			item = nitem;
328 		}
329 
330 		if (tokens[pos + 1] == NULL) {
331 			if (item->type == type)
332 				return (item);
333 			return (NULL);
334 		}
335 
336 		if (item->type == KORE_JSON_TYPE_OBJECT ||
337 		    item->type == KORE_JSON_TYPE_ARRAY) {
338 			item = json_find_item(item, tokens, type, pos + 1);
339 		} else {
340 			item = NULL;
341 		}
342 
343 		break;
344 	}
345 
346 	return (item);
347 }
348 
349 void
kore_json_item_free(struct kore_json_item * item)350 kore_json_item_free(struct kore_json_item *item)
351 {
352 	struct kore_json_item	*node;
353 
354 	if (item == NULL)
355 		return;
356 
357 	switch (item->type) {
358 	case KORE_JSON_TYPE_OBJECT:
359 	case KORE_JSON_TYPE_ARRAY:
360 		while ((node = TAILQ_FIRST(&item->data.items)) != NULL) {
361 			TAILQ_REMOVE(&item->data.items, node, list);
362 			kore_json_item_free(node);
363 		}
364 		break;
365 	case KORE_JSON_TYPE_STRING:
366 		kore_free(item->data.string);
367 		break;
368 	case KORE_JSON_TYPE_NUMBER:
369 	case KORE_JSON_TYPE_LITERAL:
370 	case KORE_JSON_TYPE_INTEGER:
371 	case KORE_JSON_TYPE_INTEGER_U64:
372 		break;
373 	default:
374 		fatal("%s: unknown type %d", __func__, item->type);
375 	}
376 
377 	kore_free(item->name);
378 	kore_free(item);
379 }
380 
381 static struct kore_json_item *
json_item_alloc(int type,const char * name,struct kore_json_item * parent)382 json_item_alloc(int type, const char *name, struct kore_json_item *parent)
383 {
384 	struct kore_json_item	*item;
385 
386 	item = kore_calloc(1, sizeof(*item));
387 	item->type = type;
388 	item->parent = parent;
389 
390 	switch (item->type) {
391 	case KORE_JSON_TYPE_OBJECT:
392 		TAILQ_INIT(&item->data.items);
393 		item->parse = json_parse_object;
394 		break;
395 	case KORE_JSON_TYPE_ARRAY:
396 		TAILQ_INIT(&item->data.items);
397 		item->parse = json_parse_array;
398 		break;
399 	case KORE_JSON_TYPE_STRING:
400 		item->parse = json_parse_string;
401 		break;
402 	case KORE_JSON_TYPE_NUMBER:
403 	case KORE_JSON_TYPE_INTEGER:
404 	case KORE_JSON_TYPE_INTEGER_U64:
405 		item->parse = json_parse_number;
406 		break;
407 	case KORE_JSON_TYPE_LITERAL:
408 		item->parse = json_parse_literal;
409 		break;
410 	default:
411 		fatal("%s: unknown type %d", __func__, item->type);
412 	}
413 
414 	if (name)
415 		item->name = kore_strdup(name);
416 
417 	if (parent) {
418 		if (parent->type != KORE_JSON_TYPE_OBJECT &&
419 		    parent->type != KORE_JSON_TYPE_ARRAY) {
420 			fatal("%s: invalid parent type (%d)",
421 			    __func__, parent->type);
422 		}
423 
424 		TAILQ_INSERT_TAIL(&parent->data.items, item, list);
425 	}
426 
427 	return (item);
428 }
429 
430 static int
json_peek(struct kore_json * json,u_int8_t * ch)431 json_peek(struct kore_json *json, u_int8_t *ch)
432 {
433 	return (json_next_byte(json, ch, 1));
434 }
435 
436 static int
json_next(struct kore_json * json,u_int8_t * ch)437 json_next(struct kore_json *json, u_int8_t *ch)
438 {
439 	return (json_next_byte(json, ch, 0));
440 }
441 
442 static int
json_next_byte(struct kore_json * json,u_int8_t * ch,int peek)443 json_next_byte(struct kore_json *json, u_int8_t *ch, int peek)
444 {
445 	if (json->offset >= json->length) {
446 		json->error = KORE_JSON_ERR_EOF;
447 		return (KORE_RESULT_ERROR);
448 	}
449 
450 	*ch = json->data[json->offset];
451 
452 	if (peek == 0)
453 		json->offset++;
454 
455 	return (KORE_RESULT_OK);
456 }
457 
458 static int
json_consume_whitespace(struct kore_json * json)459 json_consume_whitespace(struct kore_json *json)
460 {
461 	u_int8_t	ch;
462 
463 	for (;;) {
464 		if (!json_peek(json, &ch))
465 			return (KORE_RESULT_ERROR);
466 
467 		if (ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t')
468 			break;
469 
470 		json->offset++;
471 	}
472 
473 	return (KORE_RESULT_OK);
474 }
475 
476 static int
json_guess_type(u_int8_t ch,u_int32_t * type)477 json_guess_type(u_int8_t ch, u_int32_t *type)
478 {
479 	if (ch == '-' || (ch >= '0' && ch <= '9')) {
480 		*type = KORE_JSON_TYPE_NUMBER;
481 		return (KORE_RESULT_OK);
482 	}
483 
484 	switch (ch) {
485 	case '{':
486 		*type = KORE_JSON_TYPE_OBJECT;
487 		break;
488 	case '"':
489 		*type = KORE_JSON_TYPE_STRING;
490 		break;
491 	case '[':
492 		*type = KORE_JSON_TYPE_ARRAY;
493 		break;
494 	case 'f':
495 	case 'n':
496 	case 't':
497 		*type = KORE_JSON_TYPE_LITERAL;
498 		break;
499 	default:
500 		return (KORE_RESULT_ERROR);
501 	}
502 
503 	return (KORE_RESULT_OK);
504 }
505 
506 static int
json_parse_object(struct kore_json * json,struct kore_json_item * object)507 json_parse_object(struct kore_json *json, struct kore_json_item *object)
508 {
509 	u_int8_t		ch;
510 	u_int32_t		type;
511 	char			*key;
512 	struct kore_json_item	*item;
513 	int			ret, hasnext;
514 
515 	if (json->depth++ >= KORE_JSON_DEPTH_MAX) {
516 		json->error = KORE_JSON_ERR_DEPTH;
517 		return (KORE_RESULT_ERROR);
518 	}
519 
520 	key = NULL;
521 	hasnext = 0;
522 	ret = KORE_RESULT_ERROR;
523 
524 	if (!json_next(json, &ch))
525 		goto cleanup;
526 
527 	if (ch != '{')
528 		goto cleanup;
529 
530 	for (;;) {
531 		if (!json_consume_whitespace(json))
532 			goto cleanup;
533 
534 		if (!json_peek(json, &ch))
535 			goto cleanup;
536 
537 		switch (ch) {
538 		case '}':
539 			if (hasnext) {
540 				json->error = KORE_JSON_ERR_INVALID_JSON;
541 				goto cleanup;
542 			}
543 			json->offset++;
544 			ret = KORE_RESULT_OK;
545 			goto cleanup;
546 		case '"':
547 			if ((key = json_get_string(json)) == NULL)
548 				goto cleanup;
549 			break;
550 		default:
551 			goto cleanup;
552 		}
553 
554 		if (!json_consume_whitespace(json))
555 			goto cleanup;
556 
557 		if (!json_next(json, &ch))
558 			goto cleanup;
559 
560 		if (ch != ':')
561 			goto cleanup;
562 
563 		if (!json_consume_whitespace(json))
564 			goto cleanup;
565 
566 		if (!json_peek(json, &ch))
567 			goto cleanup;
568 
569 		if (!json_guess_type(ch, &type))
570 			goto cleanup;
571 
572 		item = json_item_alloc(type, key, object);
573 
574 		if (!item->parse(json, item))
575 			goto cleanup;
576 
577 		key = NULL;
578 
579 		if (!json_consume_whitespace(json))
580 			goto cleanup;
581 
582 		if (!json_next(json, &ch))
583 			goto cleanup;
584 
585 		if (ch == ',') {
586 			hasnext = 1;
587 			continue;
588 		}
589 
590 		if (ch == '}') {
591 			ret = KORE_RESULT_OK;
592 			break;
593 		}
594 
595 		break;
596 	}
597 
598 cleanup:
599 	if (ret == KORE_RESULT_ERROR && json->error == 0)
600 		json->error = KORE_JSON_ERR_INVALID_OBJECT;
601 
602 	json->depth--;
603 
604 	return (ret);
605 }
606 
607 static int
json_parse_array(struct kore_json * json,struct kore_json_item * array)608 json_parse_array(struct kore_json *json, struct kore_json_item *array)
609 {
610 	u_int8_t		ch;
611 	u_int32_t		type;
612 	char			*key;
613 	struct kore_json_item	*item;
614 	int			ret, hasnext;
615 
616 	if (json->depth++ >= KORE_JSON_DEPTH_MAX) {
617 		json->error = KORE_JSON_ERR_DEPTH;
618 		return (KORE_RESULT_ERROR);
619 	}
620 
621 	key = NULL;
622 	hasnext = 0;
623 	ret = KORE_RESULT_ERROR;
624 
625 	if (!json_next(json, &ch))
626 		goto cleanup;
627 
628 	if (ch != '[')
629 		goto cleanup;
630 
631 	for (;;) {
632 		if (!json_consume_whitespace(json))
633 			goto cleanup;
634 
635 		if (!json_peek(json, &ch))
636 			goto cleanup;
637 
638 		if (ch == ']') {
639 			if (hasnext) {
640 				json->error = KORE_JSON_ERR_INVALID_JSON;
641 				goto cleanup;
642 			}
643 			json->offset++;
644 			ret = KORE_RESULT_OK;
645 			goto cleanup;
646 		}
647 
648 		if (!json_guess_type(ch, &type))
649 			goto cleanup;
650 
651 		item = json_item_alloc(type, key, array);
652 
653 		if (!item->parse(json, item))
654 			goto cleanup;
655 
656 		key = NULL;
657 
658 		if (!json_consume_whitespace(json))
659 			goto cleanup;
660 
661 		if (!json_next(json, &ch))
662 			goto cleanup;
663 
664 		if (ch == ',') {
665 			hasnext = 1;
666 			continue;
667 		}
668 
669 		if (ch == ']') {
670 			ret = KORE_RESULT_OK;
671 			break;
672 		}
673 
674 		break;
675 	}
676 
677 cleanup:
678 	if (ret == KORE_RESULT_ERROR && json->error == 0)
679 		json->error = KORE_JSON_ERR_INVALID_ARRAY;
680 
681 	json->depth--;
682 
683 	return (ret);
684 }
685 
686 static int
json_parse_string(struct kore_json * json,struct kore_json_item * string)687 json_parse_string(struct kore_json *json, struct kore_json_item *string)
688 {
689 	char		*value;
690 
691 	if ((value = json_get_string(json)) == NULL)
692 		return (KORE_RESULT_ERROR);
693 
694 	string->type = KORE_JSON_TYPE_STRING;
695 	string->data.string = kore_strdup(value);
696 
697 	return (KORE_RESULT_OK);
698 }
699 
700 static int
json_parse_number(struct kore_json * json,struct kore_json_item * number)701 json_parse_number(struct kore_json *json, struct kore_json_item *number)
702 {
703 	u_int8_t	ch;
704 	int		ret;
705 	char		*str;
706 	u_int32_t	type;
707 
708 	str = NULL;
709 	ret = KORE_RESULT_ERROR;
710 	kore_buf_reset(&json->tmpbuf);
711 
712 	type = KORE_JSON_TYPE_NUMBER | KORE_JSON_TYPE_INTEGER |
713 	    KORE_JSON_TYPE_INTEGER_U64;
714 
715 	for (;;) {
716 		if (!json_peek(json, &ch))
717 			break;
718 
719 		switch (ch) {
720 		case 'e':
721 		case 'E':
722 		case '.':
723 			type = KORE_JSON_TYPE_NUMBER;
724 			kore_buf_append(&json->tmpbuf, &ch, sizeof(ch));
725 			json->offset++;
726 			continue;
727 		case '-':
728 			if (json->tmpbuf.offset != 0)
729 				goto cleanup;
730 			type &= ~KORE_JSON_TYPE_INTEGER_U64;
731 			/* FALLTHROUGH */
732 		case '0':
733 		case '1':
734 		case '2':
735 		case '3':
736 		case '4':
737 		case '5':
738 		case '6':
739 		case '7':
740 		case '8':
741 		case '9':
742 		case '+':
743 			kore_buf_append(&json->tmpbuf, &ch, sizeof(ch));
744 			json->offset++;
745 			continue;
746 		}
747 
748 		break;
749 	}
750 
751 	if (type & KORE_JSON_TYPE_INTEGER_U64)
752 		type = KORE_JSON_TYPE_INTEGER_U64;
753 
754 	if (type & KORE_JSON_TYPE_INTEGER)
755 		type = KORE_JSON_TYPE_INTEGER;
756 
757 	str = kore_buf_stringify(&json->tmpbuf, NULL);
758 
759 	switch (type) {
760 	case KORE_JSON_TYPE_NUMBER:
761 		number->data.number =
762 		    kore_strtodouble(str, -DBL_MAX, DBL_MAX, &ret);
763 		break;
764 	case KORE_JSON_TYPE_INTEGER:
765 		number->data.s64 = (int64_t)kore_strtonum64(str, 1, &ret);
766 		break;
767 	case KORE_JSON_TYPE_INTEGER_U64:
768 		number->data.s64 = kore_strtonum64(str, 0, &ret);
769 		break;
770 	default:
771 		goto cleanup;
772 	}
773 
774 	number->type = type;
775 
776 cleanup:
777 	if (ret == KORE_RESULT_ERROR && json->error == 0)
778 		json->error = KORE_JSON_ERR_INVALID_NUMBER;
779 
780 	return (ret);
781 }
782 
783 static int
json_parse_literal(struct kore_json * json,struct kore_json_item * literal)784 json_parse_literal(struct kore_json *json, struct kore_json_item *literal)
785 {
786 	size_t		len, idx;
787 	int		ret, val;
788 	u_int8_t	ch, *tmpl;
789 
790 	ret = KORE_RESULT_ERROR;
791 
792 	if (!json_next(json, &ch))
793 		goto cleanup;
794 
795 	switch (ch) {
796 	case 'f':
797 		val = KORE_JSON_FALSE;
798 		tmpl = json_false_literal;
799 		len = sizeof(json_false_literal) - 1;
800 		break;
801 	case 'n':
802 		val = KORE_JSON_NULL;
803 		tmpl = json_null_literal;
804 		len = sizeof(json_null_literal) - 1;
805 		break;
806 	case 't':
807 		val = KORE_JSON_TRUE;
808 		tmpl = json_true_literal;
809 		len = sizeof(json_true_literal) - 1;
810 		break;
811 	default:
812 		goto cleanup;
813 	}
814 
815 	for (idx = 0; idx < len; idx++) {
816 		if (!json_next(json, &ch))
817 			goto cleanup;
818 
819 		if (ch != tmpl[idx + 1])
820 			goto cleanup;
821 	}
822 
823 	literal->data.literal = val;
824 	literal->type = KORE_JSON_TYPE_LITERAL;
825 
826 	ret = KORE_RESULT_OK;
827 
828 cleanup:
829 	if (ret == KORE_RESULT_ERROR && json->error == 0)
830 		json->error = KORE_JSON_ERR_INVALID_LITERAL;
831 
832 	return (ret);
833 }
834 
835 static char *
json_get_string(struct kore_json * json)836 json_get_string(struct kore_json *json)
837 {
838 	u_int8_t	ch;
839 	char		*res;
840 
841 	res = NULL;
842 
843 	if (!json_next(json, &ch))
844 		goto cleanup;
845 
846 	if (ch != '"')
847 		goto cleanup;
848 
849 	kore_buf_reset(&json->tmpbuf);
850 
851 	for (;;) {
852 		if (!json_next(json, &ch))
853 			goto cleanup;
854 
855 		if (ch == '"')
856 			break;
857 
858 		if (ch <= 0x1f)
859 			goto cleanup;
860 
861 		if (ch == '\\') {
862 			if (!json_next(json, &ch))
863 				goto cleanup;
864 
865 			switch (ch) {
866 			case '\"':
867 			case '\\':
868 			case '/':
869 				break;
870 			case 'b':
871 				ch = '\b';
872 				break;
873 			case 'f':
874 				ch = '\f';
875 				break;
876 			case 'n':
877 				ch = '\n';
878 				break;
879 			case 'r':
880 				ch = '\r';
881 				break;
882 			case 't':
883 				ch = '\t';
884 				break;
885 			case 'u':
886 			default:
887 				/* XXX - not supported. */
888 				goto cleanup;
889 			}
890 		}
891 
892 		kore_buf_append(&json->tmpbuf, &ch, sizeof(ch));
893 	}
894 
895 	res = kore_buf_stringify(&json->tmpbuf, NULL);
896 
897 cleanup:
898 	if (res == NULL && json->error == 0)
899 		json->error = KORE_JSON_ERR_INVALID_STRING;
900 
901 	return (res);
902 }
903