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