kore

Kore is a web application platform for writing scalable, concurrent web based processes in C or Python.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

json.c (20428B)



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