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