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 		size_t i;
563 
564 		for (i = 0; i < descr->object.sub_descr_len; i++) {
565 			total += get_elem_size(&descr->object.sub_descr[i]);
566 		}
567 
568 		return ROUND_UP(total, 1 << descr->align_shift);
569 	}
570 	default:
571 		return -EINVAL;
572 	}
573 }
574 
arr_parse(struct json_obj * obj,const struct json_obj_descr * elem_descr,size_t max_elements,void * field,void * val)575 static int arr_parse(struct json_obj *obj,
576 		     const struct json_obj_descr *elem_descr,
577 		     size_t max_elements, void *field, void *val)
578 {
579 	void *value = val;
580 	size_t *elements = (size_t *)((char *)value + elem_descr->offset);
581 	ptrdiff_t elem_size;
582 	void *last_elem;
583 	struct json_token tok;
584 
585 	/* For nested arrays, skip parent descriptor to get elements */
586 	if (elem_descr->type == JSON_TOK_ARRAY_START) {
587 		elem_descr = elem_descr->array.element_descr;
588 	}
589 
590 	*elements = 0;
591 	elem_size = get_elem_size(elem_descr);
592 	last_elem = (char *)field + elem_size * max_elements;
593 
594 	__ASSERT_NO_MSG(elem_size > 0);
595 
596 	while (!arr_next(obj, &tok)) {
597 		if (tok.type == JSON_TOK_ARRAY_END) {
598 			return 0;
599 		}
600 
601 		if (field == last_elem) {
602 			return -ENOSPC;
603 		}
604 
605 		/* For nested arrays, update value to current field,
606 		 * so it matches descriptor's offset to length field
607 		 */
608 		if (elem_descr->type == JSON_TOK_ARRAY_START) {
609 			value = field;
610 		}
611 
612 		if (decode_value(obj, elem_descr, &tok, field, value) < 0) {
613 			return -EINVAL;
614 		}
615 
616 		(*elements)++;
617 		field = (char *)field + elem_size;
618 	}
619 
620 	return -EINVAL;
621 }
622 
arr_data_parse(struct json_obj * obj,struct json_obj_token * val)623 static int arr_data_parse(struct json_obj *obj, struct json_obj_token *val)
624 {
625 	bool string_state = false;
626 	int array_in_array = 1;
627 
628 	/* Init length to zero */
629 	val->length = 0;
630 
631 	while (obj->lex.pos != obj->lex.end) {
632 		if (string_state) {
633 			if (*obj->lex.pos == JSON_TOK_STRING) {
634 				string_state = false;
635 			}
636 		} else {
637 			if (*obj->lex.pos == JSON_TOK_ARRAY_END) {
638 				array_in_array--;
639 				if (array_in_array == 0) {
640 					/* Set array data length + 1 object end */
641 					val->length = obj->lex.pos - val->start + 1;
642 					/* Init Lexer that Object Parse can be finished properly */
643 					obj->lex.state = lexer_json;
644 					/* Move position to before array end */
645 					obj->lex.pos--;
646 					obj->lex.tok.end = obj->lex.pos;
647 					obj->lex.tok.start = val->start;
648 					obj->lex.tok.type = JSON_TOK_NONE;
649 					return 0;
650 				}
651 			} else if (*obj->lex.pos == JSON_TOK_STRING) {
652 				string_state = true;
653 			} else if (*obj->lex.pos == JSON_TOK_ARRAY_START) {
654 				/* arrary in array update structure count */
655 				array_in_array++;
656 			}
657 		}
658 		obj->lex.pos++;
659 	}
660 
661 	return -EINVAL;
662 }
663 
obj_parse(struct json_obj * obj,const struct json_obj_descr * descr,size_t descr_len,void * val)664 static int64_t obj_parse(struct json_obj *obj, const struct json_obj_descr *descr,
665 			 size_t descr_len, void *val)
666 {
667 	struct json_obj_key_value kv;
668 	int64_t decoded_fields = 0;
669 	size_t i;
670 	int ret;
671 
672 	while (!obj_next(obj, &kv)) {
673 		if (kv.value.type == JSON_TOK_OBJECT_END) {
674 			return decoded_fields;
675 		}
676 
677 		for (i = 0; i < descr_len; i++) {
678 			void *decode_field = (char *)val + descr[i].offset;
679 
680 			/* Field has been decoded already, skip */
681 			if (decoded_fields & ((int64_t)1 << i)) {
682 				continue;
683 			}
684 
685 			/* Check if it's the i-th field */
686 			if (kv.key_len != descr[i].field_name_len) {
687 				continue;
688 			}
689 
690 			if (memcmp(kv.key, descr[i].field_name,
691 				   descr[i].field_name_len)) {
692 				continue;
693 			}
694 
695 			/* Store the decoded value */
696 			ret = decode_value(obj, &descr[i], &kv.value,
697 					   decode_field, val);
698 			if (ret < 0) {
699 				return ret;
700 			}
701 
702 			decoded_fields |= (int64_t)1<<i;
703 			break;
704 		}
705 
706 		/* Skip field, if no descriptor was found */
707 		if (i >= descr_len) {
708 			ret = skip_field(obj, &kv);
709 			if (ret < 0) {
710 				return ret;
711 			}
712 		}
713 	}
714 
715 	return -EINVAL;
716 }
717 
json_obj_parse(char * payload,size_t len,const struct json_obj_descr * descr,size_t descr_len,void * val)718 int64_t json_obj_parse(char *payload, size_t len,
719 		       const struct json_obj_descr *descr, size_t descr_len,
720 		       void *val)
721 {
722 	struct json_obj obj;
723 	int64_t ret;
724 
725 	__ASSERT_NO_MSG(descr_len < (sizeof(ret) * CHAR_BIT - 1));
726 
727 	ret = obj_init(&obj, payload, len);
728 	if (ret < 0) {
729 		return ret;
730 	}
731 
732 	return obj_parse(&obj, descr, descr_len, val);
733 }
734 
json_arr_parse(char * payload,size_t len,const struct json_obj_descr * descr,void * val)735 int json_arr_parse(char *payload, size_t len,
736 		   const struct json_obj_descr *descr, void *val)
737 {
738 	struct json_obj arr;
739 	int ret;
740 
741 	ret = arr_init(&arr, payload, len);
742 	if (ret < 0) {
743 		return ret;
744 	}
745 
746 	void *ptr = (char *)val + descr->offset;
747 
748 	return arr_parse(&arr, descr->array.element_descr,
749 			 descr->array.n_elements, ptr, val);
750 }
751 
752 
json_arr_separate_object_parse_init(struct json_obj * json,char * payload,size_t len)753 int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len)
754 {
755 	return arr_init(json, payload, len);
756 }
757 
json_arr_separate_parse_object(struct json_obj * json,const struct json_obj_descr * descr,size_t descr_len,void * val)758 int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr,
759 			  size_t descr_len, void *val)
760 {
761 	struct json_token tok;
762 
763 	if (!lexer_next(&json->lex, &tok)) {
764 		return -EINVAL;
765 	}
766 
767 	if (tok.type == JSON_TOK_ARRAY_END) {
768 		return 0;
769 	} else if (tok.type == JSON_TOK_COMMA) {
770 		if (!lexer_next(&json->lex, &tok)) {
771 			return -EINVAL;
772 		}
773 	}
774 
775 	if (tok.type != JSON_TOK_OBJECT_START) {
776 		return -EINVAL;
777 	}
778 
779 	return obj_parse(json, descr, descr_len, val);
780 }
781 
escape_as(char chr)782 static char escape_as(char chr)
783 {
784 	switch (chr) {
785 	case '"':
786 		return '"';
787 	case '\\':
788 		return '\\';
789 	case '\b':
790 		return 'b';
791 	case '\f':
792 		return 'f';
793 	case '\n':
794 		return 'n';
795 	case '\r':
796 		return 'r';
797 	case '\t':
798 		return 't';
799 	}
800 
801 	return 0;
802 }
803 
json_escape_internal(const char * str,json_append_bytes_t append_bytes,void * data)804 static int json_escape_internal(const char *str,
805 				json_append_bytes_t append_bytes,
806 				void *data)
807 {
808 	const char *cur;
809 	int ret = 0;
810 
811 	for (cur = str; ret == 0 && *cur; cur++) {
812 		char escaped = escape_as(*cur);
813 
814 		if (escaped) {
815 			char bytes[2] = { '\\', escaped };
816 
817 			ret = append_bytes(bytes, 2, data);
818 		} else {
819 			ret = append_bytes(cur, 1, data);
820 		}
821 	}
822 
823 	return ret;
824 }
825 
json_calc_escaped_len(const char * str,size_t len)826 size_t json_calc_escaped_len(const char *str, size_t len)
827 {
828 	size_t escaped_len = len;
829 	size_t pos;
830 
831 	for (pos = 0; pos < len; pos++) {
832 		if (escape_as(str[pos])) {
833 			escaped_len++;
834 		}
835 	}
836 
837 	return escaped_len;
838 }
839 
json_escape(char * str,size_t * len,size_t buf_size)840 ssize_t json_escape(char *str, size_t *len, size_t buf_size)
841 {
842 	char *next; /* Points after next character to escape. */
843 	char *dest; /* Points after next place to write escaped character. */
844 	size_t escaped_len = json_calc_escaped_len(str, *len);
845 
846 	if (escaped_len == *len) {
847 		/*
848 		 * If no escape is necessary, there is nothing to do.
849 		 */
850 		return 0;
851 	}
852 
853 	if (escaped_len >= buf_size) {
854 		return -ENOMEM;
855 	}
856 
857 	/*
858 	 * By walking backwards in the buffer from the end positions
859 	 * of both the original and escaped strings, we avoid using
860 	 * extra space. Characters in the original string are
861 	 * overwritten only after they have already been escaped.
862 	 */
863 	str[escaped_len] = '\0';
864 	for (next = &str[*len], dest = &str[escaped_len]; next != str;) {
865 		char next_c = *(--next);
866 		char escape = escape_as(next_c);
867 
868 		if (escape) {
869 			*(--dest) = escape;
870 			*(--dest) = '\\';
871 		} else {
872 			*(--dest) = next_c;
873 		}
874 	}
875 	*len = escaped_len;
876 
877 	return 0;
878 }
879 
880 static int encode(const struct json_obj_descr *descr, const void *val,
881 		  json_append_bytes_t append_bytes, void *data);
882 
arr_encode(const struct json_obj_descr * elem_descr,const void * field,const void * val,json_append_bytes_t append_bytes,void * data)883 static int arr_encode(const struct json_obj_descr *elem_descr,
884 		      const void *field, const void *val,
885 		      json_append_bytes_t append_bytes, void *data)
886 {
887 	ptrdiff_t elem_size;
888 	/*
889 	 * NOTE: Since an element descriptor's offset isn't meaningful
890 	 * (array elements occur at multiple offsets in `val'), we use
891 	 * its space in elem_descr to store the offset to the field
892 	 * containing the number of elements.
893 	 */
894 	size_t n_elem = *(size_t *)((char *)val + elem_descr->offset);
895 	size_t i;
896 	int ret;
897 
898 	ret = append_bytes("[", 1, data);
899 	if (ret < 0) {
900 		return ret;
901 	}
902 
903 	/* For nested arrays, skip parent descriptor to get elements */
904 	if (elem_descr->type == JSON_TOK_ARRAY_START) {
905 		elem_descr = elem_descr->array.element_descr;
906 	}
907 
908 	elem_size = get_elem_size(elem_descr);
909 
910 	for (i = 0; i < n_elem; i++) {
911 		/*
912 		 * Though "field" points at the next element in the
913 		 * array which we need to encode, the value in
914 		 * elem_descr->offset is actually the offset of the
915 		 * length field in the "parent" struct containing the
916 		 * array.
917 		 *
918 		 * To patch things up, we lie to encode() about where
919 		 * the field is by exactly the amount it will offset
920 		 * it. This is a size optimization for struct
921 		 * json_obj_descr: the alternative is to keep a
922 		 * separate field next to element_descr which is an
923 		 * offset to the length field in the parent struct,
924 		 * but that would add a size_t to every descriptor.
925 		 */
926 		ret = encode(elem_descr, (char *)field - elem_descr->offset,
927 			     append_bytes, data);
928 		if (ret < 0) {
929 			return ret;
930 		}
931 
932 		if (i < n_elem - 1) {
933 			ret = append_bytes(",", 1, data);
934 			if (ret < 0) {
935 				return ret;
936 			}
937 		}
938 
939 		field = (char *)field + elem_size;
940 	}
941 
942 	return append_bytes("]", 1, data);
943 }
944 
str_encode(const char ** str,json_append_bytes_t append_bytes,void * data)945 static int str_encode(const char **str, json_append_bytes_t append_bytes,
946 		      void *data)
947 {
948 	int ret;
949 
950 	ret = append_bytes("\"", 1, data);
951 	if (ret < 0) {
952 		return ret;
953 	}
954 
955 	ret = json_escape_internal(*str, append_bytes, data);
956 	if (!ret) {
957 		return append_bytes("\"", 1, data);
958 	}
959 
960 	return ret;
961 }
962 
num_encode(const int32_t * num,json_append_bytes_t append_bytes,void * data)963 static int num_encode(const int32_t *num, json_append_bytes_t append_bytes,
964 		      void *data)
965 {
966 	char buf[3 * sizeof(int32_t)];
967 	int ret;
968 
969 	ret = snprintk(buf, sizeof(buf), "%d", *num);
970 	if (ret < 0) {
971 		return ret;
972 	}
973 	if (ret >= (int)sizeof(buf)) {
974 		return -ENOMEM;
975 	}
976 
977 	return append_bytes(buf, (size_t)ret, data);
978 }
979 
float_ascii_encode(struct json_obj_token * num,json_append_bytes_t append_bytes,void * data)980 static int float_ascii_encode(struct json_obj_token *num, json_append_bytes_t append_bytes,
981 		      void *data)
982 {
983 
984 	return append_bytes(num->start, num->length, data);
985 }
986 
opaque_string_encode(struct json_obj_token * opaque,json_append_bytes_t append_bytes,void * data)987 static int opaque_string_encode(struct json_obj_token *opaque, json_append_bytes_t append_bytes,
988 		      void *data)
989 {
990 	int ret;
991 
992 	ret = append_bytes("\"", 1, data);
993 	if (ret < 0) {
994 		return ret;
995 	}
996 
997 	ret = append_bytes(opaque->start, opaque->length, data);
998 	if (ret < 0) {
999 		return ret;
1000 	}
1001 
1002 	return append_bytes("\"", 1, data);
1003 }
1004 
bool_encode(const bool * value,json_append_bytes_t append_bytes,void * data)1005 static int bool_encode(const bool *value, json_append_bytes_t append_bytes,
1006 		       void *data)
1007 {
1008 	if (*value) {
1009 		return append_bytes("true", 4, data);
1010 	}
1011 
1012 	return append_bytes("false", 5, data);
1013 }
1014 
encode(const struct json_obj_descr * descr,const void * val,json_append_bytes_t append_bytes,void * data)1015 static int encode(const struct json_obj_descr *descr, const void *val,
1016 		  json_append_bytes_t append_bytes, void *data)
1017 {
1018 	void *ptr = (char *)val + descr->offset;
1019 
1020 	switch (descr->type) {
1021 	case JSON_TOK_FALSE:
1022 	case JSON_TOK_TRUE:
1023 		return bool_encode(ptr, append_bytes, data);
1024 	case JSON_TOK_STRING:
1025 		return str_encode(ptr, append_bytes, data);
1026 	case JSON_TOK_ARRAY_START:
1027 		return arr_encode(descr->array.element_descr, ptr,
1028 				  val, append_bytes, data);
1029 	case JSON_TOK_OBJECT_START:
1030 		return json_obj_encode(descr->object.sub_descr,
1031 				       descr->object.sub_descr_len,
1032 				       ptr, append_bytes, data);
1033 	case JSON_TOK_NUMBER:
1034 		return num_encode(ptr, append_bytes, data);
1035 	case JSON_TOK_FLOAT:
1036 		return float_ascii_encode(ptr, append_bytes, data);
1037 	case JSON_TOK_OPAQUE:
1038 		return opaque_string_encode(ptr, append_bytes, data);
1039 	default:
1040 		return -EINVAL;
1041 	}
1042 }
1043 
json_obj_encode(const struct json_obj_descr * descr,size_t descr_len,const void * val,json_append_bytes_t append_bytes,void * data)1044 int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
1045 		    const void *val, json_append_bytes_t append_bytes,
1046 		    void *data)
1047 {
1048 	size_t i;
1049 	int ret;
1050 
1051 	ret = append_bytes("{", 1, data);
1052 	if (ret < 0) {
1053 		return ret;
1054 	}
1055 
1056 	for (i = 0; i < descr_len; i++) {
1057 		ret = str_encode((const char **)&descr[i].field_name,
1058 				 append_bytes, data);
1059 		if (ret < 0) {
1060 			return ret;
1061 		}
1062 
1063 		ret = append_bytes(":", 1, data);
1064 		if (ret < 0) {
1065 			return ret;
1066 		}
1067 
1068 		ret = encode(&descr[i], val, append_bytes, data);
1069 		if (ret < 0) {
1070 			return ret;
1071 		}
1072 
1073 		if (i < descr_len - 1) {
1074 			ret = append_bytes(",", 1, data);
1075 			if (ret < 0) {
1076 				return ret;
1077 			}
1078 		}
1079 	}
1080 
1081 	return append_bytes("}", 1, data);
1082 }
1083 
json_arr_encode(const struct json_obj_descr * descr,const void * val,json_append_bytes_t append_bytes,void * data)1084 int json_arr_encode(const struct json_obj_descr *descr, const void *val,
1085 		    json_append_bytes_t append_bytes, void *data)
1086 {
1087 	void *ptr = (char *)val + descr->offset;
1088 
1089 	return arr_encode(descr->array.element_descr, ptr, val, append_bytes,
1090 			  data);
1091 }
1092 
1093 struct appender {
1094 	char *buffer;
1095 	size_t used;
1096 	size_t size;
1097 };
1098 
append_bytes_to_buf(const char * bytes,size_t len,void * data)1099 static int append_bytes_to_buf(const char *bytes, size_t len, void *data)
1100 {
1101 	struct appender *appender = data;
1102 
1103 	if (len >= appender->size - appender->used) {
1104 		return -ENOMEM;
1105 	}
1106 
1107 	memcpy(appender->buffer + appender->used, bytes, len);
1108 	appender->used += len;
1109 	appender->buffer[appender->used] = '\0';
1110 
1111 	return 0;
1112 }
1113 
json_obj_encode_buf(const struct json_obj_descr * descr,size_t descr_len,const void * val,char * buffer,size_t buf_size)1114 int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
1115 			const void *val, char *buffer, size_t buf_size)
1116 {
1117 	struct appender appender = { .buffer = buffer, .size = buf_size };
1118 
1119 	return json_obj_encode(descr, descr_len, val, append_bytes_to_buf,
1120 			       &appender);
1121 }
1122 
json_arr_encode_buf(const struct json_obj_descr * descr,const void * val,char * buffer,size_t buf_size)1123 int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
1124 			char *buffer, size_t buf_size)
1125 {
1126 	struct appender appender = { .buffer = buffer, .size = buf_size };
1127 
1128 	return json_arr_encode(descr, val, append_bytes_to_buf, &appender);
1129 }
1130 
measure_bytes(const char * bytes,size_t len,void * data)1131 static int measure_bytes(const char *bytes, size_t len, void *data)
1132 {
1133 	ssize_t *total = data;
1134 
1135 	*total += (ssize_t)len;
1136 
1137 	ARG_UNUSED(bytes);
1138 
1139 	return 0;
1140 }
1141 
json_calc_encoded_len(const struct json_obj_descr * descr,size_t descr_len,const void * val)1142 ssize_t json_calc_encoded_len(const struct json_obj_descr *descr,
1143 			      size_t descr_len, const void *val)
1144 {
1145 	ssize_t total = 0;
1146 	int ret;
1147 
1148 	ret = json_obj_encode(descr, descr_len, val, measure_bytes, &total);
1149 	if (ret < 0) {
1150 		return ret;
1151 	}
1152 
1153 	return total;
1154 }
1155 
json_calc_encoded_arr_len(const struct json_obj_descr * descr,const void * val)1156 ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr,
1157 				  const void *val)
1158 {
1159 	ssize_t total = 0;
1160 	int ret;
1161 
1162 	ret = json_arr_encode(descr, val, measure_bytes, &total);
1163 	if (ret < 0) {
1164 		return ret;
1165 	}
1166 
1167 	return total;
1168 }
1169