mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 04:49:38 -07:00
jansson update. 2.11 to 2.12 (#724)
This commit is contained in:
parent
5594c6215e
commit
6a2bd85719
10 changed files with 190 additions and 151 deletions
|
@ -61,8 +61,8 @@ static int dump_to_file(const char *buffer, size_t size, void *data)
|
|||
|
||||
static int dump_to_fd(const char *buffer, size_t size, void *data)
|
||||
{
|
||||
int *dest = (int *)data;
|
||||
#ifdef HAVE_UNISTD_H
|
||||
int *dest = (int *)data;
|
||||
if(write(*dest, buffer, size) == (ssize_t)size)
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -101,7 +101,7 @@ static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t
|
|||
static int dump_string(const char *str, size_t len, json_dump_callback_t dump, void *data, size_t flags)
|
||||
{
|
||||
const char *pos, *end, *lim;
|
||||
int32_t codepoint;
|
||||
int32_t codepoint = 0;
|
||||
|
||||
if(dump("\"", 1, data))
|
||||
return -1;
|
||||
|
@ -306,7 +306,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|||
const char *separator;
|
||||
int separator_length;
|
||||
/* Space for "0x", double the sizeof a pointer for the hex and a terminator. */
|
||||
char key[2 + (sizeof(json) * 2) + 1];
|
||||
char loop_key[2 + (sizeof(json) * 2) + 1];
|
||||
|
||||
if(flags & JSON_COMPACT) {
|
||||
separator = ":";
|
||||
|
@ -318,7 +318,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|||
}
|
||||
|
||||
/* detect circular references */
|
||||
if (loop_check(parents, json, key, sizeof(key)))
|
||||
if (loop_check(parents, json, loop_key, sizeof(loop_key)))
|
||||
return -1;
|
||||
|
||||
iter = json_object_iter((json_t *)json);
|
||||
|
@ -326,7 +326,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|||
if(!embed && dump("{", 1, data))
|
||||
return -1;
|
||||
if(!iter) {
|
||||
hashtable_del(parents, key);
|
||||
hashtable_del(parents, loop_key);
|
||||
return embed ? 0 : dump("}", 1, data);
|
||||
}
|
||||
if(dump_indent(flags, depth + 1, 0, dump, data))
|
||||
|
@ -422,7 +422,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
|
|||
}
|
||||
}
|
||||
|
||||
hashtable_del(parents, key);
|
||||
hashtable_del(parents, loop_key);
|
||||
return embed ? 0 : dump("}", 1, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ typedef struct hashtable {
|
|||
*
|
||||
* Returns 0 on success, -1 on error (out of memory).
|
||||
*/
|
||||
int hashtable_init(hashtable_t *hashtable);
|
||||
int hashtable_init(hashtable_t *hashtable) JANSSON_ATTRS(warn_unused_result);
|
||||
|
||||
/**
|
||||
* hashtable_close - Release all resources used by a hashtable object
|
||||
|
|
|
@ -164,7 +164,7 @@ static int seed_from_timestamp_and_pid(uint32_t *seed) {
|
|||
}
|
||||
|
||||
static uint32_t generate_seed() {
|
||||
uint32_t seed;
|
||||
uint32_t seed = 0;
|
||||
int done = 0;
|
||||
|
||||
#if !defined(_WIN32) && defined(USE_URANDOM)
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#define JANSSON_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> /* for size_t */
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -22,11 +21,11 @@ extern "C" {
|
|||
/* version */
|
||||
|
||||
#define JANSSON_MAJOR_VERSION 2
|
||||
#define JANSSON_MINOR_VERSION 11
|
||||
#define JANSSON_MINOR_VERSION 12
|
||||
#define JANSSON_MICRO_VERSION 0
|
||||
|
||||
/* Micro version is omitted if it's 0 */
|
||||
#define JANSSON_VERSION "2.11"
|
||||
#define JANSSON_VERSION "2.12"
|
||||
|
||||
/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
|
||||
for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
|
||||
|
@ -40,6 +39,12 @@ extern "C" {
|
|||
#define JANSSON_THREAD_SAFE_REFCOUNT 1
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define JANSSON_ATTRS(...) __attribute__((__VA_ARGS__))
|
||||
#else
|
||||
#define JANSSON_ATTRS(...)
|
||||
#endif
|
||||
|
||||
/* types */
|
||||
|
||||
typedef enum {
|
||||
|
@ -186,7 +191,7 @@ static JSON_INLINE enum json_error_code json_error_code(const json_error_t *e) {
|
|||
|
||||
void json_object_seed(size_t seed);
|
||||
size_t json_object_size(const json_t *object);
|
||||
json_t *json_object_get(const json_t *object, const char *key);
|
||||
json_t *json_object_get(const json_t *object, const char *key) JANSSON_ATTRS(warn_unused_result);
|
||||
int json_object_set_new(json_t *object, const char *key, json_t *value);
|
||||
int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
|
||||
int json_object_del(json_t *object, const char *key);
|
||||
|
@ -238,7 +243,7 @@ int json_object_iter_set(json_t *object, void *iter, json_t *value)
|
|||
}
|
||||
|
||||
size_t json_array_size(const json_t *array);
|
||||
json_t *json_array_get(const json_t *array, size_t index);
|
||||
json_t *json_array_get(const json_t *array, size_t index) JANSSON_ATTRS(warn_unused_result);
|
||||
int json_array_set_new(json_t *array, size_t index, json_t *value);
|
||||
int json_array_append_new(json_t *array, json_t *value);
|
||||
int json_array_insert_new(json_t *array, size_t index, json_t *value);
|
||||
|
@ -279,9 +284,9 @@ int json_real_set(json_t *real, double value);
|
|||
|
||||
/* pack, unpack */
|
||||
|
||||
json_t *json_pack(const char *fmt, ...);
|
||||
json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...);
|
||||
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap);
|
||||
json_t *json_pack(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result);
|
||||
|
||||
#define JSON_VALIDATE_ONLY 0x1
|
||||
#define JSON_STRICT 0x2
|
||||
|
@ -292,8 +297,8 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char
|
|||
|
||||
/* sprintf */
|
||||
|
||||
json_t *json_sprintf(const char *fmt, ...);
|
||||
json_t *json_vsprintf(const char *fmt, va_list ap);
|
||||
json_t *json_sprintf(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 2));
|
||||
json_t *json_vsprintf(const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 0));
|
||||
|
||||
|
||||
/* equality */
|
||||
|
@ -303,10 +308,8 @@ int json_equal(const json_t *value1, const json_t *value2);
|
|||
|
||||
/* copying */
|
||||
|
||||
json_t *json_copy(json_t *value);
|
||||
json_t *json_deep_copy(const json_t *value);
|
||||
|
||||
/* path */
|
||||
json_t *json_copy(json_t *value) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_deep_copy(const json_t *value) JANSSON_ATTRS(warn_unused_result);
|
||||
|
||||
json_t *json_path_get(const json_t *json, const char *path);
|
||||
int json_path_set_new(json_t *json, const char *path, json_t *value, size_t flags, json_error_t *error);
|
||||
|
@ -327,12 +330,12 @@ int json_path_set(json_t *json, const char *path, json_t *value, size_t flags, j
|
|||
|
||||
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
|
||||
|
||||
json_t *json_loads(const char *input, size_t flags, json_error_t *error);
|
||||
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error);
|
||||
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error);
|
||||
json_t *json_loadfd(int input, size_t flags, json_error_t *error);
|
||||
json_t *json_load_file(const char *path, size_t flags, json_error_t *error);
|
||||
json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error);
|
||||
json_t *json_loads(const char *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loadfd(int input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_load_file(const char *path, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
|
||||
|
||||
/* encoding */
|
||||
|
@ -350,7 +353,7 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla
|
|||
|
||||
typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
|
||||
|
||||
char *json_dumps(const json_t *json, size_t flags);
|
||||
char *json_dumps(const json_t *json, size_t flags) JANSSON_ATTRS(warn_unused_result);
|
||||
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);
|
||||
int json_dumpf(const json_t *json, FILE *output, size_t flags);
|
||||
int json_dumpfd(const json_t *json, int output, size_t flags);
|
||||
|
|
|
@ -87,11 +87,11 @@ int jsonp_strtod(strbuffer_t *strbuffer, double *out);
|
|||
int jsonp_dtostr(char *buffer, size_t size, double value, int prec);
|
||||
|
||||
/* Wrappers for custom memory functions */
|
||||
void* jsonp_malloc(size_t size);
|
||||
void* jsonp_malloc(size_t size) JANSSON_ATTRS(warn_unused_result);
|
||||
void jsonp_free(void *ptr);
|
||||
char *jsonp_strndup(const char *str, size_t length);
|
||||
char *jsonp_strdup(const char *str);
|
||||
char *jsonp_strndup(const char *str, size_t len);
|
||||
char *jsonp_strndup(const char *str, size_t length) JANSSON_ATTRS(warn_unused_result);
|
||||
char *jsonp_strdup(const char *str) JANSSON_ATTRS(warn_unused_result);
|
||||
char *jsonp_strndup(const char *str, size_t len) JANSSON_ATTRS(warn_unused_result);
|
||||
|
||||
|
||||
/* Windows compatibility */
|
||||
|
|
|
@ -829,10 +829,8 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
|
|||
}
|
||||
|
||||
json = jsonp_stringn_nocheck_own(value, len);
|
||||
if(json) {
|
||||
lex->value.string.val = NULL;
|
||||
lex->value.string.len = 0;
|
||||
}
|
||||
lex->value.string.val = NULL;
|
||||
lex->value.string.len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1036,8 +1034,8 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
|
|||
|
||||
static int fd_get_func(int *fd)
|
||||
{
|
||||
uint8_t c;
|
||||
#ifdef HAVE_UNISTD_H
|
||||
uint8_t c;
|
||||
if (read(*fd, &c, 1) == 1)
|
||||
return c;
|
||||
#endif
|
||||
|
|
|
@ -75,6 +75,9 @@ static void next_token(scanner_t *s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!token(s) && !*s->fmt)
|
||||
return;
|
||||
|
||||
t = s->fmt;
|
||||
s->column++;
|
||||
s->pos++;
|
||||
|
@ -97,7 +100,7 @@ static void next_token(scanner_t *s)
|
|||
s->token.column = s->column;
|
||||
s->token.pos = s->pos;
|
||||
|
||||
t++;
|
||||
if (*t) t++;
|
||||
s->fmt = t;
|
||||
}
|
||||
|
||||
|
@ -127,7 +130,7 @@ static json_t *pack(scanner_t *s, va_list *ap);
|
|||
/* ours will be set to 1 if jsonp_free() must be called for the result
|
||||
afterwards */
|
||||
static char *read_string(scanner_t *s, va_list *ap,
|
||||
const char *purpose, size_t *out_len, int *ours)
|
||||
const char *purpose, size_t *out_len, int *ours, int optional)
|
||||
{
|
||||
char t;
|
||||
strbuffer_t strbuff;
|
||||
|
@ -144,7 +147,10 @@ static char *read_string(scanner_t *s, va_list *ap,
|
|||
str = va_arg(*ap, const char *);
|
||||
|
||||
if(!str) {
|
||||
set_error(s, "<args>", json_error_null_value, "NULL string argument");
|
||||
if (!optional) {
|
||||
set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
|
||||
s->has_error = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -152,19 +158,28 @@ static char *read_string(scanner_t *s, va_list *ap,
|
|||
|
||||
if(!utf8_check_string(str, length)) {
|
||||
set_error(s, "<args>", json_error_invalid_utf8, "Invalid UTF-8 %s", purpose);
|
||||
s->has_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*out_len = length;
|
||||
return (char *)str;
|
||||
} else if (optional) {
|
||||
set_error(s, "<format>", json_error_invalid_format, "Cannot use '%c' on optional strings", t);
|
||||
s->has_error = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strbuffer_init(&strbuff);
|
||||
if(strbuffer_init(&strbuff)) {
|
||||
set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
||||
s->has_error = 1;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
str = va_arg(*ap, const char *);
|
||||
if(!str) {
|
||||
set_error(s, "<args>", json_error_null_value, "NULL string argument");
|
||||
set_error(s, "<args>", json_error_null_value, "NULL %s", purpose);
|
||||
s->has_error = 1;
|
||||
}
|
||||
|
||||
|
@ -220,6 +235,7 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|||
size_t len;
|
||||
int ours;
|
||||
json_t *value;
|
||||
char valueOptional;
|
||||
|
||||
if(!token(s)) {
|
||||
set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
|
||||
|
@ -231,20 +247,21 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|||
goto error;
|
||||
}
|
||||
|
||||
key = read_string(s, ap, "object key", &len, &ours);
|
||||
if (!key)
|
||||
s->has_error = 1;
|
||||
key = read_string(s, ap, "object key", &len, &ours, 0);
|
||||
|
||||
next_token(s);
|
||||
|
||||
next_token(s);
|
||||
valueOptional = token(s);
|
||||
prev_token(s);
|
||||
|
||||
value = pack(s, ap);
|
||||
if(!value) {
|
||||
if(ours)
|
||||
jsonp_free(key);
|
||||
|
||||
if(strchr("soO", token(s)) && s->next_token.token == '*') {
|
||||
next_token(s);
|
||||
} else {
|
||||
if(valueOptional != '*') {
|
||||
set_error(s, "<args>", json_error_null_value, "NULL object value");
|
||||
s->has_error = 1;
|
||||
}
|
||||
|
||||
|
@ -263,8 +280,6 @@ static json_t *pack_object(scanner_t *s, va_list *ap)
|
|||
if(ours)
|
||||
jsonp_free(key);
|
||||
|
||||
if(strchr("soO", token(s)) && s->next_token.token == '*')
|
||||
next_token(s);
|
||||
next_token(s);
|
||||
}
|
||||
|
||||
|
@ -283,6 +298,7 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
|||
|
||||
while(token(s) != ']') {
|
||||
json_t *value;
|
||||
char valueOptional;
|
||||
|
||||
if(!token(s)) {
|
||||
set_error(s, "<format>", json_error_invalid_format, "Unexpected end of format string");
|
||||
|
@ -290,11 +306,13 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
|||
goto error;
|
||||
}
|
||||
|
||||
next_token(s);
|
||||
valueOptional = token(s);
|
||||
prev_token(s);
|
||||
|
||||
value = pack(s, ap);
|
||||
if(!value) {
|
||||
if(strchr("soO", token(s)) && s->next_token.token == '*') {
|
||||
next_token(s);
|
||||
} else {
|
||||
if(valueOptional != '*') {
|
||||
s->has_error = 1;
|
||||
}
|
||||
|
||||
|
@ -310,8 +328,6 @@ static json_t *pack_array(scanner_t *s, va_list *ap)
|
|||
s->has_error = 1;
|
||||
}
|
||||
|
||||
if(strchr("soO", token(s)) && s->next_token.token == '*')
|
||||
next_token(s);
|
||||
next_token(s);
|
||||
}
|
||||
|
||||
|
@ -326,23 +342,97 @@ error:
|
|||
static json_t *pack_string(scanner_t *s, va_list *ap)
|
||||
{
|
||||
char *str;
|
||||
char t;
|
||||
size_t len;
|
||||
int ours;
|
||||
int nullable;
|
||||
int optional;
|
||||
|
||||
next_token(s);
|
||||
nullable = token(s) == '?';
|
||||
if (!nullable)
|
||||
t = token(s);
|
||||
optional = t == '?' || t == '*';
|
||||
if (!optional)
|
||||
prev_token(s);
|
||||
|
||||
str = read_string(s, ap, "string", &len, &ours);
|
||||
if (!str) {
|
||||
return nullable ? json_null() : NULL;
|
||||
} else if (ours) {
|
||||
return jsonp_stringn_nocheck_own(str, len);
|
||||
} else {
|
||||
return json_stringn_nocheck(str, len);
|
||||
str = read_string(s, ap, "string", &len, &ours, optional);
|
||||
|
||||
if (!str)
|
||||
return t == '?' && !s->has_error ? json_null() : NULL;
|
||||
|
||||
if (s->has_error) {
|
||||
/* It's impossible to reach this point if ours != 0, do not free str. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ours)
|
||||
return jsonp_stringn_nocheck_own(str, len);
|
||||
|
||||
return json_stringn_nocheck(str, len);
|
||||
}
|
||||
|
||||
static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref)
|
||||
{
|
||||
json_t *json;
|
||||
char ntoken;
|
||||
|
||||
next_token(s);
|
||||
ntoken = token(s);
|
||||
|
||||
if (ntoken != '?' && ntoken != '*')
|
||||
prev_token(s);
|
||||
|
||||
json = va_arg(*ap, json_t *);
|
||||
|
||||
if (json)
|
||||
return need_incref ? json_incref(json) : json;
|
||||
|
||||
switch (ntoken) {
|
||||
case '?':
|
||||
return json_null();
|
||||
case '*':
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
set_error(s, "<args>", json_error_null_value, "NULL object");
|
||||
s->has_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static json_t *pack_integer(scanner_t *s, json_int_t value)
|
||||
{
|
||||
json_t *json = json_integer(value);
|
||||
|
||||
if (!json) {
|
||||
set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
||||
s->has_error = 1;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
static json_t *pack_real(scanner_t *s, double value)
|
||||
{
|
||||
/* Allocate without setting value so we can identify OOM error. */
|
||||
json_t *json = json_real(0.0);
|
||||
|
||||
if (!json) {
|
||||
set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
|
||||
s->has_error = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (json_real_set(json, value)) {
|
||||
json_decref(json);
|
||||
|
||||
set_error(s, "<args>", json_error_numeric_overflow, "Invalid floating point value");
|
||||
s->has_error = 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
static json_t *pack(scanner_t *s, va_list *ap)
|
||||
|
@ -364,49 +454,19 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
|||
return va_arg(*ap, int) ? json_true() : json_false();
|
||||
|
||||
case 'i': /* integer from int */
|
||||
return json_integer(va_arg(*ap, int));
|
||||
return pack_integer(s, va_arg(*ap, int));
|
||||
|
||||
case 'I': /* integer from json_int_t */
|
||||
return json_integer(va_arg(*ap, json_int_t));
|
||||
return pack_integer(s, va_arg(*ap, json_int_t));
|
||||
|
||||
case 'f': /* real */
|
||||
return json_real(va_arg(*ap, double));
|
||||
return pack_real(s, va_arg(*ap, double));
|
||||
|
||||
case 'O': /* a json_t object; increments refcount */
|
||||
{
|
||||
int nullable;
|
||||
json_t *json;
|
||||
|
||||
next_token(s);
|
||||
nullable = token(s) == '?';
|
||||
if (!nullable)
|
||||
prev_token(s);
|
||||
|
||||
json = va_arg(*ap, json_t *);
|
||||
if (!json && nullable) {
|
||||
return json_null();
|
||||
} else {
|
||||
return json_incref(json);
|
||||
}
|
||||
}
|
||||
return pack_object_inter(s, ap, 1);
|
||||
|
||||
case 'o': /* a json_t object; doesn't increment refcount */
|
||||
{
|
||||
int nullable;
|
||||
json_t *json;
|
||||
|
||||
next_token(s);
|
||||
nullable = token(s) == '?';
|
||||
if (!nullable)
|
||||
prev_token(s);
|
||||
|
||||
json = va_arg(*ap, json_t *);
|
||||
if (!json && nullable) {
|
||||
return json_null();
|
||||
} else {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
return pack_object_inter(s, ap, 0);
|
||||
|
||||
default:
|
||||
set_error(s, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
|
||||
|
@ -508,48 +568,34 @@ static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
|
|||
if(root && strict == 1) {
|
||||
/* We need to check that all non optional items have been parsed */
|
||||
const char *key;
|
||||
int have_unrecognized_keys = 0;
|
||||
/* keys_res is 1 for uninitialized, 0 for success, -1 for error. */
|
||||
int keys_res = 1;
|
||||
strbuffer_t unrecognized_keys;
|
||||
json_t *value;
|
||||
long unpacked = 0;
|
||||
if (gotopt) {
|
||||
/* We have optional keys, we need to iter on each key */
|
||||
|
||||
if (gotopt || json_object_size(root) != key_set.size) {
|
||||
json_object_foreach(root, key, value) {
|
||||
if(!hashtable_get(&key_set, key)) {
|
||||
unpacked++;
|
||||
|
||||
/* Save unrecognized keys for the error message */
|
||||
if (!have_unrecognized_keys) {
|
||||
strbuffer_init(&unrecognized_keys);
|
||||
have_unrecognized_keys = 1;
|
||||
} else {
|
||||
strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
|
||||
if (keys_res == 1) {
|
||||
keys_res = strbuffer_init(&unrecognized_keys);
|
||||
} else if (!keys_res) {
|
||||
keys_res = strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
|
||||
}
|
||||
strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
|
||||
|
||||
if (!keys_res)
|
||||
keys_res = strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No optional keys, we can just compare the number of items */
|
||||
unpacked = (long)json_object_size(root) - (long)key_set.size;
|
||||
}
|
||||
if (unpacked) {
|
||||
if (!gotopt) {
|
||||
/* Save unrecognized keys for the error message */
|
||||
json_object_foreach(root, key, value) {
|
||||
if(!hashtable_get(&key_set, key)) {
|
||||
if (!have_unrecognized_keys) {
|
||||
strbuffer_init(&unrecognized_keys);
|
||||
have_unrecognized_keys = 1;
|
||||
} else {
|
||||
strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
|
||||
}
|
||||
strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
set_error(s, "<validation>", json_error_end_of_input_expected,
|
||||
"%li object item(s) left unpacked: %s",
|
||||
unpacked, strbuffer_value(&unrecognized_keys));
|
||||
unpacked,
|
||||
keys_res ? "<unknown>" : strbuffer_value(&unrecognized_keys));
|
||||
strbuffer_close(&unrecognized_keys);
|
||||
goto out;
|
||||
}
|
||||
|
@ -805,6 +851,7 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
|
|||
value = pack(&s, &ap_copy);
|
||||
va_end(ap_copy);
|
||||
|
||||
/* This will cover all situations where s.has_error is true */
|
||||
if(!value)
|
||||
return NULL;
|
||||
|
||||
|
@ -814,10 +861,6 @@ json_t *json_vpack_ex(json_error_t *error, size_t flags,
|
|||
set_error(&s, "<format>", json_error_invalid_format, "Garbage after format string");
|
||||
return NULL;
|
||||
}
|
||||
if(s.has_error) {
|
||||
json_decref(value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <jansson.h>
|
||||
#include "jansson_private.h"
|
||||
|
||||
|
||||
json_t *json_path_get(const json_t *json, const char *path)
|
||||
{
|
||||
static const char root_chr = '$', array_open = '[';
|
||||
|
|
|
@ -16,7 +16,7 @@ typedef struct {
|
|||
size_t size; /* bytes allocated */
|
||||
} strbuffer_t;
|
||||
|
||||
int strbuffer_init(strbuffer_t *strbuff);
|
||||
int strbuffer_init(strbuffer_t *strbuff) JANSSON_ATTRS(warn_unused_result);
|
||||
void strbuffer_close(strbuffer_t *strbuff);
|
||||
|
||||
void strbuffer_clear(strbuffer_t *strbuff);
|
||||
|
|
|
@ -652,8 +652,7 @@ static json_t *string_create(const char *value, size_t len, int own)
|
|||
|
||||
string = jsonp_malloc(sizeof(json_string_t));
|
||||
if(!string) {
|
||||
if(!own)
|
||||
jsonp_free(v);
|
||||
jsonp_free(v);
|
||||
return NULL;
|
||||
}
|
||||
json_init(&string->json, JSON_STRING);
|
||||
|
@ -768,9 +767,6 @@ static int json_string_equal(const json_t *string1, const json_t *string2)
|
|||
{
|
||||
json_string_t *s1, *s2;
|
||||
|
||||
if(!json_is_string(string1) || !json_is_string(string2))
|
||||
return 0;
|
||||
|
||||
s1 = json_to_string(string1);
|
||||
s2 = json_to_string(string2);
|
||||
return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
|
||||
|
@ -780,34 +776,38 @@ static json_t *json_string_copy(const json_t *string)
|
|||
{
|
||||
json_string_t *s;
|
||||
|
||||
if(!json_is_string(string))
|
||||
return NULL;
|
||||
|
||||
s = json_to_string(string);
|
||||
return json_stringn_nocheck(s->value, s->length);
|
||||
}
|
||||
|
||||
json_t *json_vsprintf(const char *fmt, va_list ap) {
|
||||
json_t *json = NULL;
|
||||
int length;
|
||||
char *buf;
|
||||
va_list aq;
|
||||
va_copy(aq, ap);
|
||||
|
||||
length = vsnprintf(NULL, 0, fmt, ap);
|
||||
if (length == 0)
|
||||
return json_string("");
|
||||
if (length == 0) {
|
||||
json = json_string("");
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = jsonp_malloc(length + 1);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
vsnprintf(buf, length + 1, fmt, aq);
|
||||
if (!utf8_check_string(buf, length)) {
|
||||
jsonp_free(buf);
|
||||
return NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return jsonp_stringn_nocheck_own(buf, length);
|
||||
json = jsonp_stringn_nocheck_own(buf, length);
|
||||
|
||||
out:
|
||||
va_end(aq);
|
||||
return json;
|
||||
}
|
||||
|
||||
json_t *json_sprintf(const char *fmt, ...) {
|
||||
|
@ -1044,8 +1044,6 @@ json_t *json_copy(json_t *json)
|
|||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_t *json_deep_copy(const json_t *json)
|
||||
|
@ -1073,6 +1071,4 @@ json_t *json_deep_copy(const json_t *json)
|
|||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue