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