diff --git a/3party/jansson/CHANGES b/3party/jansson/CHANGES index 3434e48a04..5e002d54d9 100644 --- a/3party/jansson/CHANGES +++ b/3party/jansson/CHANGES @@ -1,3 +1,36 @@ +Version 2.1 (in development) +============================ + +* New features: + + - `json_loadb()`: Decode a string with a given size, useful if the + string is not null terminated. + + - Add ``JSON_ENCODE_ANY`` encoding flag to allow encoding any JSON + value. By default, only arrays and objects can be encoded. (#19) + + - Add ``JSON_REJECT_DUPLICATES`` decoding flag to issue a decoding + error if any JSON object in the input contins duplicate keys. (#3) + + - Add ``JSON_DISABLE_EOF_CHECK`` decoding flag to stop decoding after a + valid JSON input. This allows other data after the JSON data. + +* Bug fixes: + + - Fix an additional memory leak when memory allocation fails in + `json_object_set()` and friends. + + - Clear errno before calling `strtod()` for better portability. (#27) + +* Building: + + - Avoid set-but-not-used warning/error in a test. (#20) + +* Other: + + - Minor clarifications to documentation. + + Version 2.0.1 ============= @@ -10,7 +43,7 @@ Released 2011-03-31 - Fix object key hashing in json_unpack() strict checking mode. - - Fix the parentheses in JANSSON_VERSION_HEX macro. + - Fix the parentheses in ``JANSSON_VERSION_HEX`` macro. - Fix `json_object_size()` return value. diff --git a/3party/jansson/jansson.pro b/3party/jansson/jansson.pro index 8091e91dde..1b20fdb406 100644 --- a/3party/jansson/jansson.pro +++ b/3party/jansson/jansson.pro @@ -23,5 +23,4 @@ HEADERS += \ src/hashtable.h \ src/strbuffer.h \ src/utf.h \ - src/util.h \ src/jansson_config.h \ diff --git a/3party/jansson/src/config.h b/3party/jansson/src/config.h deleted file mode 100644 index c1d6cd3533..0000000000 --- a/3party/jansson/src/config.h +++ /dev/null @@ -1,53 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#ifndef _MSC_VER -#define HAVE_INTTYPES_H 1 -#endif - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus - #ifdef _MSC_VER - #define JSON_INLINE - #else - #define JSON_INLINE inline - #endif -#else - #define JSON_INLINE inline -#endif - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int32_t */ diff --git a/3party/jansson/src/dump.c b/3party/jansson/src/dump.c index 9c013665c6..f32f66760b 100644 --- a/3party/jansson/src/dump.c +++ b/3party/jansson/src/dump.c @@ -421,8 +421,10 @@ char *json_dumps(const json_t *json, size_t flags) strbuffer_t strbuff; char *result; - if(!json_is_array(json) && !json_is_object(json)) - return NULL; + if(!(flags & JSON_ENCODE_ANY)) { + if(!json_is_array(json) && !json_is_object(json)) + return NULL; + } if(strbuffer_init(&strbuff)) return NULL; @@ -440,8 +442,10 @@ char *json_dumps(const json_t *json, size_t flags) int json_dumpf(const json_t *json, FILE *output, size_t flags) { - if(!json_is_array(json) && !json_is_object(json)) - return -1; + if(!(flags & JSON_ENCODE_ANY)) { + if(!json_is_array(json) && !json_is_object(json)) + return -1; + } return do_dump(json, flags, 0, dump_to_file, (void *)output); } diff --git a/3party/jansson/src/jansson.h b/3party/jansson/src/jansson.h index eb24aed87a..3abb4cfc13 100644 --- a/3party/jansson/src/jansson.h +++ b/3party/jansson/src/jansson.h @@ -21,11 +21,11 @@ extern "C" { /* version */ #define JANSSON_MAJOR_VERSION 2 -#define JANSSON_MINOR_VERSION 0 -#define JANSSON_MICRO_VERSION 1 +#define JANSSON_MINOR_VERSION 1 +#define JANSSON_MICRO_VERSION 0 /* Micro version is omitted if it's 0 */ -#define JANSSON_VERSION "2.0.1" +#define JANSSON_VERSION "2.1" /* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ @@ -214,17 +214,25 @@ json_t *json_copy(json_t *value); json_t *json_deep_copy(json_t *value); -/* loading, printing */ +/* decoding */ + +#define JSON_REJECT_DUPLICATES 0x1 +#define JSON_DISABLE_EOF_CHECK 0x2 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_load_file(const char *path, size_t flags, json_error_t *error); + +/* encoding */ + #define JSON_INDENT(n) (n & 0x1F) #define JSON_COMPACT 0x20 #define JSON_ENSURE_ASCII 0x40 #define JSON_SORT_KEYS 0x80 #define JSON_PRESERVE_ORDER 0x100 +#define JSON_ENCODE_ANY 0x200 char *json_dumps(const json_t *json, size_t flags); int json_dumpf(const json_t *json, FILE *output, size_t flags); diff --git a/3party/jansson/src/load.c b/3party/jansson/src/load.c index 7232d31b78..8a53f135f9 100644 --- a/3party/jansson/src/load.c +++ b/3party/jansson/src/load.c @@ -643,9 +643,9 @@ static void lex_close(lex_t *lex) /*** parser ***/ -static json_t *parse_value(lex_t *lex, json_error_t *error); +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error); -static json_t *parse_object(lex_t *lex, json_error_t *error) +static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error) { json_t *object = json_object(); if(!object) @@ -668,6 +668,14 @@ static json_t *parse_object(lex_t *lex, json_error_t *error) if(!key) return NULL; + if(flags & JSON_REJECT_DUPLICATES) { + if(json_object_get(object, key)) { + jsonp_free(key); + error_set(error, lex, "duplicate object key"); + goto error; + } + } + lex_scan(lex, error); if(lex->token != ':') { jsonp_free(key); @@ -676,7 +684,7 @@ static json_t *parse_object(lex_t *lex, json_error_t *error) } lex_scan(lex, error); - value = parse_value(lex, error); + value = parse_value(lex, flags, error); if(!value) { jsonp_free(key); goto error; @@ -710,7 +718,7 @@ error: return NULL; } -static json_t *parse_array(lex_t *lex, json_error_t *error) +static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error) { json_t *array = json_array(); if(!array) @@ -721,7 +729,7 @@ static json_t *parse_array(lex_t *lex, json_error_t *error) return array; while(lex->token) { - json_t *elem = parse_value(lex, error); + json_t *elem = parse_value(lex, flags, error); if(!elem) goto error; @@ -750,7 +758,7 @@ error: return NULL; } -static json_t *parse_value(lex_t *lex, json_error_t *error) +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error) { json_t *json; @@ -783,11 +791,11 @@ static json_t *parse_value(lex_t *lex, json_error_t *error) break; case '{': - json = parse_object(lex, error); + json = parse_object(lex, flags, error); break; case '[': - json = parse_array(lex, error); + json = parse_array(lex, flags, error); break; case TOKEN_INVALID: @@ -805,15 +813,30 @@ static json_t *parse_value(lex_t *lex, json_error_t *error) return json; } -static json_t *parse_json(lex_t *lex, json_error_t *error) +static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) { + json_t *result; + lex_scan(lex, error); if(lex->token != '[' && lex->token != '{') { error_set(error, lex, "'[' or '{' expected"); return NULL; } - return parse_value(lex, error); + result = parse_value(lex, flags, error); + if(!result) + return NULL; + + if(!(flags & JSON_DISABLE_EOF_CHECK)) { + lex_scan(lex, error); + if(lex->token != TOKEN_EOF) { + error_set(error, lex, "end of file expected"); + json_decref(result); + result = NULL; + } + } + + return result; } typedef struct @@ -842,8 +865,6 @@ json_t *json_loads(const char *string, size_t flags, json_error_t *error) json_t *result; string_data_t stream_data; - (void)flags; /* unused */ - stream_data.data = string; stream_data.pos = 0; @@ -851,19 +872,47 @@ json_t *json_loads(const char *string, size_t flags, json_error_t *error) return NULL; jsonp_error_init(error, ""); + result = parse_json(&lex, flags, error); - result = parse_json(&lex, error); - if(!result) - goto out; + lex_close(&lex); + return result; +} - lex_scan(&lex, error); - if(lex.token != TOKEN_EOF) { - error_set(error, &lex, "end of file expected"); - json_decref(result); - result = NULL; - } +typedef struct +{ + const char *data; + size_t len; + size_t pos; +} buffer_data_t; + +static int buffer_get(void *data) +{ + char c; + buffer_data_t *stream = data; + if(stream->pos >= stream->len) + return EOF; + + c = stream->data[stream->pos]; + stream->pos++; + return (unsigned char)c; +} + +json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) +{ + lex_t lex; + json_t *result; + buffer_data_t stream_data; + + stream_data.data = buffer; + stream_data.pos = 0; + stream_data.len = buflen; + + if(lex_init(&lex, buffer_get, (void *)&stream_data)) + return NULL; + + jsonp_error_init(error, ""); + result = parse_json(&lex, flags, error); -out: lex_close(&lex); return result; } @@ -873,7 +922,6 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) lex_t lex; const char *source; json_t *result; - (void)flags; /* unused */ if(lex_init(&lex, (get_func)fgetc, input)) return NULL; @@ -884,19 +932,8 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) source = ""; jsonp_error_init(error, source); + result = parse_json(&lex, flags, error); - result = parse_json(&lex, error); - if(!result) - goto out; - - lex_scan(&lex, error); - if(lex.token != TOKEN_EOF) { - error_set(error, &lex, "end of file expected"); - json_decref(result); - result = NULL; - } - -out: lex_close(&lex); return result; } diff --git a/3party/jansson/src/util.h b/3party/jansson/src/util.h deleted file mode 100644 index 49b3a17755..0000000000 --- a/3party/jansson/src/util.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2009, 2010 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef UTIL_H -#define UTIL_H - -#ifndef max - #define max(a, b) ((a) > (b) ? (a) : (b)) -#endif - -#endif diff --git a/3party/jansson/src/value.c b/3party/jansson/src/value.c index 5d8ae22ce0..47ebb2c8bd 100644 --- a/3party/jansson/src/value.c +++ b/3party/jansson/src/value.c @@ -139,7 +139,10 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) allocated. */ k = jsonp_malloc(offsetof(object_key_t, key) + strlen(key) + 1); if(!k) + { + json_decref(value); return -1; + } k->serial = object->serial++; strcpy(k->key, key);