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