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.
11 #include "jansson_private.h"
35 #define token(scanner) ((scanner)->token.token)
37 static const char * const type_names
[] = {
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
)
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
));
67 static void next_token(scanner_t
*s
)
70 s
->prev_token
= s
->token
;
72 if(s
->next_token
.line
) {
73 s
->token
= s
->next_token
;
74 s
->next_token
.line
= 0;
82 /* skip space and ignored chars */
83 while(*t
== ' ' || *t
== '\t' || *t
== '\n' || *t
== ',' || *t
== ':') {
96 s
->token
.line
= s
->line
;
97 s
->token
.column
= s
->column
;
98 s
->token
.pos
= s
->pos
;
104 static void prev_token(scanner_t
*s
)
106 s
->next_token
= s
->token
;
107 s
->token
= s
->prev_token
;
110 static void set_error(scanner_t
*s
, const char *source
, enum json_error_code code
,
111 const char *fmt
, ...)
116 jsonp_error_vset(s
->error
, s
->token
.line
, s
->token
.column
, s
->token
.pos
,
119 jsonp_error_set_source(s
->error
, source
);
124 static json_t
*pack(scanner_t
*s
, va_list *ap
);
127 /* ours will be set to 1 if jsonp_free() must be called for the result
129 static char *read_string(scanner_t
*s
, va_list *ap
,
130 const char *purpose
, size_t *out_len
, int *ours
)
142 if(t
!= '#' && t
!= '%' && t
!= '+') {
143 /* Optimize the simple case */
144 str
= va_arg(*ap
, const char *);
147 set_error(s
, "<args>", json_error_null_value
, "NULL string argument");
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
);
162 strbuffer_init(&strbuff
);
165 str
= va_arg(*ap
, const char *);
167 set_error(s
, "<args>", json_error_null_value
, "NULL string argument");
173 if(token(s
) == '#') {
174 length
= va_arg(*ap
, int);
176 else if(token(s
) == '%') {
177 length
= va_arg(*ap
, size_t);
181 length
= s
->has_error
? 0 : strlen(str
);
184 if(!s
->has_error
&& strbuffer_append_bytes(&strbuff
, str
, length
) == -1) {
185 set_error(s
, "<internal>", json_error_out_of_memory
, "Out of memory");
190 if(token(s
) != '+') {
197 strbuffer_close(&strbuff
);
201 if(!utf8_check_string(strbuff
.value
, strbuff
.length
)) {
202 set_error(s
, "<args>", json_error_invalid_utf8
, "Invalid UTF-8 %s", purpose
);
203 strbuffer_close(&strbuff
);
208 *out_len
= strbuff
.length
;
210 return strbuffer_steal_value(&strbuff
);
213 static json_t
*pack_object(scanner_t
*s
, va_list *ap
)
215 json_t
*object
= json_object();
218 while(token(s
) != '}') {
225 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected end of format string");
229 if(token(s
) != 's') {
230 set_error(s
, "<format>", json_error_invalid_format
, "Expected format 's', got '%c'", token(s
));
234 key
= read_string(s
, ap
, "object key", &len
, &ours
);
245 if(strchr("soO", token(s
)) && s
->next_token
.token
== '*') {
258 if(!s
->has_error
&& json_object_set_new_nocheck(object
, key
, value
)) {
259 set_error(s
, "<internal>", json_error_out_of_memory
, "Unable to add key \"%s\"", key
);
266 if(strchr("soO", token(s
)) && s
->next_token
.token
== '*')
279 static json_t
*pack_array(scanner_t
*s
, va_list *ap
)
281 json_t
*array
= json_array();
284 while(token(s
) != ']') {
288 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected end of format string");
289 /* Format string errors are unrecoverable. */
295 if(strchr("soO", token(s
)) && s
->next_token
.token
== '*') {
308 if(!s
->has_error
&& json_array_append_new(array
, value
)) {
309 set_error(s
, "<internal>", json_error_out_of_memory
, "Unable to append to array");
313 if(strchr("soO", token(s
)) && s
->next_token
.token
== '*')
326 static json_t
*pack_string(scanner_t
*s
, va_list *ap
)
334 nullable
= token(s
) == '?';
338 str
= read_string(s
, ap
, "string", &len
, &ours
);
340 return nullable
? json_null() : NULL
;
342 return jsonp_stringn_nocheck_own(str
, len
);
344 return json_stringn_nocheck(str
, len
);
348 static json_t
*pack(scanner_t
*s
, va_list *ap
)
352 return pack_object(s
, ap
);
355 return pack_array(s
, ap
);
357 case 's': /* string */
358 return pack_string(s
, ap
);
363 case 'b': /* boolean */
364 return va_arg(*ap
, int) ? json_true() : json_false();
366 case 'i': /* integer from int */
367 return json_integer(va_arg(*ap
, int));
369 case 'I': /* integer from json_int_t */
370 return json_integer(va_arg(*ap
, json_int_t
));
373 return json_real(va_arg(*ap
, double));
375 case 'O': /* a json_t object; increments refcount */
381 nullable
= token(s
) == '?';
385 json
= va_arg(*ap
, json_t
*);
386 if (!json
&& nullable
) {
389 return json_incref(json
);
393 case 'o': /* a json_t object; doesn't increment refcount */
399 nullable
= token(s
) == '?';
403 json
= va_arg(*ap
, json_t
*);
404 if (!json
&& nullable
) {
412 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected format character '%c'",
419 static int unpack(scanner_t
*s
, json_t
*root
, va_list *ap
);
421 static int unpack_object(scanner_t
*s
, json_t
*root
, va_list *ap
)
427 /* Use a set (emulated by a hashtable) to check that all object
428 keys are accessed. Checking that the correct number of keys
429 were accessed is not enough, as the same key can be unpacked
434 if(hashtable_init(&key_set
)) {
435 set_error(s
, "<internal>", json_error_out_of_memory
, "Out of memory");
439 if(root
&& !json_is_object(root
)) {
440 set_error(s
, "<validation>", json_error_wrong_type
, "Expected object, got %s",
446 while(token(s
) != '}') {
452 set_error(s
, "<format>", json_error_invalid_format
, "Expected '}' after '%c', got '%c'",
453 (strict
== 1 ? '!' : '*'), token(s
));
458 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected end of format string");
462 if(token(s
) == '!' || token(s
) == '*') {
463 strict
= (token(s
) == '!' ? 1 : -1);
468 if(token(s
) != 's') {
469 set_error(s
, "<format>", json_error_invalid_format
, "Expected format 's', got '%c'", token(s
));
473 key
= va_arg(*ap
, const char *);
475 set_error(s
, "<args>", json_error_null_value
, "NULL object key");
481 if(token(s
) == '?') {
491 value
= json_object_get(root
, key
);
493 set_error(s
, "<validation>", json_error_item_not_found
, "Object item not found: %s", key
);
498 if(unpack(s
, value
, ap
))
501 hashtable_set(&key_set
, key
, json_null());
505 if(strict
== 0 && (s
->flags
& JSON_STRICT
))
508 if(root
&& strict
== 1) {
509 /* We need to check that all non optional items have been parsed */
511 int have_unrecognized_keys
= 0;
512 strbuffer_t unrecognized_keys
;
516 /* We have optional keys, we need to iter on each key */
517 json_object_foreach(root
, key
, value
) {
518 if(!hashtable_get(&key_set
, key
)) {
521 /* Save unrecognized keys for the error message */
522 if (!have_unrecognized_keys
) {
523 strbuffer_init(&unrecognized_keys
);
524 have_unrecognized_keys
= 1;
526 strbuffer_append_bytes(&unrecognized_keys
, ", ", 2);
528 strbuffer_append_bytes(&unrecognized_keys
, key
, strlen(key
));
532 /* No optional keys, we can just compare the number of items */
533 unpacked
= (long)json_object_size(root
) - (long)key_set
.size
;
537 /* Save unrecognized keys for the error message */
538 json_object_foreach(root
, key
, value
) {
539 if(!hashtable_get(&key_set
, key
)) {
540 if (!have_unrecognized_keys
) {
541 strbuffer_init(&unrecognized_keys
);
542 have_unrecognized_keys
= 1;
544 strbuffer_append_bytes(&unrecognized_keys
, ", ", 2);
546 strbuffer_append_bytes(&unrecognized_keys
, key
, strlen(key
));
550 set_error(s
, "<validation>", json_error_end_of_input_expected
,
551 "%li object item(s) left unpacked: %s",
552 unpacked
, strbuffer_value(&unrecognized_keys
));
553 strbuffer_close(&unrecognized_keys
);
561 hashtable_close(&key_set
);
565 static int unpack_array(scanner_t
*s
, json_t
*root
, va_list *ap
)
570 if(root
&& !json_is_array(root
)) {
571 set_error(s
, "<validation>", json_error_wrong_type
, "Expected array, got %s", type_name(root
));
576 while(token(s
) != ']') {
580 set_error(s
, "<format>", json_error_invalid_format
, "Expected ']' after '%c', got '%c'",
581 (strict
== 1 ? '!' : '*'),
587 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected end of format string");
591 if(token(s
) == '!' || token(s
) == '*') {
592 strict
= (token(s
) == '!' ? 1 : -1);
597 if(!strchr(unpack_value_starters
, token(s
))) {
598 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected format character '%c'",
608 value
= json_array_get(root
, i
);
610 set_error(s
, "<validation>", json_error_index_out_of_range
, "Array index %lu out of range",
616 if(unpack(s
, value
, ap
))
623 if(strict
== 0 && (s
->flags
& JSON_STRICT
))
626 if(root
&& strict
== 1 && i
!= json_array_size(root
)) {
627 long diff
= (long)json_array_size(root
) - (long)i
;
628 set_error(s
, "<validation>", json_error_end_of_input_expected
, "%li array item(s) left unpacked", diff
);
635 static int unpack(scanner_t
*s
, json_t
*root
, va_list *ap
)
640 return unpack_object(s
, root
, ap
);
643 return unpack_array(s
, root
, ap
);
646 if(root
&& !json_is_string(root
)) {
647 set_error(s
, "<validation>", json_error_wrong_type
, "Expected string, got %s",
652 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
653 const char **str_target
;
654 size_t *len_target
= NULL
;
656 str_target
= va_arg(*ap
, const char **);
658 set_error(s
, "<args>", json_error_null_value
, "NULL string argument");
664 if(token(s
) == '%') {
665 len_target
= va_arg(*ap
, size_t *);
667 set_error(s
, "<args>", json_error_null_value
, "NULL string length argument");
675 *str_target
= json_string_value(root
);
677 *len_target
= json_string_length(root
);
683 if(root
&& !json_is_integer(root
)) {
684 set_error(s
, "<validation>", json_error_wrong_type
, "Expected integer, got %s",
689 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
690 int *target
= va_arg(*ap
, int*);
692 *target
= (int)json_integer_value(root
);
698 if(root
&& !json_is_integer(root
)) {
699 set_error(s
, "<validation>", json_error_wrong_type
, "Expected integer, got %s",
704 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
705 json_int_t
*target
= va_arg(*ap
, json_int_t
*);
707 *target
= json_integer_value(root
);
713 if(root
&& !json_is_boolean(root
)) {
714 set_error(s
, "<validation>", json_error_wrong_type
, "Expected true or false, got %s",
719 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
720 int *target
= va_arg(*ap
, int*);
722 *target
= json_is_true(root
);
728 if(root
&& !json_is_real(root
)) {
729 set_error(s
, "<validation>", json_error_wrong_type
, "Expected real, got %s",
734 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
735 double *target
= va_arg(*ap
, double*);
737 *target
= json_real_value(root
);
743 if(root
&& !json_is_number(root
)) {
744 set_error(s
, "<validation>", json_error_wrong_type
, "Expected real or integer, got %s",
749 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
750 double *target
= va_arg(*ap
, double*);
752 *target
= json_number_value(root
);
758 if(root
&& !(s
->flags
& JSON_VALIDATE_ONLY
))
763 if(!(s
->flags
& JSON_VALIDATE_ONLY
)) {
764 json_t
**target
= va_arg(*ap
, json_t
**);
772 /* Never assign, just validate */
773 if(root
&& !json_is_null(root
)) {
774 set_error(s
, "<validation>", json_error_wrong_type
, "Expected null, got %s",
781 set_error(s
, "<format>", json_error_invalid_format
, "Unexpected format character '%c'",
787 json_t
*json_vpack_ex(json_error_t
*error
, size_t flags
,
788 const char *fmt
, va_list ap
)
795 jsonp_error_init(error
, "<format>");
796 jsonp_error_set(error
, -1, -1, 0, json_error_invalid_argument
, "NULL or empty format string");
799 jsonp_error_init(error
, NULL
);
801 scanner_init(&s
, error
, flags
, fmt
);
804 va_copy(ap_copy
, ap
);
805 value
= pack(&s
, &ap_copy
);
814 set_error(&s
, "<format>", json_error_invalid_format
, "Garbage after format string");
825 json_t
*json_pack_ex(json_error_t
*error
, size_t flags
, const char *fmt
, ...)
831 value
= json_vpack_ex(error
, flags
, fmt
, ap
);
837 json_t
*json_pack(const char *fmt
, ...)
843 value
= json_vpack_ex(NULL
, 0, fmt
, ap
);
849 int json_vunpack_ex(json_t
*root
, json_error_t
*error
, size_t flags
,
850 const char *fmt
, va_list ap
)
856 jsonp_error_init(error
, "<root>");
857 jsonp_error_set(error
, -1, -1, 0, json_error_null_value
, "NULL root value");
862 jsonp_error_init(error
, "<format>");
863 jsonp_error_set(error
, -1, -1, 0, json_error_invalid_argument
, "NULL or empty format string");
866 jsonp_error_init(error
, NULL
);
868 scanner_init(&s
, error
, flags
, fmt
);
871 va_copy(ap_copy
, ap
);
872 if(unpack(&s
, root
, &ap_copy
)) {
880 set_error(&s
, "<format>", json_error_invalid_format
, "Garbage after format string");
887 int json_unpack_ex(json_t
*root
, json_error_t
*error
, size_t flags
, const char *fmt
, ...)
893 ret
= json_vunpack_ex(root
, error
, flags
, fmt
, ap
);
899 int json_unpack(json_t
*root
, const char *fmt
, ...)
905 ret
= json_vunpack_ex(root
, NULL
, 0, fmt
, ap
);