Fix gcc10 compiler warnings
[legacy-proxmark3.git] / client / jansson / pack_unpack.c
blob3b9977667e87275489b5b2378f1645f330b343a2
1 /*
2 * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
3 * Copyright (c) 2011-2012 Graeme Smecher <graeme.smecher@mail.mcgill.ca>
5 * Jansson is free software; you can redistribute it and/or modify
6 * it under the terms of the MIT license. See LICENSE for details.
7 */
9 #include <string.h>
10 #include "jansson.h"
11 #include "jansson_private.h"
12 #include "utf.h"
14 typedef struct {
15 int line;
16 int column;
17 size_t pos;
18 char token;
19 } token_t;
21 typedef struct {
22 const char *start;
23 const char *fmt;
24 token_t prev_token;
25 token_t token;
26 token_t next_token;
27 json_error_t *error;
28 size_t flags;
29 int line;
30 int column;
31 size_t pos;
32 int has_error;
33 } scanner_t;
35 #define token(scanner) ((scanner)->token.token)
37 static const char * const type_names[] = {
38 "object",
39 "array",
40 "string",
41 "integer",
42 "real",
43 "true",
44 "false",
45 "null"
48 #define type_name(x) type_names[json_typeof(x)]
50 static const char unpack_value_starters[] = "{[siIbfFOon";
52 static void scanner_init(scanner_t *s, json_error_t *error,
53 size_t flags, const char *fmt)
55 s->error = error;
56 s->flags = flags;
57 s->fmt = s->start = fmt;
58 memset(&s->prev_token, 0, sizeof(token_t));
59 memset(&s->token, 0, sizeof(token_t));
60 memset(&s->next_token, 0, sizeof(token_t));
61 s->line = 1;
62 s->column = 0;
63 s->pos = 0;
64 s->has_error = 0;
67 static void next_token(scanner_t *s)
69 const char *t;
70 s->prev_token = s->token;
72 if(s->next_token.line) {
73 s->token = s->next_token;
74 s->next_token.line = 0;
75 return;
78 if (!token(s) && !*s->fmt)
79 return;
81 t = s->fmt;
82 s->column++;
83 s->pos++;
85 /* skip space and ignored chars */
86 while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
87 if(*t == '\n') {
88 s->line++;
89 s->column = 1;
91 else
92 s->column++;
94 s->pos++;
95 t++;
98 s->token.token = *t;
99 s->token.line = s->line;
100 s->token.column = s->column;
101 s->token.pos = s->pos;
103 if (*t) t++;
104 s->fmt = t;
107 static void prev_token(scanner_t *s)
109 s->next_token = s->token;
110 s->token = s->prev_token;
113 static void set_error(scanner_t *s, const char *source, enum json_error_code code,
114 const char *fmt, ...)
116 va_list ap;
117 va_start(ap, fmt);
119 jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
120 code, fmt, ap);
122 jsonp_error_set_source(s->error, source);
124 va_end(ap);
127 static json_t *pack(scanner_t *s, va_list *ap);
130 /* ours will be set to 1 if jsonp_free() must be called for the result
131 afterwards */
132 static char *read_string(scanner_t *s, va_list *ap,
133 const char *purpose, size_t *out_len, int *ours, int optional)
135 char t;
136 strbuffer_t strbuff;
137 const char *str;
138 size_t length;
140 next_token(s);
141 t = token(s);
142 prev_token(s);
144 *ours = 0;
145 if(t != '#' && t != '%' && t != '+') {
146 /* Optimize the simple case */
147 str = va_arg(*ap, const char *);
149 if(!str) {
150 if (!optional) {
151 set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
152 s->has_error = 1;
154 return NULL;
157 length = strlen(str);
159 if(!utf8_check_string(str, length)) {
160 set_error(s, "<args>", json_error_invalid_utf8, "Invalid UTF-8 %s", purpose);
161 s->has_error = 1;
162 return NULL;
165 *out_len = length;
166 return (char *)str;
167 } else if (optional) {
168 set_error(s, "<format>", json_error_invalid_format, "Cannot use '%c' on optional strings", t);
169 s->has_error = 1;
171 return NULL;
174 if(strbuffer_init(&strbuff)) {
175 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
176 s->has_error = 1;
179 while(1) {
180 str = va_arg(*ap, const char *);
181 if(!str) {
182 set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
183 s->has_error = 1;
186 next_token(s);
188 if(token(s) == '#') {
189 length = va_arg(*ap, int);
191 else if(token(s) == '%') {
192 length = va_arg(*ap, size_t);
194 else {
195 prev_token(s);
196 length = s->has_error ? 0 : strlen(str);
199 if(!s->has_error && strbuffer_append_bytes(&strbuff, str, length) == -1) {
200 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
201 s->has_error = 1;
204 next_token(s);
205 if(token(s) != '+') {
206 prev_token(s);
207 break;
211 if(s->has_error) {
212 strbuffer_close(&strbuff);
213 return NULL;
216 if(!utf8_check_string(strbuff.value, strbuff.length)) {
217 set_error(s, "<args>", json_error_invalid_utf8, "Invalid UTF-8 %s", purpose);
218 strbuffer_close(&strbuff);
219 s->has_error = 1;
220 return NULL;
223 *out_len = strbuff.length;
224 *ours = 1;
225 return strbuffer_steal_value(&strbuff);
228 static json_t *pack_object(scanner_t *s, va_list *ap)
230 json_t *object = json_object();
231 next_token(s);
233 while(token(s) != '}') {
234 char *key;
235 size_t len;
236 int ours;
237 json_t *value;
238 char valueOptional;
240 if(!token(s)) {
241 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
242 goto error;
245 if(token(s) != 's') {
246 set_error(s, "<format>", json_error_invalid_format, "Expected format 's', got '%c'", token(s));
247 goto error;
250 key = read_string(s, ap, "object key", &len, &ours, 0);
252 next_token(s);
254 next_token(s);
255 valueOptional = token(s);
256 prev_token(s);
258 value = pack(s, ap);
259 if(!value) {
260 if(ours)
261 jsonp_free(key);
263 if(valueOptional != '*') {
264 set_error(s, "<args>", json_error_null_value, "NULL object value");
265 s->has_error = 1;
268 next_token(s);
269 continue;
272 if(s->has_error)
273 json_decref(value);
275 if(!s->has_error && json_object_set_new_nocheck(object, key, value)) {
276 set_error(s, "<internal>", json_error_out_of_memory, "Unable to add key \"%s\"", key);
277 s->has_error = 1;
280 if(ours)
281 jsonp_free(key);
283 next_token(s);
286 if(!s->has_error)
287 return object;
289 error:
290 json_decref(object);
291 return NULL;
294 static json_t *pack_array(scanner_t *s, va_list *ap)
296 json_t *array = json_array();
297 next_token(s);
299 while(token(s) != ']') {
300 json_t *value;
301 char valueOptional;
303 if(!token(s)) {
304 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
305 /* Format string errors are unrecoverable. */
306 goto error;
309 next_token(s);
310 valueOptional = token(s);
311 prev_token(s);
313 value = pack(s, ap);
314 if(!value) {
315 if(valueOptional != '*') {
316 s->has_error = 1;
319 next_token(s);
320 continue;
323 if(s->has_error)
324 json_decref(value);
326 if(!s->has_error && json_array_append_new(array, value)) {
327 set_error(s, "<internal>", json_error_out_of_memory, "Unable to append to array");
328 s->has_error = 1;
331 next_token(s);
334 if(!s->has_error)
335 return array;
337 error:
338 json_decref(array);
339 return NULL;
342 static json_t *pack_string(scanner_t *s, va_list *ap)
344 char *str;
345 char t;
346 size_t len;
347 int ours;
348 int optional;
350 next_token(s);
351 t = token(s);
352 optional = t == '?' || t == '*';
353 if (!optional)
354 prev_token(s);
356 str = read_string(s, ap, "string", &len, &ours, optional);
358 if (!str)
359 return t == '?' && !s->has_error ? json_null() : NULL;
361 if (s->has_error) {
362 /* It's impossible to reach this point if ours != 0, do not free str. */
363 return NULL;
366 if (ours)
367 return jsonp_stringn_nocheck_own(str, len);
369 return json_stringn_nocheck(str, len);
372 static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
374 json_t *json;
375 char ntoken;
377 next_token(s);
378 ntoken = token(s);
380 if (ntoken != '?' && ntoken != '*')
381 prev_token(s);
383 json = va_arg(*ap, json_t *);
385 if (json)
386 return need_incref ? json_incref(json) : json;
388 switch (ntoken) {
389 case '?':
390 return json_null();
391 case '*':
392 return NULL;
393 default:
394 break;
397 set_error(s, "<args>", json_error_null_value, "NULL object");
398 s->has_error = 1;
399 return NULL;
402 static json_t *pack_integer(scanner_t *s, json_int_t value)
404 json_t *json = json_integer(value);
406 if (!json) {
407 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
408 s->has_error = 1;
411 return json;
414 static json_t *pack_real(scanner_t *s, double value)
416 /* Allocate without setting value so we can identify OOM error. */
417 json_t *json = json_real(0.0);
419 if (!json) {
420 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
421 s->has_error = 1;
423 return NULL;
426 if (json_real_set(json, value)) {
427 json_decref(json);
429 set_error(s, "<args>", json_error_numeric_overflow, "Invalid floating point value");
430 s->has_error = 1;
432 return NULL;
435 return json;
438 static json_t *pack(scanner_t *s, va_list *ap)
440 switch(token(s)) {
441 case '{':
442 return pack_object(s, ap);
444 case '[':
445 return pack_array(s, ap);
447 case 's': /* string */
448 return pack_string(s, ap);
450 case 'n': /* null */
451 return json_null();
453 case 'b': /* boolean */
454 return va_arg(*ap, int) ? json_true() : json_false();
456 case 'i': /* integer from int */
457 return pack_integer(s, va_arg(*ap, int));
459 case 'I': /* integer from json_int_t */
460 return pack_integer(s, va_arg(*ap, json_int_t));
462 case 'f': /* real */
463 return pack_real(s, va_arg(*ap, double));
465 case 'O': /* a json_t object; increments refcount */
466 return pack_object_inter(s, ap, 1);
468 case 'o': /* a json_t object; doesn't increment refcount */
469 return pack_object_inter(s, ap, 0);
471 default:
472 set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
473 token(s));
474 s->has_error = 1;
475 return NULL;
479 static int unpack(scanner_t *s, json_t *root, va_list *ap);
481 static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
483 int ret = -1;
484 int strict = 0;
485 int gotopt = 0;
487 /* Use a set (emulated by a hashtable) to check that all object
488 keys are accessed. Checking that the correct number of keys
489 were accessed is not enough, as the same key can be unpacked
490 multiple times.
492 hashtable_t key_set;
494 if(hashtable_init(&key_set)) {
495 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
496 return -1;
499 if(root && !json_is_object(root)) {
500 set_error(s, "<validation>", json_error_wrong_type, "Expected object, got %s",
501 type_name(root));
502 goto out;
504 next_token(s);
506 while(token(s) != '}') {
507 const char *key;
508 json_t *value;
509 int opt = 0;
511 if(strict != 0) {
512 set_error(s, "<format>", json_error_invalid_format, "Expected '}' after '%c', got '%c'",
513 (strict == 1 ? '!' : '*'), token(s));
514 goto out;
517 if(!token(s)) {
518 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
519 goto out;
522 if(token(s) == '!' || token(s) == '*') {
523 strict = (token(s) == '!' ? 1 : -1);
524 next_token(s);
525 continue;
528 if(token(s) != 's') {
529 set_error(s, "<format>", json_error_invalid_format, "Expected format 's', got '%c'", token(s));
530 goto out;
533 key = va_arg(*ap, const char *);
534 if(!key) {
535 set_error(s, "<args>", json_error_null_value, "NULL object key");
536 goto out;
539 next_token(s);
541 if(token(s) == '?') {
542 opt = gotopt = 1;
543 next_token(s);
546 if(!root) {
547 /* skipping */
548 value = NULL;
550 else {
551 value = json_object_get(root, key);
552 if(!value && !opt) {
553 set_error(s, "<validation>", json_error_item_not_found, "Object item not found: %s", key);
554 goto out;
558 if(unpack(s, value, ap))
559 goto out;
561 hashtable_set(&key_set, key, json_null());
562 next_token(s);
565 if(strict == 0 && (s->flags & JSON_STRICT))
566 strict = 1;
568 if(root && strict == 1) {
569 /* We need to check that all non optional items have been parsed */
570 const char *key;
571 /* keys_res is 1 for uninitialized, 0 for success, -1 for error. */
572 int keys_res = 1;
573 strbuffer_t unrecognized_keys;
574 json_t *value;
575 long unpacked = 0;
577 if (gotopt || json_object_size(root) != key_set.size) {
578 json_object_foreach(root, key, value) {
579 if(!hashtable_get(&key_set, key)) {
580 unpacked++;
582 /* Save unrecognized keys for the error message */
583 if (keys_res == 1) {
584 keys_res = strbuffer_init(&unrecognized_keys);
585 } else if (!keys_res) {
586 keys_res = strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
589 if (!keys_res)
590 keys_res = strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
594 if (unpacked) {
595 set_error(s, "<validation>", json_error_end_of_input_expected,
596 "%li object item(s) left unpacked: %s",
597 unpacked,
598 keys_res ? "<unknown>" : strbuffer_value(&unrecognized_keys));
599 strbuffer_close(&unrecognized_keys);
600 goto out;
604 ret = 0;
606 out:
607 hashtable_close(&key_set);
608 return ret;
611 static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
613 size_t i = 0;
614 int strict = 0;
616 if(root && !json_is_array(root)) {
617 set_error(s, "<validation>", json_error_wrong_type, "Expected array, got %s", type_name(root));
618 return -1;
620 next_token(s);
622 while(token(s) != ']') {
623 json_t *value;
625 if(strict != 0) {
626 set_error(s, "<format>", json_error_invalid_format, "Expected ']' after '%c', got '%c'",
627 (strict == 1 ? '!' : '*'),
628 token(s));
629 return -1;
632 if(!token(s)) {
633 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
634 return -1;
637 if(token(s) == '!' || token(s) == '*') {
638 strict = (token(s) == '!' ? 1 : -1);
639 next_token(s);
640 continue;
643 if(!strchr(unpack_value_starters, token(s))) {
644 set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
645 token(s));
646 return -1;
649 if(!root) {
650 /* skipping */
651 value = NULL;
653 else {
654 value = json_array_get(root, i);
655 if(!value) {
656 set_error(s, "<validation>", json_error_index_out_of_range, "Array index %lu out of range",
657 (unsigned long)i);
658 return -1;
662 if(unpack(s, value, ap))
663 return -1;
665 next_token(s);
666 i++;
669 if(strict == 0 && (s->flags & JSON_STRICT))
670 strict = 1;
672 if(root && strict == 1 && i != json_array_size(root)) {
673 long diff = (long)json_array_size(root) - (long)i;
674 set_error(s, "<validation>", json_error_end_of_input_expected, "%li array item(s) left unpacked", diff);
675 return -1;
678 return 0;
681 static int unpack(scanner_t *s, json_t *root, va_list *ap)
683 switch(token(s))
685 case '{':
686 return unpack_object(s, root, ap);
688 case '[':
689 return unpack_array(s, root, ap);
691 case 's':
692 if(root && !json_is_string(root)) {
693 set_error(s, "<validation>", json_error_wrong_type, "Expected string, got %s",
694 type_name(root));
695 return -1;
698 if(!(s->flags & JSON_VALIDATE_ONLY)) {
699 const char **str_target;
700 size_t *len_target = NULL;
702 str_target = va_arg(*ap, const char **);
703 if(!str_target) {
704 set_error(s, "<args>", json_error_null_value, "NULL string argument");
705 return -1;
708 next_token(s);
710 if(token(s) == '%') {
711 len_target = va_arg(*ap, size_t *);
712 if(!len_target) {
713 set_error(s, "<args>", json_error_null_value, "NULL string length argument");
714 return -1;
717 else
718 prev_token(s);
720 if(root) {
721 *str_target = json_string_value(root);
722 if(len_target)
723 *len_target = json_string_length(root);
726 return 0;
728 case 'i':
729 if(root && !json_is_integer(root)) {
730 set_error(s, "<validation>", json_error_wrong_type, "Expected integer, got %s",
731 type_name(root));
732 return -1;
735 if(!(s->flags & JSON_VALIDATE_ONLY)) {
736 int *target = va_arg(*ap, int*);
737 if(root)
738 *target = (int)json_integer_value(root);
741 return 0;
743 case 'I':
744 if(root && !json_is_integer(root)) {
745 set_error(s, "<validation>", json_error_wrong_type, "Expected integer, got %s",
746 type_name(root));
747 return -1;
750 if(!(s->flags & JSON_VALIDATE_ONLY)) {
751 json_int_t *target = va_arg(*ap, json_int_t*);
752 if(root)
753 *target = json_integer_value(root);
756 return 0;
758 case 'b':
759 if(root && !json_is_boolean(root)) {
760 set_error(s, "<validation>", json_error_wrong_type, "Expected true or false, got %s",
761 type_name(root));
762 return -1;
765 if(!(s->flags & JSON_VALIDATE_ONLY)) {
766 int *target = va_arg(*ap, int*);
767 if(root)
768 *target = json_is_true(root);
771 return 0;
773 case 'f':
774 if(root && !json_is_real(root)) {
775 set_error(s, "<validation>", json_error_wrong_type, "Expected real, got %s",
776 type_name(root));
777 return -1;
780 if(!(s->flags & JSON_VALIDATE_ONLY)) {
781 double *target = va_arg(*ap, double*);
782 if(root)
783 *target = json_real_value(root);
786 return 0;
788 case 'F':
789 if(root && !json_is_number(root)) {
790 set_error(s, "<validation>", json_error_wrong_type, "Expected real or integer, got %s",
791 type_name(root));
792 return -1;
795 if(!(s->flags & JSON_VALIDATE_ONLY)) {
796 double *target = va_arg(*ap, double*);
797 if(root)
798 *target = json_number_value(root);
801 return 0;
803 case 'O':
804 if(root && !(s->flags & JSON_VALIDATE_ONLY))
805 json_incref(root);
806 /* Fall through */
808 case 'o':
809 if(!(s->flags & JSON_VALIDATE_ONLY)) {
810 json_t **target = va_arg(*ap, json_t**);
811 if(root)
812 *target = root;
815 return 0;
817 case 'n':
818 /* Never assign, just validate */
819 if(root && !json_is_null(root)) {
820 set_error(s, "<validation>", json_error_wrong_type, "Expected null, got %s",
821 type_name(root));
822 return -1;
824 return 0;
826 default:
827 set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
828 token(s));
829 return -1;
833 json_t *json_vpack_ex(json_error_t *error, size_t flags,
834 const char *fmt, va_list ap)
836 scanner_t s;
837 va_list ap_copy;
838 json_t *value;
840 if(!fmt || !*fmt) {
841 jsonp_error_init(error, "<format>");
842 jsonp_error_set(error, -1, -1, 0, json_error_invalid_argument, "NULL or empty format string");
843 return NULL;
845 jsonp_error_init(error, NULL);
847 scanner_init(&s, error, flags, fmt);
848 next_token(&s);
850 va_copy(ap_copy, ap);
851 value = pack(&s, &ap_copy);
852 va_end(ap_copy);
854 /* This will cover all situations where s.has_error is true */
855 if(!value)
856 return NULL;
858 next_token(&s);
859 if(token(&s)) {
860 json_decref(value);
861 set_error(&s, "<format>", json_error_invalid_format, "Garbage after format string");
862 return NULL;
865 return value;
868 json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
870 json_t *value;
871 va_list ap;
873 va_start(ap, fmt);
874 value = json_vpack_ex(error, flags, fmt, ap);
875 va_end(ap);
877 return value;
880 json_t *json_pack(const char *fmt, ...)
882 json_t *value;
883 va_list ap;
885 va_start(ap, fmt);
886 value = json_vpack_ex(NULL, 0, fmt, ap);
887 va_end(ap);
889 return value;
892 int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
893 const char *fmt, va_list ap)
895 scanner_t s;
896 va_list ap_copy;
898 if(!root) {
899 jsonp_error_init(error, "<root>");
900 jsonp_error_set(error, -1, -1, 0, json_error_null_value, "NULL root value");
901 return -1;
904 if(!fmt || !*fmt) {
905 jsonp_error_init(error, "<format>");
906 jsonp_error_set(error, -1, -1, 0, json_error_invalid_argument, "NULL or empty format string");
907 return -1;
909 jsonp_error_init(error, NULL);
911 scanner_init(&s, error, flags, fmt);
912 next_token(&s);
914 va_copy(ap_copy, ap);
915 if(unpack(&s, root, &ap_copy)) {
916 va_end(ap_copy);
917 return -1;
919 va_end(ap_copy);
921 next_token(&s);
922 if(token(&s)) {
923 set_error(&s, "<format>", json_error_invalid_format, "Garbage after format string");
924 return -1;
927 return 0;
930 int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)
932 int ret;
933 va_list ap;
935 va_start(ap, fmt);
936 ret = json_vunpack_ex(root, error, flags, fmt, ap);
937 va_end(ap);
939 return ret;
942 int json_unpack(json_t *root, const char *fmt, ...)
944 int ret;
945 va_list ap;
947 va_start(ap, fmt);
948 ret = json_vunpack_ex(root, NULL, 0, fmt, ap);
949 va_end(ap);
951 return ret;