1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/sys/__assert.h>
8 #include <ctype.h>
9 #include <errno.h>
10 #include <limits.h>
11 #include <zephyr/sys/printk.h>
12 #include <zephyr/sys/util.h>
13 #include <stdbool.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <zephyr/types.h>
17 
18 #include <zephyr/data/json.h>
19 
20 struct json_obj_key_value {
21 	const char *key;
22 	size_t key_len;
23 	struct json_token value;
24 };
25 
lexer_consume(struct json_lexer * lex,struct json_token * tok,enum json_tokens empty_token)26 static bool lexer_consume(struct json_lexer *lex, struct json_token *tok,
27 			  enum json_tokens empty_token)
28 {
29 	if (lex->tok.type == empty_token) {
30 		return false;
31 	}
32 
33 	*tok = lex->tok;
34 	lex->tok.type = empty_token;
35 
36 	return true;
37 }
38 
lexer_next(struct json_lexer * lex,struct json_token * tok)39 static bool lexer_next(struct json_lexer *lex, struct json_token *tok)
40 {
41 	while (lex->state) {
42 		if (lexer_consume(lex, tok, JSON_TOK_NONE)) {
43 			return true;
44 		}
45 
46 		lex->state = lex->state(lex);
47 	}
48 
49 	return lexer_consume(lex, tok, JSON_TOK_EOF);
50 }
51 
52 static void *lexer_json(struct json_lexer *lex);
53 
emit(struct json_lexer * lex,enum json_tokens token)54 static void emit(struct json_lexer *lex, enum json_tokens token)
55 {
56 	lex->tok.type = token;
57 	lex->tok.start = lex->start;
58 	lex->tok.end = lex->pos;
59 	lex->start = lex->pos;
60 }
61 
next(struct json_lexer * lex)62 static int next(struct json_lexer *lex)
63 {
64 	if (lex->pos >= lex->end) {
65 		lex->pos = lex->end + 1;
66 
67 		return '\0';
68 	}
69 
70 	return *lex->pos++;
71 }
72 
ignore(struct json_lexer * lex)73 static void ignore(struct json_lexer *lex)
74 {
75 	lex->start = lex->pos;
76 }
77 
backup(struct json_lexer * lex)78 static void backup(struct json_lexer *lex)
79 {
80 	lex->pos--;
81 }
82 
peek(struct json_lexer * lex)83 static int peek(struct json_lexer *lex)
84 {
85 	int chr = next(lex);
86 
87 	backup(lex);
88 
89 	return chr;
90 }
91 
lexer_string(struct json_lexer * lex)92 static void *lexer_string(struct json_lexer *lex)
93 {
94 	ignore(lex);
95 
96 	while (true) {
97 		int chr = next(lex);
98 
99 		if (chr == '\0') {
100 			emit(lex, JSON_TOK_ERROR);
101 			return NULL;
102 		}
103 
104 		if (chr == '\\') {
105 			switch (next(lex)) {
106 			case '"':
107 			case '\\':
108 			case '/':
109 			case 'b':
110 			case 'f':
111 			case 'n':
112 			case 'r':
113 			case 't':
114 				continue;
115 			case 'u':
116 				if (isxdigit(next(lex)) == 0) {
117 					goto error;
118 				}
119 
120 				if (isxdigit(next(lex)) == 0) {
121 					goto error;
122 				}
123 
124 				if (isxdigit(next(lex)) == 0) {
125 					goto error;
126 				}
127 
128 				if (isxdigit(next(lex)) == 0) {
129 					goto error;
130 				}
131 
132 				break;
133 			default:
134 				goto error;
135 			}
136 		}
137 
138 		if (chr == '"') {
139 			backup(lex);
140 			emit(lex, JSON_TOK_STRING);
141 
142 			next(lex);
143 			ignore(lex);
144 
145 			return lexer_json;
146 		}
147 	}
148 
149 error:
150 	emit(lex, JSON_TOK_ERROR);
151 	return NULL;
152 }
153 
accept_run(struct json_lexer * lex,const char * run)154 static int accept_run(struct json_lexer *lex, const char *run)
155 {
156 	for (; *run; run++) {
157 		if (next(lex) != *run) {
158 			return -EINVAL;
159 		}
160 	}
161 
162 	return 0;
163 }
164 
lexer_boolean(struct json_lexer * lex)165 static void *lexer_boolean(struct json_lexer *lex)
166 {
167 	backup(lex);
168 
169 	switch (next(lex)) {
170 	case 't':
171 		if (!accept_run(lex, "rue")) {
172 			emit(lex, JSON_TOK_TRUE);
173 			return lexer_json;
174 		}
175 		break;
176 	case 'f':
177 		if (!accept_run(lex, "alse")) {
178 			emit(lex, JSON_TOK_FALSE);
179 			return lexer_json;
180 		}
181 		break;
182 	}
183 
184 	emit(lex, JSON_TOK_ERROR);
185 	return NULL;
186 }
187 
lexer_null(struct json_lexer * lex)188 static void *lexer_null(struct json_lexer *lex)
189 {
190 	if (accept_run(lex, "ull") < 0) {
191 		emit(lex, JSON_TOK_ERROR);
192 		return NULL;
193 	}
194 
195 	emit(lex, JSON_TOK_NULL);
196 	return lexer_json;
197 }
198 
lexer_number(struct json_lexer * lex)199 static void *lexer_number(struct json_lexer *lex)
200 {
201 	while (true) {
202 		int chr = next(lex);
203 
204 		if (isdigit(chr) != 0 || chr == '.') {
205 			continue;
206 		}
207 
208 		backup(lex);
209 		emit(lex, JSON_TOK_NUMBER);
210 
211 		return lexer_json;
212 	}
213 }
214 
lexer_json(struct json_lexer * lex)215 static void *lexer_json(struct json_lexer *lex)
216 {
217 	while (true) {
218 		int chr = next(lex);
219 
220 		switch (chr) {
221 		case '\0':
222 			emit(lex, JSON_TOK_EOF);
223 			return NULL;
224 		case '}':
225 		case '{':
226 		case '[':
227 		case ']':
228 		case ',':
229 		case ':':
230 			emit(lex, (enum json_tokens)chr);
231 			return lexer_json;
232 		case '"':
233 			return lexer_string;
234 		case 'n':
235 			return lexer_null;
236 		case 't':
237 		case 'f':
238 			return lexer_boolean;
239 		case '-':
240 			if (isdigit(peek(lex)) != 0) {
241 				return lexer_number;
242 			}
243 
244 			__fallthrough;
245 		default:
246 			if (isspace(chr) != 0) {
247 				ignore(lex);
248 				continue;
249 			}
250 
251 			if (isdigit(chr) != 0) {
252 				return lexer_number;
253 			}
254 
255 			emit(lex, JSON_TOK_ERROR);
256 			return NULL;
257 		}
258 	}
259 }
260 
lexer_init(struct json_lexer * lex,char * data,size_t len)261 static void lexer_init(struct json_lexer *lex, char *data, size_t len)
262 {
263 	lex->state = lexer_json;
264 	lex->start = data;
265 	lex->pos = data;
266 	lex->end = data + len;
267 	lex->tok.type = JSON_TOK_NONE;
268 }
269 
obj_init(struct json_obj * json,char * data,size_t len)270 static int obj_init(struct json_obj *json, char *data, size_t len)
271 {
272 	struct json_token tok;
273 
274 	lexer_init(&json->lex, data, len);
275 
276 	if (!lexer_next(&json->lex, &tok)) {
277 		return -EINVAL;
278 	}
279 
280 	if (tok.type != JSON_TOK_OBJECT_START) {
281 		return -EINVAL;
282 	}
283 
284 	return 0;
285 }
286 
arr_init(struct json_obj * json,char * data,size_t len)287 static int arr_init(struct json_obj *json, char *data, size_t len)
288 {
289 	struct json_token tok;
290 
291 	lexer_init(&json->lex, data, len);
292 
293 	if (!lexer_next(&json->lex, &tok)) {
294 		return -EINVAL;
295 	}
296 
297 	if (tok.type != JSON_TOK_ARRAY_START) {
298 		return -EINVAL;
299 	}
300 
301 	return 0;
302 }
303 
element_token(enum json_tokens token)304 static int element_token(enum json_tokens token)
305 {
306 	switch (token) {
307 	case JSON_TOK_OBJECT_START:
308 	case JSON_TOK_ARRAY_START:
309 	case JSON_TOK_STRING:
310 	case JSON_TOK_NUMBER:
311 	case JSON_TOK_INT64:
312 	case JSON_TOK_UINT64:
313 	case JSON_TOK_FLOAT:
314 	case JSON_TOK_OPAQUE:
315 	case JSON_TOK_OBJ_ARRAY:
316 	case JSON_TOK_TRUE:
317 	case JSON_TOK_FALSE:
318 		return 0;
319 	default:
320 		return -EINVAL;
321 	}
322 }
323 
obj_next(struct json_obj * json,struct json_obj_key_value * kv)324 static int obj_next(struct json_obj *json,
325 		    struct json_obj_key_value *kv)
326 {
327 	struct json_token tok;
328 
329 	if (!lexer_next(&json->lex, &tok)) {
330 		return -EINVAL;
331 	}
332 
333 	/* Match end of object or next key */
334 	switch (tok.type) {
335 	case JSON_TOK_OBJECT_END:
336 		kv->key = NULL;
337 		kv->key_len = 0;
338 		kv->value = tok;
339 
340 		return 0;
341 	case JSON_TOK_COMMA:
342 		if (!lexer_next(&json->lex, &tok)) {
343 			return -EINVAL;
344 		}
345 
346 		if (tok.type != JSON_TOK_STRING) {
347 			return -EINVAL;
348 		}
349 
350 		__fallthrough;
351 	case JSON_TOK_STRING:
352 		kv->key = tok.start;
353 		kv->key_len = (size_t)(tok.end - tok.start);
354 		break;
355 	default:
356 		return -EINVAL;
357 	}
358 
359 	/* Match : after key */
360 	if (!lexer_next(&json->lex, &tok)) {
361 		return -EINVAL;
362 	}
363 
364 	if (tok.type != JSON_TOK_COLON) {
365 		return -EINVAL;
366 	}
367 
368 	/* Match value */
369 	if (!lexer_next(&json->lex, &kv->value)) {
370 		return -EINVAL;
371 	}
372 
373 	return element_token(kv->value.type);
374 }
375 
arr_next(struct json_obj * json,struct json_token * value)376 static int arr_next(struct json_obj *json, struct json_token *value)
377 {
378 	if (!lexer_next(&json->lex, value)) {
379 		return -EINVAL;
380 	}
381 
382 	if (value->type == JSON_TOK_ARRAY_END) {
383 		return 0;
384 	}
385 
386 	if (value->type == JSON_TOK_COMMA) {
387 		if (!lexer_next(&json->lex, value)) {
388 			return -EINVAL;
389 		}
390 	}
391 
392 	return element_token(value->type);
393 }
394 
skip_field(struct json_obj * obj,struct json_obj_key_value * kv)395 static int skip_field(struct json_obj *obj, struct json_obj_key_value *kv)
396 {
397 	int field_count = 1;
398 
399 	if (kv->value.type == JSON_TOK_OBJECT_START ||
400 	    kv->value.type == JSON_TOK_ARRAY_START) {
401 		while (field_count > 0 && lexer_next(&obj->lex, &kv->value)) {
402 			switch (kv->value.type) {
403 			case JSON_TOK_OBJECT_START:
404 			case JSON_TOK_ARRAY_START:
405 				field_count++;
406 				break;
407 			case JSON_TOK_OBJECT_END:
408 			case JSON_TOK_ARRAY_END:
409 				field_count--;
410 				break;
411 			case JSON_TOK_ERROR:
412 				return -EINVAL;
413 			default:
414 				break;
415 			}
416 		}
417 	}
418 
419 	return 0;
420 }
421 
decode_num(const struct json_token * token,int32_t * num)422 static int decode_num(const struct json_token *token, int32_t *num)
423 {
424 	/* FIXME: strtod() is not available in newlib/minimal libc,
425 	 * so using strtol() here.
426 	 */
427 	char *endptr;
428 	char prev_end;
429 
430 	prev_end = *token->end;
431 	*token->end = '\0';
432 
433 	errno = 0;
434 	*num = strtol(token->start, &endptr, 10);
435 
436 	*token->end = prev_end;
437 
438 	if (errno != 0) {
439 		return -errno;
440 	}
441 
442 	if (endptr != token->end) {
443 		return -EINVAL;
444 	}
445 
446 	return 0;
447 }
448 
decode_int64(const struct json_token * token,int64_t * num)449 static int decode_int64(const struct json_token *token, int64_t *num)
450 {
451 	char *endptr;
452 	char prev_end;
453 
454 	prev_end = *token->end;
455 	*token->end = '\0';
456 
457 	errno = 0;
458 	*num = strtoll(token->start, &endptr, 10);
459 
460 	*token->end = prev_end;
461 
462 	if (errno != 0) {
463 		return -errno;
464 	}
465 
466 	if (endptr != token->end) {
467 		return -EINVAL;
468 	}
469 
470 	return 0;
471 }
472 
decode_uint64(const struct json_token * token,uint64_t * num)473 static int decode_uint64(const struct json_token *token, uint64_t *num)
474 {
475 	char *endptr;
476 	char prev_end;
477 
478 	prev_end = *token->end;
479 	*token->end = '\0';
480 
481 	errno = 0;
482 	*num = strtoull(token->start, &endptr, 10);
483 
484 	*token->end = prev_end;
485 
486 	if (errno != 0) {
487 		return -errno;
488 	}
489 
490 	if (endptr != token->end) {
491 		return -EINVAL;
492 	}
493 
494 	return 0;
495 }
496 
equivalent_types(enum json_tokens type1,enum json_tokens type2)497 static bool equivalent_types(enum json_tokens type1, enum json_tokens type2)
498 {
499 	if (type1 == JSON_TOK_TRUE || type1 == JSON_TOK_FALSE) {
500 		return type2 == JSON_TOK_TRUE || type2 == JSON_TOK_FALSE;
501 	}
502 
503 	if (type1 == JSON_TOK_NUMBER && type2 == JSON_TOK_FLOAT) {
504 		return true;
505 	}
506 
507 	if (type1 == JSON_TOK_NUMBER && type2 == JSON_TOK_INT64) {
508 		return true;
509 	}
510 
511 	if (type1 == JSON_TOK_NUMBER && type2 == JSON_TOK_UINT64) {
512 		return true;
513 	}
514 
515 	if (type1 == JSON_TOK_STRING && type2 == JSON_TOK_OPAQUE) {
516 		return true;
517 	}
518 
519 	if (type1 == JSON_TOK_ARRAY_START && type2 == JSON_TOK_OBJ_ARRAY) {
520 		return true;
521 	}
522 
523 	return type1 == type2;
524 }
525 
526 static int64_t obj_parse(struct json_obj *obj,
527 			 const struct json_obj_descr *descr, size_t descr_len,
528 			 void *val);
529 static int arr_parse(struct json_obj *obj,
530 		     const struct json_obj_descr *elem_descr,
531 		     size_t max_elements, void *field, void *val);
532 
533 static int arr_data_parse(struct json_obj *obj, struct json_obj_token *val);
534 
decode_value(struct json_obj * obj,const struct json_obj_descr * descr,struct json_token * value,void * field,void * val)535 static int64_t decode_value(struct json_obj *obj,
536 			    const struct json_obj_descr *descr,
537 			    struct json_token *value, void *field, void *val)
538 {
539 
540 	if (!equivalent_types(value->type, descr->type)) {
541 		return -EINVAL;
542 	}
543 
544 	switch (descr->type) {
545 	case JSON_TOK_OBJECT_START:
546 		return obj_parse(obj, descr->object.sub_descr,
547 				 descr->object.sub_descr_len,
548 				 field);
549 	case JSON_TOK_ARRAY_START:
550 		return arr_parse(obj, descr->array.element_descr,
551 				 descr->array.n_elements, field, val);
552 	case JSON_TOK_OBJ_ARRAY: {
553 		struct json_obj_token *obj_token = field;
554 
555 		obj_token->start = value->start;
556 		return arr_data_parse(obj, obj_token);
557 	}
558 
559 	case JSON_TOK_FALSE:
560 	case JSON_TOK_TRUE: {
561 		bool *v = field;
562 
563 		*v = value->type == JSON_TOK_TRUE;
564 
565 		return 0;
566 	}
567 	case JSON_TOK_NUMBER: {
568 		int32_t *num = field;
569 
570 		return decode_num(value, num);
571 	}
572 	case JSON_TOK_INT64: {
573 		int64_t *num = field;
574 
575 		return decode_int64(value, num);
576 	}
577 	case JSON_TOK_UINT64: {
578 		uint64_t *num = field;
579 
580 		return decode_uint64(value, num);
581 	}
582 	case JSON_TOK_OPAQUE:
583 	case JSON_TOK_FLOAT: {
584 		struct json_obj_token *obj_token = field;
585 
586 		obj_token->start = value->start;
587 		obj_token->length = value->end - value->start;
588 		return 0;
589 	}
590 	case JSON_TOK_STRING: {
591 		char **str = field;
592 
593 		*value->end = '\0';
594 		*str = value->start;
595 
596 		return 0;
597 	}
598 	default:
599 		return -EINVAL;
600 	}
601 }
602 
get_elem_size(const struct json_obj_descr * descr)603 static ptrdiff_t get_elem_size(const struct json_obj_descr *descr)
604 {
605 	switch (descr->type) {
606 	case JSON_TOK_NUMBER:
607 		return sizeof(int32_t);
608 	case JSON_TOK_INT64:
609 		return sizeof(int64_t);
610 	case JSON_TOK_UINT64:
611 		return sizeof(uint64_t);
612 	case JSON_TOK_OPAQUE:
613 	case JSON_TOK_FLOAT:
614 	case JSON_TOK_OBJ_ARRAY:
615 		return sizeof(struct json_obj_token);
616 	case JSON_TOK_STRING:
617 		return sizeof(char *);
618 	case JSON_TOK_TRUE:
619 	case JSON_TOK_FALSE:
620 		return sizeof(bool);
621 	case JSON_TOK_ARRAY_START: {
622 		ptrdiff_t size;
623 
624 		size = descr->array.n_elements * get_elem_size(descr->array.element_descr);
625 		/* Consider additional item count field for array objects */
626 		if (descr->field_name_len > 0) {
627 			size = size + sizeof(size_t);
628 		}
629 
630 		return size;
631 	}
632 	case JSON_TOK_OBJECT_START: {
633 		ptrdiff_t total = 0;
634 		uint32_t align_shift = 0;
635 		size_t i;
636 
637 		for (i = 0; i < descr->object.sub_descr_len; i++) {
638 			total += get_elem_size(&descr->object.sub_descr[i]);
639 
640 			if (descr->object.sub_descr[i].align_shift > align_shift) {
641 				align_shift = descr->object.sub_descr[i].align_shift;
642 			}
643 		}
644 
645 		return ROUND_UP(total, 1 << align_shift);
646 	}
647 	default:
648 		return -EINVAL;
649 	}
650 }
651 
arr_parse(struct json_obj * obj,const struct json_obj_descr * elem_descr,size_t max_elements,void * field,void * val)652 static int arr_parse(struct json_obj *obj,
653 		     const struct json_obj_descr *elem_descr,
654 		     size_t max_elements, void *field, void *val)
655 {
656 	void *value = val;
657 	size_t *elements = (size_t *)((char *)value + elem_descr->offset);
658 	ptrdiff_t elem_size;
659 	void *last_elem;
660 	struct json_token tok;
661 
662 	/* For nested arrays, skip parent descriptor to get elements */
663 	if (elem_descr->type == JSON_TOK_ARRAY_START) {
664 		elem_descr = elem_descr->array.element_descr;
665 	}
666 
667 	*elements = 0;
668 	elem_size = get_elem_size(elem_descr);
669 	last_elem = (char *)field + elem_size * max_elements;
670 
671 	__ASSERT_NO_MSG(elem_size > 0);
672 
673 	while (!arr_next(obj, &tok)) {
674 		if (tok.type == JSON_TOK_ARRAY_END) {
675 			return 0;
676 		}
677 
678 		if (field == last_elem) {
679 			return -ENOSPC;
680 		}
681 
682 		/* For nested arrays, update value to current field,
683 		 * so it matches descriptor's offset to length field
684 		 */
685 		if (elem_descr->type == JSON_TOK_ARRAY_START) {
686 			value = field;
687 		}
688 
689 		if (decode_value(obj, elem_descr, &tok, field, value) < 0) {
690 			return -EINVAL;
691 		}
692 
693 		(*elements)++;
694 		field = (char *)field + elem_size;
695 	}
696 
697 	return -EINVAL;
698 }
699 
arr_data_parse(struct json_obj * obj,struct json_obj_token * val)700 static int arr_data_parse(struct json_obj *obj, struct json_obj_token *val)
701 {
702 	bool string_state = false;
703 	int array_in_array = 1;
704 
705 	/* Init length to zero */
706 	val->length = 0;
707 
708 	while (obj->lex.pos != obj->lex.end) {
709 		if (string_state) {
710 			if (*obj->lex.pos == JSON_TOK_STRING) {
711 				string_state = false;
712 			}
713 		} else {
714 			if (*obj->lex.pos == JSON_TOK_ARRAY_END) {
715 				array_in_array--;
716 				if (array_in_array == 0) {
717 					/* Set array data length + 1 object end */
718 					val->length = obj->lex.pos - val->start + 1;
719 					/* Init Lexer that Object Parse can be finished properly */
720 					obj->lex.state = lexer_json;
721 					/* Move position to before array end */
722 					obj->lex.pos--;
723 					obj->lex.tok.end = obj->lex.pos;
724 					obj->lex.tok.start = val->start;
725 					obj->lex.tok.type = JSON_TOK_NONE;
726 					return 0;
727 				}
728 			} else if (*obj->lex.pos == JSON_TOK_STRING) {
729 				string_state = true;
730 			} else if (*obj->lex.pos == JSON_TOK_ARRAY_START) {
731 				/* arrary in array update structure count */
732 				array_in_array++;
733 			}
734 		}
735 		obj->lex.pos++;
736 	}
737 
738 	return -EINVAL;
739 }
740 
obj_parse(struct json_obj * obj,const struct json_obj_descr * descr,size_t descr_len,void * val)741 static int64_t obj_parse(struct json_obj *obj, const struct json_obj_descr *descr,
742 			 size_t descr_len, void *val)
743 {
744 	struct json_obj_key_value kv;
745 	int64_t decoded_fields = 0;
746 	size_t i;
747 	int ret;
748 
749 	while (!obj_next(obj, &kv)) {
750 		if (kv.value.type == JSON_TOK_OBJECT_END) {
751 			return decoded_fields;
752 		}
753 
754 		for (i = 0; i < descr_len; i++) {
755 			void *decode_field = (char *)val + descr[i].offset;
756 
757 			/* Field has been decoded already, skip */
758 			if (decoded_fields & ((int64_t)1 << i)) {
759 				continue;
760 			}
761 
762 			/* Check if it's the i-th field */
763 			if (kv.key_len != descr[i].field_name_len) {
764 				continue;
765 			}
766 
767 			if (memcmp(kv.key, descr[i].field_name,
768 				   descr[i].field_name_len)) {
769 				continue;
770 			}
771 
772 			/* Store the decoded value */
773 			ret = decode_value(obj, &descr[i], &kv.value,
774 					   decode_field, val);
775 			if (ret < 0) {
776 				return ret;
777 			}
778 
779 			decoded_fields |= (int64_t)1<<i;
780 			break;
781 		}
782 
783 		/* Skip field, if no descriptor was found */
784 		if (i >= descr_len) {
785 			ret = skip_field(obj, &kv);
786 			if (ret < 0) {
787 				return ret;
788 			}
789 		}
790 	}
791 
792 	return -EINVAL;
793 }
794 
json_obj_parse(char * payload,size_t len,const struct json_obj_descr * descr,size_t descr_len,void * val)795 int64_t json_obj_parse(char *payload, size_t len,
796 		       const struct json_obj_descr *descr, size_t descr_len,
797 		       void *val)
798 {
799 	struct json_obj obj;
800 	int64_t ret;
801 
802 	__ASSERT_NO_MSG(descr_len < (sizeof(ret) * CHAR_BIT - 1));
803 
804 	ret = obj_init(&obj, payload, len);
805 	if (ret < 0) {
806 		return ret;
807 	}
808 
809 	return obj_parse(&obj, descr, descr_len, val);
810 }
811 
json_arr_parse(char * payload,size_t len,const struct json_obj_descr * descr,void * val)812 int json_arr_parse(char *payload, size_t len,
813 		   const struct json_obj_descr *descr, void *val)
814 {
815 	struct json_obj arr;
816 	int ret;
817 
818 	ret = arr_init(&arr, payload, len);
819 	if (ret < 0) {
820 		return ret;
821 	}
822 
823 	void *ptr = (char *)val + descr->offset;
824 
825 	return arr_parse(&arr, descr->array.element_descr,
826 			 descr->array.n_elements, ptr, val);
827 }
828 
829 
json_arr_separate_object_parse_init(struct json_obj * json,char * payload,size_t len)830 int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len)
831 {
832 	return arr_init(json, payload, len);
833 }
834 
json_arr_separate_parse_object(struct json_obj * json,const struct json_obj_descr * descr,size_t descr_len,void * val)835 int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr,
836 			  size_t descr_len, void *val)
837 {
838 	struct json_token tok;
839 
840 	if (!lexer_next(&json->lex, &tok)) {
841 		return -EINVAL;
842 	}
843 
844 	if (tok.type == JSON_TOK_ARRAY_END) {
845 		return 0;
846 	} else if (tok.type == JSON_TOK_COMMA) {
847 		if (!lexer_next(&json->lex, &tok)) {
848 			return -EINVAL;
849 		}
850 	}
851 
852 	if (tok.type != JSON_TOK_OBJECT_START) {
853 		return -EINVAL;
854 	}
855 
856 	return obj_parse(json, descr, descr_len, val);
857 }
858 
escape_as(char chr)859 static char escape_as(char chr)
860 {
861 	switch (chr) {
862 	case '"':
863 		return '"';
864 	case '\\':
865 		return '\\';
866 	case '\b':
867 		return 'b';
868 	case '\f':
869 		return 'f';
870 	case '\n':
871 		return 'n';
872 	case '\r':
873 		return 'r';
874 	case '\t':
875 		return 't';
876 	}
877 
878 	return 0;
879 }
880 
json_escape_internal(const char * str,json_append_bytes_t append_bytes,void * data)881 static int json_escape_internal(const char *str,
882 				json_append_bytes_t append_bytes,
883 				void *data)
884 {
885 	const char *cur;
886 	int ret = 0;
887 
888 	for (cur = str; ret == 0 && *cur; cur++) {
889 		char escaped = escape_as(*cur);
890 
891 		if (escaped) {
892 			char bytes[2] = { '\\', escaped };
893 
894 			ret = append_bytes(bytes, 2, data);
895 		} else {
896 			ret = append_bytes(cur, 1, data);
897 		}
898 	}
899 
900 	return ret;
901 }
902 
json_calc_escaped_len(const char * str,size_t len)903 size_t json_calc_escaped_len(const char *str, size_t len)
904 {
905 	size_t escaped_len = len;
906 	size_t pos;
907 
908 	for (pos = 0; pos < len; pos++) {
909 		if (escape_as(str[pos])) {
910 			escaped_len++;
911 		}
912 	}
913 
914 	return escaped_len;
915 }
916 
json_escape(char * str,size_t * len,size_t buf_size)917 ssize_t json_escape(char *str, size_t *len, size_t buf_size)
918 {
919 	char *next; /* Points after next character to escape. */
920 	char *dest; /* Points after next place to write escaped character. */
921 	size_t escaped_len = json_calc_escaped_len(str, *len);
922 
923 	if (escaped_len == *len) {
924 		/*
925 		 * If no escape is necessary, there is nothing to do.
926 		 */
927 		return 0;
928 	}
929 
930 	if (escaped_len >= buf_size) {
931 		return -ENOMEM;
932 	}
933 
934 	/*
935 	 * By walking backwards in the buffer from the end positions
936 	 * of both the original and escaped strings, we avoid using
937 	 * extra space. Characters in the original string are
938 	 * overwritten only after they have already been escaped.
939 	 */
940 	str[escaped_len] = '\0';
941 	for (next = &str[*len], dest = &str[escaped_len]; next != str;) {
942 		char next_c = *(--next);
943 		char escape = escape_as(next_c);
944 
945 		if (escape) {
946 			*(--dest) = escape;
947 			*(--dest) = '\\';
948 		} else {
949 			*(--dest) = next_c;
950 		}
951 	}
952 	*len = escaped_len;
953 
954 	return 0;
955 }
956 
957 static int encode(const struct json_obj_descr *descr, const void *val,
958 		  json_append_bytes_t append_bytes, void *data);
959 
arr_encode(const struct json_obj_descr * elem_descr,const void * field,const void * val,json_append_bytes_t append_bytes,void * data)960 static int arr_encode(const struct json_obj_descr *elem_descr,
961 		      const void *field, const void *val,
962 		      json_append_bytes_t append_bytes, void *data)
963 {
964 	ptrdiff_t elem_size;
965 	/*
966 	 * NOTE: Since an element descriptor's offset isn't meaningful
967 	 * (array elements occur at multiple offsets in `val'), we use
968 	 * its space in elem_descr to store the offset to the field
969 	 * containing the number of elements.
970 	 */
971 	size_t n_elem = *(size_t *)((char *)val + elem_descr->offset);
972 	size_t i;
973 	int ret;
974 
975 	ret = append_bytes("[", 1, data);
976 	if (ret < 0) {
977 		return ret;
978 	}
979 
980 	/* For nested arrays, skip parent descriptor to get elements */
981 	if (elem_descr->type == JSON_TOK_ARRAY_START) {
982 		elem_descr = elem_descr->array.element_descr;
983 	}
984 
985 	elem_size = get_elem_size(elem_descr);
986 
987 	for (i = 0; i < n_elem; i++) {
988 		/*
989 		 * Though "field" points at the next element in the
990 		 * array which we need to encode, the value in
991 		 * elem_descr->offset is actually the offset of the
992 		 * length field in the "parent" struct containing the
993 		 * array.
994 		 *
995 		 * To patch things up, we lie to encode() about where
996 		 * the field is by exactly the amount it will offset
997 		 * it. This is a size optimization for struct
998 		 * json_obj_descr: the alternative is to keep a
999 		 * separate field next to element_descr which is an
1000 		 * offset to the length field in the parent struct,
1001 		 * but that would add a size_t to every descriptor.
1002 		 */
1003 		ret = encode(elem_descr, (char *)field - elem_descr->offset,
1004 			     append_bytes, data);
1005 		if (ret < 0) {
1006 			return ret;
1007 		}
1008 
1009 		if (i < n_elem - 1) {
1010 			ret = append_bytes(",", 1, data);
1011 			if (ret < 0) {
1012 				return ret;
1013 			}
1014 		}
1015 
1016 		field = (char *)field + elem_size;
1017 	}
1018 
1019 	return append_bytes("]", 1, data);
1020 }
1021 
str_encode(const char ** str,json_append_bytes_t append_bytes,void * data)1022 static int str_encode(const char **str, json_append_bytes_t append_bytes,
1023 		      void *data)
1024 {
1025 	int ret;
1026 
1027 	ret = append_bytes("\"", 1, data);
1028 	if (ret < 0) {
1029 		return ret;
1030 	}
1031 
1032 	ret = json_escape_internal(*str, append_bytes, data);
1033 	if (!ret) {
1034 		return append_bytes("\"", 1, data);
1035 	}
1036 
1037 	return ret;
1038 }
1039 
num_encode(const int32_t * num,json_append_bytes_t append_bytes,void * data)1040 static int num_encode(const int32_t *num, json_append_bytes_t append_bytes,
1041 		      void *data)
1042 {
1043 	char buf[3 * sizeof(int32_t)];
1044 	int ret;
1045 
1046 	ret = snprintk(buf, sizeof(buf), "%d", *num);
1047 	if (ret < 0) {
1048 		return ret;
1049 	}
1050 	if (ret >= (int)sizeof(buf)) {
1051 		return -ENOMEM;
1052 	}
1053 
1054 	return append_bytes(buf, (size_t)ret, data);
1055 }
1056 
int64_encode(const int64_t * num,json_append_bytes_t append_bytes,void * data)1057 static int int64_encode(const int64_t *num, json_append_bytes_t append_bytes,
1058 			void *data)
1059 {
1060 	char buf[sizeof("-9223372036854775808")];
1061 	int ret;
1062 
1063 	ret = snprintk(buf, sizeof(buf), "%" PRId64, *num);
1064 	if (ret < 0) {
1065 		return ret;
1066 	}
1067 	if (ret >= (int)sizeof(buf)) {
1068 		return -ENOMEM;
1069 	}
1070 
1071 	return append_bytes(buf, (size_t)ret, data);
1072 }
1073 
uint64_encode(const uint64_t * num,json_append_bytes_t append_bytes,void * data)1074 static int uint64_encode(const uint64_t *num, json_append_bytes_t append_bytes,
1075 			void *data)
1076 {
1077 	char buf[sizeof("18446744073709551610")];
1078 	int ret;
1079 
1080 	ret = snprintk(buf, sizeof(buf), "%" PRIu64, *num);
1081 	if (ret < 0) {
1082 		return ret;
1083 	}
1084 	if (ret >= (int)sizeof(buf)) {
1085 		return -ENOMEM;
1086 	}
1087 
1088 	return append_bytes(buf, (size_t)ret, data);
1089 }
1090 
float_ascii_encode(struct json_obj_token * num,json_append_bytes_t append_bytes,void * data)1091 static int float_ascii_encode(struct json_obj_token *num, json_append_bytes_t append_bytes,
1092 		      void *data)
1093 {
1094 
1095 	return append_bytes(num->start, num->length, data);
1096 }
1097 
opaque_string_encode(struct json_obj_token * opaque,json_append_bytes_t append_bytes,void * data)1098 static int opaque_string_encode(struct json_obj_token *opaque, json_append_bytes_t append_bytes,
1099 		      void *data)
1100 {
1101 	int ret;
1102 
1103 	ret = append_bytes("\"", 1, data);
1104 	if (ret < 0) {
1105 		return ret;
1106 	}
1107 
1108 	ret = append_bytes(opaque->start, opaque->length, data);
1109 	if (ret < 0) {
1110 		return ret;
1111 	}
1112 
1113 	return append_bytes("\"", 1, data);
1114 }
1115 
encoded_obj_encode(const char ** str,json_append_bytes_t append_bytes,void * data)1116 static int encoded_obj_encode(const char **str, json_append_bytes_t append_bytes, void *data)
1117 {
1118 	size_t len = strlen(*str);
1119 
1120 	return append_bytes(*str, len, data);
1121 }
1122 
bool_encode(const bool * value,json_append_bytes_t append_bytes,void * data)1123 static int bool_encode(const bool *value, json_append_bytes_t append_bytes,
1124 		       void *data)
1125 {
1126 	if (*value) {
1127 		return append_bytes("true", 4, data);
1128 	}
1129 
1130 	return append_bytes("false", 5, data);
1131 }
1132 
encode(const struct json_obj_descr * descr,const void * val,json_append_bytes_t append_bytes,void * data)1133 static int encode(const struct json_obj_descr *descr, const void *val,
1134 		  json_append_bytes_t append_bytes, void *data)
1135 {
1136 	void *ptr = (char *)val + descr->offset;
1137 
1138 	switch (descr->type) {
1139 	case JSON_TOK_FALSE:
1140 	case JSON_TOK_TRUE:
1141 		return bool_encode(ptr, append_bytes, data);
1142 	case JSON_TOK_STRING:
1143 		return str_encode(ptr, append_bytes, data);
1144 	case JSON_TOK_ARRAY_START:
1145 		return arr_encode(descr->array.element_descr, ptr,
1146 				  val, append_bytes, data);
1147 	case JSON_TOK_OBJECT_START:
1148 		return json_obj_encode(descr->object.sub_descr,
1149 				       descr->object.sub_descr_len,
1150 				       ptr, append_bytes, data);
1151 	case JSON_TOK_NUMBER:
1152 		return num_encode(ptr, append_bytes, data);
1153 	case JSON_TOK_INT64:
1154 		return int64_encode(ptr, append_bytes, data);
1155 	case JSON_TOK_UINT64:
1156 		return uint64_encode(ptr, append_bytes, data);
1157 	case JSON_TOK_FLOAT:
1158 		return float_ascii_encode(ptr, append_bytes, data);
1159 	case JSON_TOK_OPAQUE:
1160 		return opaque_string_encode(ptr, append_bytes, data);
1161 	case JSON_TOK_ENCODED_OBJ:
1162 		return encoded_obj_encode(ptr, append_bytes, data);
1163 	default:
1164 		return -EINVAL;
1165 	}
1166 }
1167 
json_obj_encode(const struct json_obj_descr * descr,size_t descr_len,const void * val,json_append_bytes_t append_bytes,void * data)1168 int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
1169 		    const void *val, json_append_bytes_t append_bytes,
1170 		    void *data)
1171 {
1172 	size_t i;
1173 	int ret;
1174 
1175 	ret = append_bytes("{", 1, data);
1176 	if (ret < 0) {
1177 		return ret;
1178 	}
1179 
1180 	for (i = 0; i < descr_len; i++) {
1181 		ret = str_encode((const char **)&descr[i].field_name,
1182 				 append_bytes, data);
1183 		if (ret < 0) {
1184 			return ret;
1185 		}
1186 
1187 		ret = append_bytes(":", 1, data);
1188 		if (ret < 0) {
1189 			return ret;
1190 		}
1191 
1192 		ret = encode(&descr[i], val, append_bytes, data);
1193 		if (ret < 0) {
1194 			return ret;
1195 		}
1196 
1197 		if (i < descr_len - 1) {
1198 			ret = append_bytes(",", 1, data);
1199 			if (ret < 0) {
1200 				return ret;
1201 			}
1202 		}
1203 	}
1204 
1205 	return append_bytes("}", 1, data);
1206 }
1207 
json_arr_encode(const struct json_obj_descr * descr,const void * val,json_append_bytes_t append_bytes,void * data)1208 int json_arr_encode(const struct json_obj_descr *descr, const void *val,
1209 		    json_append_bytes_t append_bytes, void *data)
1210 {
1211 	void *ptr = (char *)val + descr->offset;
1212 
1213 	return arr_encode(descr->array.element_descr, ptr, val, append_bytes,
1214 			  data);
1215 }
1216 
1217 struct appender {
1218 	char *buffer;
1219 	size_t used;
1220 	size_t size;
1221 };
1222 
append_bytes_to_buf(const char * bytes,size_t len,void * data)1223 static int append_bytes_to_buf(const char *bytes, size_t len, void *data)
1224 {
1225 	struct appender *appender = data;
1226 
1227 	if (len >= appender->size - appender->used) {
1228 		return -ENOMEM;
1229 	}
1230 
1231 	memcpy(appender->buffer + appender->used, bytes, len);
1232 	appender->used += len;
1233 	appender->buffer[appender->used] = '\0';
1234 
1235 	return 0;
1236 }
1237 
json_obj_encode_buf(const struct json_obj_descr * descr,size_t descr_len,const void * val,char * buffer,size_t buf_size)1238 int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
1239 			const void *val, char *buffer, size_t buf_size)
1240 {
1241 	struct appender appender = { .buffer = buffer, .size = buf_size };
1242 
1243 	return json_obj_encode(descr, descr_len, val, append_bytes_to_buf,
1244 			       &appender);
1245 }
1246 
json_arr_encode_buf(const struct json_obj_descr * descr,const void * val,char * buffer,size_t buf_size)1247 int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
1248 			char *buffer, size_t buf_size)
1249 {
1250 	struct appender appender = { .buffer = buffer, .size = buf_size };
1251 
1252 	return json_arr_encode(descr, val, append_bytes_to_buf, &appender);
1253 }
1254 
measure_bytes(const char * bytes,size_t len,void * data)1255 static int measure_bytes(const char *bytes, size_t len, void *data)
1256 {
1257 	ssize_t *total = data;
1258 
1259 	*total += (ssize_t)len;
1260 
1261 	ARG_UNUSED(bytes);
1262 
1263 	return 0;
1264 }
1265 
json_calc_encoded_len(const struct json_obj_descr * descr,size_t descr_len,const void * val)1266 ssize_t json_calc_encoded_len(const struct json_obj_descr *descr,
1267 			      size_t descr_len, const void *val)
1268 {
1269 	ssize_t total = 0;
1270 	int ret;
1271 
1272 	ret = json_obj_encode(descr, descr_len, val, measure_bytes, &total);
1273 	if (ret < 0) {
1274 		return ret;
1275 	}
1276 
1277 	return total;
1278 }
1279 
json_calc_encoded_arr_len(const struct json_obj_descr * descr,const void * val)1280 ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr,
1281 				  const void *val)
1282 {
1283 	ssize_t total = 0;
1284 	int ret;
1285 
1286 	ret = json_arr_encode(descr, val, measure_bytes, &total);
1287 	if (ret < 0) {
1288 		return ret;
1289 	}
1290 
1291 	return total;
1292 }
1293