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_FLOAT:
312 	case JSON_TOK_OPAQUE:
313 	case JSON_TOK_OBJ_ARRAY:
314 	case JSON_TOK_TRUE:
315 	case JSON_TOK_FALSE:
316 		return 0;
317 	default:
318 		return -EINVAL;
319 	}
320 }
321 
obj_next(struct json_obj * json,struct json_obj_key_value * kv)322 static int obj_next(struct json_obj *json,
323 		    struct json_obj_key_value *kv)
324 {
325 	struct json_token tok;
326 
327 	if (!lexer_next(&json->lex, &tok)) {
328 		return -EINVAL;
329 	}
330 
331 	/* Match end of object or next key */
332 	switch (tok.type) {
333 	case JSON_TOK_OBJECT_END:
334 		kv->key = NULL;
335 		kv->key_len = 0;
336 		kv->value = tok;
337 
338 		return 0;
339 	case JSON_TOK_COMMA:
340 		if (!lexer_next(&json->lex, &tok)) {
341 			return -EINVAL;
342 		}
343 
344 		if (tok.type != JSON_TOK_STRING) {
345 			return -EINVAL;
346 		}
347 
348 		__fallthrough;
349 	case JSON_TOK_STRING:
350 		kv->key = tok.start;
351 		kv->key_len = (size_t)(tok.end - tok.start);
352 		break;
353 	default:
354 		return -EINVAL;
355 	}
356 
357 	/* Match : after key */
358 	if (!lexer_next(&json->lex, &tok)) {
359 		return -EINVAL;
360 	}
361 
362 	if (tok.type != JSON_TOK_COLON) {
363 		return -EINVAL;
364 	}
365 
366 	/* Match value */
367 	if (!lexer_next(&json->lex, &kv->value)) {
368 		return -EINVAL;
369 	}
370 
371 	return element_token(kv->value.type);
372 }
373 
arr_next(struct json_obj * json,struct json_token * value)374 static int arr_next(struct json_obj *json, struct json_token *value)
375 {
376 	if (!lexer_next(&json->lex, value)) {
377 		return -EINVAL;
378 	}
379 
380 	if (value->type == JSON_TOK_ARRAY_END) {
381 		return 0;
382 	}
383 
384 	if (value->type == JSON_TOK_COMMA) {
385 		if (!lexer_next(&json->lex, value)) {
386 			return -EINVAL;
387 		}
388 	}
389 
390 	return element_token(value->type);
391 }
392 
skip_field(struct json_obj * obj,struct json_obj_key_value * kv)393 static int skip_field(struct json_obj *obj, struct json_obj_key_value *kv)
394 {
395 	int field_count = 1;
396 
397 	if (kv->value.type == JSON_TOK_OBJECT_START ||
398 	    kv->value.type == JSON_TOK_ARRAY_START) {
399 		while (field_count > 0 && lexer_next(&obj->lex, &kv->value)) {
400 			switch (kv->value.type) {
401 			case JSON_TOK_OBJECT_START:
402 			case JSON_TOK_ARRAY_START:
403 				field_count++;
404 				break;
405 			case JSON_TOK_OBJECT_END:
406 			case JSON_TOK_ARRAY_END:
407 				field_count--;
408 				break;
409 			case JSON_TOK_ERROR:
410 				return -EINVAL;
411 			default:
412 				break;
413 			}
414 		}
415 	}
416 
417 	return 0;
418 }
419 
decode_num(const struct json_token * token,int32_t * num)420 static int decode_num(const struct json_token *token, int32_t *num)
421 {
422 	/* FIXME: strtod() is not available in newlib/minimal libc,
423 	 * so using strtol() here.
424 	 */
425 	char *endptr;
426 	char prev_end;
427 
428 	prev_end = *token->end;
429 	*token->end = '\0';
430 
431 	errno = 0;
432 	*num = strtol(token->start, &endptr, 10);
433 
434 	*token->end = prev_end;
435 
436 	if (errno != 0) {
437 		return -errno;
438 	}
439 
440 	if (endptr != token->end) {
441 		return -EINVAL;
442 	}
443 
444 	return 0;
445 }
446 
equivalent_types(enum json_tokens type1,enum json_tokens type2)447 static bool equivalent_types(enum json_tokens type1, enum json_tokens type2)
448 {
449 	if (type1 == JSON_TOK_TRUE || type1 == JSON_TOK_FALSE) {
450 		return type2 == JSON_TOK_TRUE || type2 == JSON_TOK_FALSE;
451 	}
452 
453 	if (type1 == JSON_TOK_NUMBER && type2 == JSON_TOK_FLOAT) {
454 		return true;
455 	}
456 
457 	if (type1 == JSON_TOK_STRING && type2 == JSON_TOK_OPAQUE) {
458 		return true;
459 	}
460 
461 	if (type1 == JSON_TOK_ARRAY_START && type2 == JSON_TOK_OBJ_ARRAY) {
462 		return true;
463 	}
464 
465 	return type1 == type2;
466 }
467 
468 static int64_t obj_parse(struct json_obj *obj,
469 			 const struct json_obj_descr *descr, size_t descr_len,
470 			 void *val);
471 static int arr_parse(struct json_obj *obj,
472 		     const struct json_obj_descr *elem_descr,
473 		     size_t max_elements, void *field, void *val);
474 
475 static int arr_data_parse(struct json_obj *obj, struct json_obj_token *val);
476 
decode_value(struct json_obj * obj,const struct json_obj_descr * descr,struct json_token * value,void * field,void * val)477 static int64_t decode_value(struct json_obj *obj,
478 			    const struct json_obj_descr *descr,
479 			    struct json_token *value, void *field, void *val)
480 {
481 
482 	if (!equivalent_types(value->type, descr->type)) {
483 		return -EINVAL;
484 	}
485 
486 	switch (descr->type) {
487 	case JSON_TOK_OBJECT_START:
488 		return obj_parse(obj, descr->object.sub_descr,
489 				 descr->object.sub_descr_len,
490 				 field);
491 	case JSON_TOK_ARRAY_START:
492 		return arr_parse(obj, descr->array.element_descr,
493 				 descr->array.n_elements, field, val);
494 	case JSON_TOK_OBJ_ARRAY: {
495 		struct json_obj_token *obj_token = field;
496 
497 		obj_token->start = value->start;
498 		return arr_data_parse(obj, obj_token);
499 	}
500 
501 	case JSON_TOK_FALSE:
502 	case JSON_TOK_TRUE: {
503 		bool *v = field;
504 
505 		*v = value->type == JSON_TOK_TRUE;
506 
507 		return 0;
508 	}
509 	case JSON_TOK_NUMBER: {
510 		int32_t *num = field;
511 
512 		return decode_num(value, num);
513 	}
514 	case JSON_TOK_OPAQUE:
515 	case JSON_TOK_FLOAT: {
516 		struct json_obj_token *obj_token = field;
517 
518 		obj_token->start = value->start;
519 		obj_token->length = value->end - value->start;
520 		return 0;
521 	}
522 	case JSON_TOK_STRING: {
523 		char **str = field;
524 
525 		*value->end = '\0';
526 		*str = value->start;
527 
528 		return 0;
529 	}
530 	default:
531 		return -EINVAL;
532 	}
533 }
534 
get_elem_size(const struct json_obj_descr * descr)535 static ptrdiff_t get_elem_size(const struct json_obj_descr *descr)
536 {
537 	switch (descr->type) {
538 	case JSON_TOK_NUMBER:
539 		return sizeof(int32_t);
540 	case JSON_TOK_OPAQUE:
541 	case JSON_TOK_FLOAT:
542 	case JSON_TOK_OBJ_ARRAY:
543 		return sizeof(struct json_obj_token);
544 	case JSON_TOK_STRING:
545 		return sizeof(char *);
546 	case JSON_TOK_TRUE:
547 	case JSON_TOK_FALSE:
548 		return sizeof(bool);
549 	case JSON_TOK_ARRAY_START: {
550 		ptrdiff_t size;
551 
552 		size = descr->array.n_elements * get_elem_size(descr->array.element_descr);
553 		/* Consider additional item count field for array objects */
554 		if (descr->field_name_len > 0) {
555 			size = size + sizeof(size_t);
556 		}
557 
558 		return size;
559 	}
560 	case JSON_TOK_OBJECT_START: {
561 		ptrdiff_t total = 0;
562 		uint32_t align_shift = 0;
563 		size_t i;
564 
565 		for (i = 0; i < descr->object.sub_descr_len; i++) {
566 			total += get_elem_size(&descr->object.sub_descr[i]);
567 
568 			if (descr->object.sub_descr[i].align_shift > align_shift) {
569 				align_shift = descr->object.sub_descr[i].align_shift;
570 			}
571 		}
572 
573 		return ROUND_UP(total, 1 << align_shift);
574 	}
575 	default:
576 		return -EINVAL;
577 	}
578 }
579 
arr_parse(struct json_obj * obj,const struct json_obj_descr * elem_descr,size_t max_elements,void * field,void * val)580 static int arr_parse(struct json_obj *obj,
581 		     const struct json_obj_descr *elem_descr,
582 		     size_t max_elements, void *field, void *val)
583 {
584 	void *value = val;
585 	size_t *elements = (size_t *)((char *)value + elem_descr->offset);
586 	ptrdiff_t elem_size;
587 	void *last_elem;
588 	struct json_token tok;
589 
590 	/* For nested arrays, skip parent descriptor to get elements */
591 	if (elem_descr->type == JSON_TOK_ARRAY_START) {
592 		elem_descr = elem_descr->array.element_descr;
593 	}
594 
595 	*elements = 0;
596 	elem_size = get_elem_size(elem_descr);
597 	last_elem = (char *)field + elem_size * max_elements;
598 
599 	__ASSERT_NO_MSG(elem_size > 0);
600 
601 	while (!arr_next(obj, &tok)) {
602 		if (tok.type == JSON_TOK_ARRAY_END) {
603 			return 0;
604 		}
605 
606 		if (field == last_elem) {
607 			return -ENOSPC;
608 		}
609 
610 		/* For nested arrays, update value to current field,
611 		 * so it matches descriptor's offset to length field
612 		 */
613 		if (elem_descr->type == JSON_TOK_ARRAY_START) {
614 			value = field;
615 		}
616 
617 		if (decode_value(obj, elem_descr, &tok, field, value) < 0) {
618 			return -EINVAL;
619 		}
620 
621 		(*elements)++;
622 		field = (char *)field + elem_size;
623 	}
624 
625 	return -EINVAL;
626 }
627 
arr_data_parse(struct json_obj * obj,struct json_obj_token * val)628 static int arr_data_parse(struct json_obj *obj, struct json_obj_token *val)
629 {
630 	bool string_state = false;
631 	int array_in_array = 1;
632 
633 	/* Init length to zero */
634 	val->length = 0;
635 
636 	while (obj->lex.pos != obj->lex.end) {
637 		if (string_state) {
638 			if (*obj->lex.pos == JSON_TOK_STRING) {
639 				string_state = false;
640 			}
641 		} else {
642 			if (*obj->lex.pos == JSON_TOK_ARRAY_END) {
643 				array_in_array--;
644 				if (array_in_array == 0) {
645 					/* Set array data length + 1 object end */
646 					val->length = obj->lex.pos - val->start + 1;
647 					/* Init Lexer that Object Parse can be finished properly */
648 					obj->lex.state = lexer_json;
649 					/* Move position to before array end */
650 					obj->lex.pos--;
651 					obj->lex.tok.end = obj->lex.pos;
652 					obj->lex.tok.start = val->start;
653 					obj->lex.tok.type = JSON_TOK_NONE;
654 					return 0;
655 				}
656 			} else if (*obj->lex.pos == JSON_TOK_STRING) {
657 				string_state = true;
658 			} else if (*obj->lex.pos == JSON_TOK_ARRAY_START) {
659 				/* arrary in array update structure count */
660 				array_in_array++;
661 			}
662 		}
663 		obj->lex.pos++;
664 	}
665 
666 	return -EINVAL;
667 }
668 
obj_parse(struct json_obj * obj,const struct json_obj_descr * descr,size_t descr_len,void * val)669 static int64_t obj_parse(struct json_obj *obj, const struct json_obj_descr *descr,
670 			 size_t descr_len, void *val)
671 {
672 	struct json_obj_key_value kv;
673 	int64_t decoded_fields = 0;
674 	size_t i;
675 	int ret;
676 
677 	while (!obj_next(obj, &kv)) {
678 		if (kv.value.type == JSON_TOK_OBJECT_END) {
679 			return decoded_fields;
680 		}
681 
682 		for (i = 0; i < descr_len; i++) {
683 			void *decode_field = (char *)val + descr[i].offset;
684 
685 			/* Field has been decoded already, skip */
686 			if (decoded_fields & ((int64_t)1 << i)) {
687 				continue;
688 			}
689 
690 			/* Check if it's the i-th field */
691 			if (kv.key_len != descr[i].field_name_len) {
692 				continue;
693 			}
694 
695 			if (memcmp(kv.key, descr[i].field_name,
696 				   descr[i].field_name_len)) {
697 				continue;
698 			}
699 
700 			/* Store the decoded value */
701 			ret = decode_value(obj, &descr[i], &kv.value,
702 					   decode_field, val);
703 			if (ret < 0) {
704 				return ret;
705 			}
706 
707 			decoded_fields |= (int64_t)1<<i;
708 			break;
709 		}
710 
711 		/* Skip field, if no descriptor was found */
712 		if (i >= descr_len) {
713 			ret = skip_field(obj, &kv);
714 			if (ret < 0) {
715 				return ret;
716 			}
717 		}
718 	}
719 
720 	return -EINVAL;
721 }
722 
json_obj_parse(char * payload,size_t len,const struct json_obj_descr * descr,size_t descr_len,void * val)723 int64_t json_obj_parse(char *payload, size_t len,
724 		       const struct json_obj_descr *descr, size_t descr_len,
725 		       void *val)
726 {
727 	struct json_obj obj;
728 	int64_t ret;
729 
730 	__ASSERT_NO_MSG(descr_len < (sizeof(ret) * CHAR_BIT - 1));
731 
732 	ret = obj_init(&obj, payload, len);
733 	if (ret < 0) {
734 		return ret;
735 	}
736 
737 	return obj_parse(&obj, descr, descr_len, val);
738 }
739 
json_arr_parse(char * payload,size_t len,const struct json_obj_descr * descr,void * val)740 int json_arr_parse(char *payload, size_t len,
741 		   const struct json_obj_descr *descr, void *val)
742 {
743 	struct json_obj arr;
744 	int ret;
745 
746 	ret = arr_init(&arr, payload, len);
747 	if (ret < 0) {
748 		return ret;
749 	}
750 
751 	void *ptr = (char *)val + descr->offset;
752 
753 	return arr_parse(&arr, descr->array.element_descr,
754 			 descr->array.n_elements, ptr, val);
755 }
756 
757 
json_arr_separate_object_parse_init(struct json_obj * json,char * payload,size_t len)758 int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len)
759 {
760 	return arr_init(json, payload, len);
761 }
762 
json_arr_separate_parse_object(struct json_obj * json,const struct json_obj_descr * descr,size_t descr_len,void * val)763 int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr,
764 			  size_t descr_len, void *val)
765 {
766 	struct json_token tok;
767 
768 	if (!lexer_next(&json->lex, &tok)) {
769 		return -EINVAL;
770 	}
771 
772 	if (tok.type == JSON_TOK_ARRAY_END) {
773 		return 0;
774 	} else if (tok.type == JSON_TOK_COMMA) {
775 		if (!lexer_next(&json->lex, &tok)) {
776 			return -EINVAL;
777 		}
778 	}
779 
780 	if (tok.type != JSON_TOK_OBJECT_START) {
781 		return -EINVAL;
782 	}
783 
784 	return obj_parse(json, descr, descr_len, val);
785 }
786 
escape_as(char chr)787 static char escape_as(char chr)
788 {
789 	switch (chr) {
790 	case '"':
791 		return '"';
792 	case '\\':
793 		return '\\';
794 	case '\b':
795 		return 'b';
796 	case '\f':
797 		return 'f';
798 	case '\n':
799 		return 'n';
800 	case '\r':
801 		return 'r';
802 	case '\t':
803 		return 't';
804 	}
805 
806 	return 0;
807 }
808 
json_escape_internal(const char * str,json_append_bytes_t append_bytes,void * data)809 static int json_escape_internal(const char *str,
810 				json_append_bytes_t append_bytes,
811 				void *data)
812 {
813 	const char *cur;
814 	int ret = 0;
815 
816 	for (cur = str; ret == 0 && *cur; cur++) {
817 		char escaped = escape_as(*cur);
818 
819 		if (escaped) {
820 			char bytes[2] = { '\\', escaped };
821 
822 			ret = append_bytes(bytes, 2, data);
823 		} else {
824 			ret = append_bytes(cur, 1, data);
825 		}
826 	}
827 
828 	return ret;
829 }
830 
json_calc_escaped_len(const char * str,size_t len)831 size_t json_calc_escaped_len(const char *str, size_t len)
832 {
833 	size_t escaped_len = len;
834 	size_t pos;
835 
836 	for (pos = 0; pos < len; pos++) {
837 		if (escape_as(str[pos])) {
838 			escaped_len++;
839 		}
840 	}
841 
842 	return escaped_len;
843 }
844 
json_escape(char * str,size_t * len,size_t buf_size)845 ssize_t json_escape(char *str, size_t *len, size_t buf_size)
846 {
847 	char *next; /* Points after next character to escape. */
848 	char *dest; /* Points after next place to write escaped character. */
849 	size_t escaped_len = json_calc_escaped_len(str, *len);
850 
851 	if (escaped_len == *len) {
852 		/*
853 		 * If no escape is necessary, there is nothing to do.
854 		 */
855 		return 0;
856 	}
857 
858 	if (escaped_len >= buf_size) {
859 		return -ENOMEM;
860 	}
861 
862 	/*
863 	 * By walking backwards in the buffer from the end positions
864 	 * of both the original and escaped strings, we avoid using
865 	 * extra space. Characters in the original string are
866 	 * overwritten only after they have already been escaped.
867 	 */
868 	str[escaped_len] = '\0';
869 	for (next = &str[*len], dest = &str[escaped_len]; next != str;) {
870 		char next_c = *(--next);
871 		char escape = escape_as(next_c);
872 
873 		if (escape) {
874 			*(--dest) = escape;
875 			*(--dest) = '\\';
876 		} else {
877 			*(--dest) = next_c;
878 		}
879 	}
880 	*len = escaped_len;
881 
882 	return 0;
883 }
884 
885 static int encode(const struct json_obj_descr *descr, const void *val,
886 		  json_append_bytes_t append_bytes, void *data);
887 
arr_encode(const struct json_obj_descr * elem_descr,const void * field,const void * val,json_append_bytes_t append_bytes,void * data)888 static int arr_encode(const struct json_obj_descr *elem_descr,
889 		      const void *field, const void *val,
890 		      json_append_bytes_t append_bytes, void *data)
891 {
892 	ptrdiff_t elem_size;
893 	/*
894 	 * NOTE: Since an element descriptor's offset isn't meaningful
895 	 * (array elements occur at multiple offsets in `val'), we use
896 	 * its space in elem_descr to store the offset to the field
897 	 * containing the number of elements.
898 	 */
899 	size_t n_elem = *(size_t *)((char *)val + elem_descr->offset);
900 	size_t i;
901 	int ret;
902 
903 	ret = append_bytes("[", 1, data);
904 	if (ret < 0) {
905 		return ret;
906 	}
907 
908 	/* For nested arrays, skip parent descriptor to get elements */
909 	if (elem_descr->type == JSON_TOK_ARRAY_START) {
910 		elem_descr = elem_descr->array.element_descr;
911 	}
912 
913 	elem_size = get_elem_size(elem_descr);
914 
915 	for (i = 0; i < n_elem; i++) {
916 		/*
917 		 * Though "field" points at the next element in the
918 		 * array which we need to encode, the value in
919 		 * elem_descr->offset is actually the offset of the
920 		 * length field in the "parent" struct containing the
921 		 * array.
922 		 *
923 		 * To patch things up, we lie to encode() about where
924 		 * the field is by exactly the amount it will offset
925 		 * it. This is a size optimization for struct
926 		 * json_obj_descr: the alternative is to keep a
927 		 * separate field next to element_descr which is an
928 		 * offset to the length field in the parent struct,
929 		 * but that would add a size_t to every descriptor.
930 		 */
931 		ret = encode(elem_descr, (char *)field - elem_descr->offset,
932 			     append_bytes, data);
933 		if (ret < 0) {
934 			return ret;
935 		}
936 
937 		if (i < n_elem - 1) {
938 			ret = append_bytes(",", 1, data);
939 			if (ret < 0) {
940 				return ret;
941 			}
942 		}
943 
944 		field = (char *)field + elem_size;
945 	}
946 
947 	return append_bytes("]", 1, data);
948 }
949 
str_encode(const char ** str,json_append_bytes_t append_bytes,void * data)950 static int str_encode(const char **str, json_append_bytes_t append_bytes,
951 		      void *data)
952 {
953 	int ret;
954 
955 	ret = append_bytes("\"", 1, data);
956 	if (ret < 0) {
957 		return ret;
958 	}
959 
960 	ret = json_escape_internal(*str, append_bytes, data);
961 	if (!ret) {
962 		return append_bytes("\"", 1, data);
963 	}
964 
965 	return ret;
966 }
967 
num_encode(const int32_t * num,json_append_bytes_t append_bytes,void * data)968 static int num_encode(const int32_t *num, json_append_bytes_t append_bytes,
969 		      void *data)
970 {
971 	char buf[3 * sizeof(int32_t)];
972 	int ret;
973 
974 	ret = snprintk(buf, sizeof(buf), "%d", *num);
975 	if (ret < 0) {
976 		return ret;
977 	}
978 	if (ret >= (int)sizeof(buf)) {
979 		return -ENOMEM;
980 	}
981 
982 	return append_bytes(buf, (size_t)ret, data);
983 }
984 
float_ascii_encode(struct json_obj_token * num,json_append_bytes_t append_bytes,void * data)985 static int float_ascii_encode(struct json_obj_token *num, json_append_bytes_t append_bytes,
986 		      void *data)
987 {
988 
989 	return append_bytes(num->start, num->length, data);
990 }
991 
opaque_string_encode(struct json_obj_token * opaque,json_append_bytes_t append_bytes,void * data)992 static int opaque_string_encode(struct json_obj_token *opaque, json_append_bytes_t append_bytes,
993 		      void *data)
994 {
995 	int ret;
996 
997 	ret = append_bytes("\"", 1, data);
998 	if (ret < 0) {
999 		return ret;
1000 	}
1001 
1002 	ret = append_bytes(opaque->start, opaque->length, data);
1003 	if (ret < 0) {
1004 		return ret;
1005 	}
1006 
1007 	return append_bytes("\"", 1, data);
1008 }
1009 
encoded_obj_encode(const char ** str,json_append_bytes_t append_bytes,void * data)1010 static int encoded_obj_encode(const char **str, json_append_bytes_t append_bytes, void *data)
1011 {
1012 	size_t len = strlen(*str);
1013 
1014 	return append_bytes(*str, len, data);
1015 }
1016 
bool_encode(const bool * value,json_append_bytes_t append_bytes,void * data)1017 static int bool_encode(const bool *value, json_append_bytes_t append_bytes,
1018 		       void *data)
1019 {
1020 	if (*value) {
1021 		return append_bytes("true", 4, data);
1022 	}
1023 
1024 	return append_bytes("false", 5, data);
1025 }
1026 
encode(const struct json_obj_descr * descr,const void * val,json_append_bytes_t append_bytes,void * data)1027 static int encode(const struct json_obj_descr *descr, const void *val,
1028 		  json_append_bytes_t append_bytes, void *data)
1029 {
1030 	void *ptr = (char *)val + descr->offset;
1031 
1032 	switch (descr->type) {
1033 	case JSON_TOK_FALSE:
1034 	case JSON_TOK_TRUE:
1035 		return bool_encode(ptr, append_bytes, data);
1036 	case JSON_TOK_STRING:
1037 		return str_encode(ptr, append_bytes, data);
1038 	case JSON_TOK_ARRAY_START:
1039 		return arr_encode(descr->array.element_descr, ptr,
1040 				  val, append_bytes, data);
1041 	case JSON_TOK_OBJECT_START:
1042 		return json_obj_encode(descr->object.sub_descr,
1043 				       descr->object.sub_descr_len,
1044 				       ptr, append_bytes, data);
1045 	case JSON_TOK_NUMBER:
1046 		return num_encode(ptr, append_bytes, data);
1047 	case JSON_TOK_FLOAT:
1048 		return float_ascii_encode(ptr, append_bytes, data);
1049 	case JSON_TOK_OPAQUE:
1050 		return opaque_string_encode(ptr, append_bytes, data);
1051 	case JSON_TOK_ENCODED_OBJ:
1052 		return encoded_obj_encode(ptr, append_bytes, data);
1053 	default:
1054 		return -EINVAL;
1055 	}
1056 }
1057 
json_obj_encode(const struct json_obj_descr * descr,size_t descr_len,const void * val,json_append_bytes_t append_bytes,void * data)1058 int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
1059 		    const void *val, json_append_bytes_t append_bytes,
1060 		    void *data)
1061 {
1062 	size_t i;
1063 	int ret;
1064 
1065 	ret = append_bytes("{", 1, data);
1066 	if (ret < 0) {
1067 		return ret;
1068 	}
1069 
1070 	for (i = 0; i < descr_len; i++) {
1071 		ret = str_encode((const char **)&descr[i].field_name,
1072 				 append_bytes, data);
1073 		if (ret < 0) {
1074 			return ret;
1075 		}
1076 
1077 		ret = append_bytes(":", 1, data);
1078 		if (ret < 0) {
1079 			return ret;
1080 		}
1081 
1082 		ret = encode(&descr[i], val, append_bytes, data);
1083 		if (ret < 0) {
1084 			return ret;
1085 		}
1086 
1087 		if (i < descr_len - 1) {
1088 			ret = append_bytes(",", 1, data);
1089 			if (ret < 0) {
1090 				return ret;
1091 			}
1092 		}
1093 	}
1094 
1095 	return append_bytes("}", 1, data);
1096 }
1097 
json_arr_encode(const struct json_obj_descr * descr,const void * val,json_append_bytes_t append_bytes,void * data)1098 int json_arr_encode(const struct json_obj_descr *descr, const void *val,
1099 		    json_append_bytes_t append_bytes, void *data)
1100 {
1101 	void *ptr = (char *)val + descr->offset;
1102 
1103 	return arr_encode(descr->array.element_descr, ptr, val, append_bytes,
1104 			  data);
1105 }
1106 
1107 struct appender {
1108 	char *buffer;
1109 	size_t used;
1110 	size_t size;
1111 };
1112 
append_bytes_to_buf(const char * bytes,size_t len,void * data)1113 static int append_bytes_to_buf(const char *bytes, size_t len, void *data)
1114 {
1115 	struct appender *appender = data;
1116 
1117 	if (len >= appender->size - appender->used) {
1118 		return -ENOMEM;
1119 	}
1120 
1121 	memcpy(appender->buffer + appender->used, bytes, len);
1122 	appender->used += len;
1123 	appender->buffer[appender->used] = '\0';
1124 
1125 	return 0;
1126 }
1127 
json_obj_encode_buf(const struct json_obj_descr * descr,size_t descr_len,const void * val,char * buffer,size_t buf_size)1128 int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
1129 			const void *val, char *buffer, size_t buf_size)
1130 {
1131 	struct appender appender = { .buffer = buffer, .size = buf_size };
1132 
1133 	return json_obj_encode(descr, descr_len, val, append_bytes_to_buf,
1134 			       &appender);
1135 }
1136 
json_arr_encode_buf(const struct json_obj_descr * descr,const void * val,char * buffer,size_t buf_size)1137 int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
1138 			char *buffer, size_t buf_size)
1139 {
1140 	struct appender appender = { .buffer = buffer, .size = buf_size };
1141 
1142 	return json_arr_encode(descr, val, append_bytes_to_buf, &appender);
1143 }
1144 
measure_bytes(const char * bytes,size_t len,void * data)1145 static int measure_bytes(const char *bytes, size_t len, void *data)
1146 {
1147 	ssize_t *total = data;
1148 
1149 	*total += (ssize_t)len;
1150 
1151 	ARG_UNUSED(bytes);
1152 
1153 	return 0;
1154 }
1155 
json_calc_encoded_len(const struct json_obj_descr * descr,size_t descr_len,const void * val)1156 ssize_t json_calc_encoded_len(const struct json_obj_descr *descr,
1157 			      size_t descr_len, const void *val)
1158 {
1159 	ssize_t total = 0;
1160 	int ret;
1161 
1162 	ret = json_obj_encode(descr, descr_len, val, measure_bytes, &total);
1163 	if (ret < 0) {
1164 		return ret;
1165 	}
1166 
1167 	return total;
1168 }
1169 
json_calc_encoded_arr_len(const struct json_obj_descr * descr,const void * val)1170 ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr,
1171 				  const void *val)
1172 {
1173 	ssize_t total = 0;
1174 	int ret;
1175 
1176 	ret = json_arr_encode(descr, val, measure_bytes, &total);
1177 	if (ret < 0) {
1178 		return ret;
1179 	}
1180 
1181 	return total;
1182 }
1183