fix length check when reading a dictionary file
[RRG-proxmark3.git] / client / deps / jansson / pack_unpack.c
blobfbe0d44efd67071c51df9af4d5bd1129a2e9870f
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) {
54 s->error = error;
55 s->flags = flags;
56 s->fmt = s->start = fmt;
57 memset(&s->prev_token, 0, sizeof(token_t));
58 memset(&s->token, 0, sizeof(token_t));
59 memset(&s->next_token, 0, sizeof(token_t));
60 s->line = 1;
61 s->column = 0;
62 s->pos = 0;
63 s->has_error = 0;
66 static void next_token(scanner_t *s) {
67 const char *t;
68 s->prev_token = s->token;
70 if (s->next_token.line) {
71 s->token = s->next_token;
72 s->next_token.line = 0;
73 return;
76 if (!token(s) && !*s->fmt)
77 return;
79 t = s->fmt;
80 s->column++;
81 s->pos++;
83 /* skip space and ignored chars */
84 while (*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
85 if (*t == '\n') {
86 s->line++;
87 s->column = 1;
88 } else
89 s->column++;
91 s->pos++;
92 t++;
95 s->token.token = *t;
96 s->token.line = s->line;
97 s->token.column = s->column;
98 s->token.pos = s->pos;
100 if (*t) t++;
101 s->fmt = t;
104 static void prev_token(scanner_t *s) {
105 s->next_token = s->token;
106 s->token = s->prev_token;
109 static void set_error(scanner_t *s, const char *source, enum json_error_code code,
110 const char *fmt, ...) {
111 va_list ap;
112 va_start(ap, fmt);
114 jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
115 code, fmt, ap);
117 jsonp_error_set_source(s->error, source);
119 va_end(ap);
122 static json_t *pack(scanner_t *s, va_list *ap);
125 /* ours will be set to 1 if jsonp_free() must be called for the result
126 afterwards */
127 static char *read_string(scanner_t *s, va_list *ap,
128 const char *purpose, size_t *out_len, int *ours, int optional) {
129 char t;
130 strbuffer_t strbuff;
131 const char *str;
132 size_t length;
134 next_token(s);
135 t = token(s);
136 prev_token(s);
138 *ours = 0;
139 if (t != '#' && t != '%' && t != '+') {
140 /* Optimize the simple case */
141 str = va_arg(*ap, const char *);
143 if (!str) {
144 if (!optional) {
145 set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
146 s->has_error = 1;
148 return NULL;
151 length = strlen(str);
153 if (!utf8_check_string(str, length)) {
154 set_error(s, "<args>", json_error_invalid_utf8, "Invalid UTF-8 %s", purpose);
155 s->has_error = 1;
156 return NULL;
159 *out_len = length;
160 return (char *)str;
161 } else if (optional) {
162 set_error(s, "<format>", json_error_invalid_format, "Cannot use '%c' on optional strings", t);
163 s->has_error = 1;
165 return NULL;
168 if (strbuffer_init(&strbuff)) {
169 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
170 s->has_error = 1;
173 while (1) {
174 str = va_arg(*ap, const char *);
175 if (!str) {
176 set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
177 s->has_error = 1;
180 next_token(s);
182 if (token(s) == '#') {
183 length = va_arg(*ap, int);
184 } else if (token(s) == '%') {
185 length = va_arg(*ap, size_t);
186 } else {
187 prev_token(s);
188 length = s->has_error == 1 ? 0 : strlen(str);
191 if (!s->has_error && strbuffer_append_bytes(&strbuff, str, length) == -1) {
192 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
193 s->has_error = 1;
196 next_token(s);
197 if (token(s) != '+') {
198 prev_token(s);
199 break;
203 if (s->has_error) {
204 strbuffer_close(&strbuff);
205 return NULL;
208 if (!utf8_check_string(strbuff.value, strbuff.length)) {
209 set_error(s, "<args>", json_error_invalid_utf8, "Invalid UTF-8 %s", purpose);
210 strbuffer_close(&strbuff);
211 s->has_error = 1;
212 return NULL;
215 *out_len = strbuff.length;
216 *ours = 1;
217 return strbuffer_steal_value(&strbuff);
220 static json_t *pack_object(scanner_t *s, va_list *ap) {
221 json_t *object = json_object();
222 next_token(s);
224 while (token(s) != '}') {
225 char *key;
226 size_t len;
227 int ours;
228 json_t *value;
229 char valueOptional;
231 if (!token(s)) {
232 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
233 goto error;
236 if (token(s) != 's') {
237 set_error(s, "<format>", json_error_invalid_format, "Expected format 's', got '%c'", token(s));
238 goto error;
241 key = read_string(s, ap, "object key", &len, &ours, 0);
243 next_token(s);
245 next_token(s);
246 valueOptional = token(s);
247 prev_token(s);
249 value = pack(s, ap);
250 if (!value) {
251 if (ours)
252 jsonp_free(key);
254 if (valueOptional != '*') {
255 set_error(s, "<args>", json_error_null_value, "NULL object value");
256 s->has_error = 1;
259 next_token(s);
260 continue;
263 if (s->has_error)
264 json_decref(value);
266 if (!s->has_error && json_object_set_new_nocheck(object, key, value)) {
267 set_error(s, "<internal>", json_error_out_of_memory, "Unable to add key \"%s\"", key);
268 s->has_error = 1;
271 if (ours)
272 jsonp_free(key);
274 next_token(s);
277 if (!s->has_error)
278 return object;
280 error:
281 json_decref(object);
282 return NULL;
285 static json_t *pack_array(scanner_t *s, va_list *ap) {
286 json_t *array = json_array();
287 next_token(s);
289 while (token(s) != ']') {
290 json_t *value;
291 char valueOptional;
293 if (!token(s)) {
294 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
295 /* Format string errors are unrecoverable. */
296 goto error;
299 next_token(s);
300 valueOptional = token(s);
301 prev_token(s);
303 value = pack(s, ap);
304 if (!value) {
305 if (valueOptional != '*') {
306 s->has_error = 1;
309 next_token(s);
310 continue;
313 if (s->has_error)
314 json_decref(value);
316 if (!s->has_error && json_array_append_new(array, value)) {
317 set_error(s, "<internal>", json_error_out_of_memory, "Unable to append to array");
318 s->has_error = 1;
321 next_token(s);
324 if (!s->has_error)
325 return array;
327 error:
328 json_decref(array);
329 return NULL;
332 static json_t *pack_string(scanner_t *s, va_list *ap) {
333 char *str;
334 char t;
335 size_t len;
336 int ours;
337 int optional;
339 next_token(s);
340 t = token(s);
341 optional = t == '?' || t == '*';
342 if (!optional)
343 prev_token(s);
345 str = read_string(s, ap, "string", &len, &ours, optional);
347 if (!str)
348 return t == '?' && !s->has_error ? json_null() : NULL;
350 if (s->has_error) {
351 /* It's impossible to reach this point if ours != 0, do not free str. */
352 return NULL;
355 if (ours)
356 return jsonp_stringn_nocheck_own(str, len);
358 return json_stringn_nocheck(str, len);
361 static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref) {
362 json_t *json;
363 char ntoken;
365 next_token(s);
366 ntoken = token(s);
368 if (ntoken != '?' && ntoken != '*')
369 prev_token(s);
371 json = va_arg(*ap, json_t *);
373 if (json)
374 return need_incref ? json_incref(json) : json;
376 switch (ntoken) {
377 case '?':
378 return json_null();
379 case '*':
380 return NULL;
381 default:
382 break;
385 set_error(s, "<args>", json_error_null_value, "NULL object");
386 s->has_error = 1;
387 return NULL;
390 static json_t *pack_integer(scanner_t *s, json_int_t value) {
391 json_t *json = json_integer(value);
393 if (!json) {
394 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
395 s->has_error = 1;
398 return json;
401 static json_t *pack_real(scanner_t *s, double value) {
402 /* Allocate without setting value so we can identify OOM error. */
403 json_t *json = json_real(0.0);
405 if (!json) {
406 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
407 s->has_error = 1;
409 return NULL;
412 if (json_real_set(json, value)) {
413 json_decref(json);
415 set_error(s, "<args>", json_error_numeric_overflow, "Invalid floating point value");
416 s->has_error = 1;
418 return NULL;
421 return json;
424 static json_t *pack(scanner_t *s, va_list *ap) {
425 switch (token(s)) {
426 case '{':
427 return pack_object(s, ap);
429 case '[':
430 return pack_array(s, ap);
432 case 's': /* string */
433 return pack_string(s, ap);
435 case 'n': /* null */
436 return json_null();
438 case 'b': /* boolean */
439 return va_arg(*ap, int) ? json_true() : json_false();
441 case 'i': /* integer from int */
442 return pack_integer(s, va_arg(*ap, int));
444 case 'I': /* integer from json_int_t */
445 return pack_integer(s, va_arg(*ap, json_int_t));
447 case 'f': /* real */
448 return pack_real(s, va_arg(*ap, double));
450 case 'O': /* a json_t object; increments refcount */
451 return pack_object_inter(s, ap, 1);
453 case 'o': /* a json_t object; doesn't increment refcount */
454 return pack_object_inter(s, ap, 0);
456 default:
457 set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
458 token(s));
459 s->has_error = 1;
460 return NULL;
464 static int unpack(scanner_t *s, json_t *root, va_list *ap);
466 static int unpack_object(scanner_t *s, json_t *root, va_list *ap) {
467 int ret = -1;
468 int strict = 0;
469 int gotopt = 0;
471 /* Use a set (emulated by a hashtable) to check that all object
472 keys are accessed. Checking that the correct number of keys
473 were accessed is not enough, as the same key can be unpacked
474 multiple times.
476 hashtable_t key_set;
478 if (hashtable_init(&key_set)) {
479 set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
480 return -1;
484 if (root && !json_is_object(root)) {
485 set_error(s,
486 "<validation>",
487 json_error_wrong_type,
488 "Expected object, got %s",
489 (root) ? type_name(root) : "NULL"
491 goto out;
493 next_token(s);
495 while (token(s) != '}') {
496 const char *key;
497 json_t *value;
498 int opt = 0;
500 if (strict != 0) {
501 set_error(s, "<format>", json_error_invalid_format, "Expected '}' after '%c', got '%c'",
502 (strict == 1 ? '!' : '*'), token(s));
503 goto out;
506 if (!token(s)) {
507 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
508 goto out;
511 if (token(s) == '!' || token(s) == '*') {
512 strict = (token(s) == '!' ? 1 : -1);
513 next_token(s);
514 continue;
517 if (token(s) != 's') {
518 set_error(s, "<format>", json_error_invalid_format, "Expected format 's', got '%c'", token(s));
519 goto out;
522 key = va_arg(*ap, const char *);
523 if (!key) {
524 set_error(s, "<args>", json_error_null_value, "NULL object key");
525 goto out;
528 next_token(s);
530 if (token(s) == '?') {
531 opt = gotopt = 1;
532 next_token(s);
535 if (!root) {
536 /* skipping */
537 value = NULL;
538 } else {
539 value = json_object_get(root, key);
540 if (!value && !opt) {
541 set_error(s, "<validation>", json_error_item_not_found, "Object item not found: %s", key);
542 goto out;
546 if (unpack(s, value, ap))
547 goto out;
549 hashtable_set(&key_set, key, json_null());
550 next_token(s);
553 if (strict == 0 && (s->flags & JSON_STRICT))
554 strict = 1;
556 if (root && strict == 1) {
557 /* We need to check that all non optional items have been parsed */
558 const char *key;
559 /* keys_res is 1 for uninitialized, 0 for success, -1 for error. */
560 int keys_res = 1;
561 strbuffer_t unrecognized_keys;
562 json_t *value;
563 long unpacked = 0;
565 if (gotopt || json_object_size(root) != key_set.size) {
566 json_object_foreach(root, key, value) {
567 if (!hashtable_get(&key_set, key)) {
568 unpacked++;
570 /* Save unrecognized keys for the error message */
571 if (keys_res == 1) {
572 keys_res = strbuffer_init(&unrecognized_keys);
573 } else if (!keys_res) {
574 keys_res = strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
577 if (!keys_res)
578 keys_res = strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
582 if (unpacked) {
583 set_error(s, "<validation>", json_error_end_of_input_expected,
584 "%li object item(s) left unpacked: %s",
585 unpacked,
586 keys_res ? "<unknown>" : strbuffer_value(&unrecognized_keys));
587 strbuffer_close(&unrecognized_keys);
588 goto out;
592 ret = 0;
594 out:
595 hashtable_close(&key_set);
596 return ret;
599 static int unpack_array(scanner_t *s, json_t *root, va_list *ap) {
600 size_t i = 0;
601 int strict = 0;
603 if (root && !json_is_array(root)) {
604 set_error(s, "<validation>", json_error_wrong_type, "Expected array, got %s", type_name(root));
605 return -1;
607 next_token(s);
609 while (token(s) != ']') {
610 json_t *value;
612 if (strict != 0) {
613 set_error(s, "<format>", json_error_invalid_format, "Expected ']' after '%c', got '%c'",
614 (strict == 1 ? '!' : '*'),
615 token(s));
616 return -1;
619 if (!token(s)) {
620 set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
621 return -1;
624 if (token(s) == '!' || token(s) == '*') {
625 strict = (token(s) == '!' ? 1 : -1);
626 next_token(s);
627 continue;
630 if (!strchr(unpack_value_starters, token(s))) {
631 set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
632 token(s));
633 return -1;
636 if (!root) {
637 /* skipping */
638 value = NULL;
639 } else {
640 value = json_array_get(root, i);
641 if (!value) {
642 set_error(s, "<validation>", json_error_index_out_of_range, "Array index %lu out of range",
643 (unsigned long)i);
644 return -1;
648 if (unpack(s, value, ap))
649 return -1;
651 next_token(s);
652 i++;
655 if (strict == 0 && (s->flags & JSON_STRICT))
656 strict = 1;
658 if (root && strict == 1 && i != json_array_size(root)) {
659 long diff = (long)json_array_size(root) - (long)i;
660 set_error(s, "<validation>", json_error_end_of_input_expected, "%li array item(s) left unpacked", diff);
661 return -1;
664 return 0;
667 static int unpack(scanner_t *s, json_t *root, va_list *ap) {
668 switch (token(s)) {
669 case '{':
670 return unpack_object(s, root, ap);
672 case '[':
673 return unpack_array(s, root, ap);
675 case 's':
676 if (root && !json_is_string(root)) {
677 set_error(s, "<validation>", json_error_wrong_type, "Expected string, got %s",
678 type_name(root));
679 return -1;
682 if (!(s->flags & JSON_VALIDATE_ONLY)) {
683 const char **str_target;
684 size_t *len_target = NULL;
686 str_target = va_arg(*ap, const char **);
687 if (!str_target) {
688 set_error(s, "<args>", json_error_null_value, "NULL string argument");
689 return -1;
692 next_token(s);
694 if (token(s) == '%') {
695 len_target = va_arg(*ap, size_t *);
696 if (!len_target) {
697 set_error(s, "<args>", json_error_null_value, "NULL string length argument");
698 return -1;
700 } else
701 prev_token(s);
703 if (root) {
704 *str_target = json_string_value(root);
705 if (len_target)
706 *len_target = json_string_length(root);
709 return 0;
711 case 'i':
712 if (root && !json_is_integer(root)) {
713 set_error(s, "<validation>", json_error_wrong_type, "Expected integer, got %s",
714 type_name(root));
715 return -1;
718 if (!(s->flags & JSON_VALIDATE_ONLY)) {
719 int *target = va_arg(*ap, int *);
720 if (root)
721 *target = (int)json_integer_value(root);
724 return 0;
726 case 'I':
727 if (root && !json_is_integer(root)) {
728 set_error(s, "<validation>", json_error_wrong_type, "Expected integer, got %s",
729 type_name(root));
730 return -1;
733 if (!(s->flags & JSON_VALIDATE_ONLY)) {
734 json_int_t *target = va_arg(*ap, json_int_t *);
735 if (root)
736 *target = json_integer_value(root);
739 return 0;
741 case 'b':
742 if (root && !json_is_boolean(root)) {
743 set_error(s,
744 "<validation>",
745 json_error_wrong_type,
746 "Expected true or false, got %s",
747 type_name(root)
749 return -1;
752 if (!(s->flags & JSON_VALIDATE_ONLY)) {
753 int *target = va_arg(*ap, int *);
754 if (root)
755 *target = json_is_true(root);
758 return 0;
760 case 'f':
761 if (root && !json_is_real(root)) {
762 set_error(s, "<validation>", json_error_wrong_type, "Expected real, got %s",
763 type_name(root));
764 return -1;
767 if (!(s->flags & JSON_VALIDATE_ONLY)) {
768 double *target = va_arg(*ap, double *);
769 if (root)
770 *target = json_real_value(root);
773 return 0;
775 case 'F':
776 if (root && !json_is_number(root)) {
777 set_error(s, "<validation>", json_error_wrong_type, "Expected real or integer, got %s",
778 type_name(root));
779 return -1;
782 if (!(s->flags & JSON_VALIDATE_ONLY)) {
783 double *target = va_arg(*ap, double *);
784 if (root)
785 *target = json_number_value(root);
788 return 0;
790 case 'O':
791 if (root && !(s->flags & JSON_VALIDATE_ONLY))
792 json_incref(root);
793 /* Fall through */
795 case 'o':
796 if (!(s->flags & JSON_VALIDATE_ONLY)) {
797 json_t **target = va_arg(*ap, json_t **);
798 if (root)
799 *target = root;
802 return 0;
804 case 'n':
805 /* Never assign, just validate */
806 if (root && !json_is_null(root)) {
807 set_error(s, "<validation>", json_error_wrong_type, "Expected null, got %s",
808 type_name(root));
809 return -1;
811 return 0;
813 default:
814 set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
815 token(s));
816 return -1;
820 json_t *json_vpack_ex(json_error_t *error, size_t flags,
821 const char *fmt, va_list ap) {
822 scanner_t s;
823 va_list ap_copy;
824 json_t *value;
826 if (!fmt || !*fmt) {
827 jsonp_error_init(error, "<format>");
828 jsonp_error_set(error, -1, -1, 0, json_error_invalid_argument, "NULL or empty format string");
829 return NULL;
831 jsonp_error_init(error, NULL);
833 scanner_init(&s, error, flags, fmt);
834 next_token(&s);
836 va_copy(ap_copy, ap);
837 value = pack(&s, &ap_copy);
838 va_end(ap_copy);
840 /* This will cover all situations where s.has_error is true */
841 if (!value)
842 return NULL;
844 next_token(&s);
845 if (token(&s)) {
846 json_decref(value);
847 set_error(&s, "<format>", json_error_invalid_format, "Garbage after format string");
848 return NULL;
851 return value;
854 json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) {
855 json_t *value;
856 va_list ap;
858 va_start(ap, fmt);
859 value = json_vpack_ex(error, flags, fmt, ap);
860 va_end(ap);
862 return value;
865 json_t *json_pack(const char *fmt, ...) {
866 json_t *value;
867 va_list ap;
869 va_start(ap, fmt);
870 value = json_vpack_ex(NULL, 0, fmt, ap);
871 va_end(ap);
873 return value;
876 int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
877 const char *fmt, va_list ap) {
878 scanner_t s;
879 va_list ap_copy;
881 if (!root) {
882 jsonp_error_init(error, "<root>");
883 jsonp_error_set(error, -1, -1, 0, json_error_null_value, "NULL root value");
884 return -1;
887 if (!fmt || !*fmt) {
888 jsonp_error_init(error, "<format>");
889 jsonp_error_set(error, -1, -1, 0, json_error_invalid_argument, "NULL or empty format string");
890 return -1;
892 jsonp_error_init(error, NULL);
894 scanner_init(&s, error, flags, fmt);
895 next_token(&s);
897 va_copy(ap_copy, ap);
898 if (unpack(&s, root, &ap_copy)) {
899 va_end(ap_copy);
900 return -1;
902 va_end(ap_copy);
904 next_token(&s);
905 if (token(&s)) {
906 set_error(&s, "<format>", json_error_invalid_format, "Garbage after format string");
907 return -1;
910 return 0;
913 int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...) {
914 int ret;
915 va_list ap;
917 va_start(ap, fmt);
918 ret = json_vunpack_ex(root, error, flags, fmt, ap);
919 va_end(ap);
921 return ret;
924 int json_unpack(json_t *root, const char *fmt, ...) {
925 int ret;
926 va_list ap;
928 va_start(ap, fmt);
929 ret = json_vunpack_ex(root, NULL, 0, fmt, ap);
930 va_end(ap);
932 return ret;