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