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