From: Petri Lehtinen Date: Mon, 14 Nov 2011 19:16:42 +0000 (+0200) Subject: Merge branch '2.2' X-Git-Tag: v2.4-moonshot~1^2~48 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=bb24697d9b83371a8687f54edfc5d624b7c4d80d;hp=c4a7bf90cf7a1b6fb1c701e2d071d1e236259e70;p=jansson.git Merge branch '2.2' --- diff --git a/doc/apiref.rst b/doc/apiref.rst index 7d69004..d6b89e3 100644 --- a/doc/apiref.rst +++ b/doc/apiref.rst @@ -737,8 +737,7 @@ can be ORed together to obtain *flags*. **Note:** Encoding any value may be useful in some scenarios, but it's generally discouraged as it violates strict compatiblity with :rfc:`4627`. If you use this flag, don't expect interoperatibility - with other JSON systems. Even Jansson itself doesn't have any means - to decode JSON texts whose root value is not object or array. + with other JSON systems. .. versionadded:: 2.1 @@ -800,7 +799,8 @@ text to the Jansson representation of JSON data. The JSON specification requires that a JSON text is either a serialized array or object, and this requirement is also enforced with the following functions. In other words, the top level value in the JSON text being -decoded must be either array or object. +decoded must be either array or object. To decode any JSON value, use +the ``JSON_DECODE_ANY`` flag (see below). See :ref:`rfc-conformance` for a discussion on Jansson's conformance to the JSON specification. It explains many design decisions that @@ -828,6 +828,17 @@ macros can be ORed together to obtain *flags*. .. versionadded:: 2.1 +``JSON_DECODE_ANY`` + By default, the decoder expects an array or object as the input. + With this flag enabled, the decoder accepts any valid JSON value. + + **Note:** Decoding any value may be useful in some scenarios, but + it's generally discouraged as it violates strict compatiblity with + :rfc:`4627`. If you use this flag, don't expect interoperatibility + with other JSON systems. + + .. versionadded:: 2.3 + The following functions perform the actual JSON decoding. .. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error) @@ -869,6 +880,14 @@ The following functions perform the actual JSON decoding. multiple times, if the input consists of consecutive JSON texts, possibly separated by whitespace. + If both ``JSON_DISABLE_EOF_CHECK`` and ``JSON_DECODE_ANY`` flags + are used, the decoder may read one extra UTF-8 code unit (up to 4 + bytes of input). For example, decoding ``4true`` correctly decodes + the integer 4, but leaves the file position pointing at ``r`` + instead of ``t``. For this reason, if reading multiple consecutive + values that are not arrays and objects, they should be separated by + at least one whitespace character. + .. function:: json_t *json_load_file(const char *path, size_t flags, json_error_t *error) .. refcounting:: new diff --git a/src/jansson.h b/src/jansson.h index 405c840..ca9ac11 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -222,6 +222,7 @@ json_t *json_deep_copy(json_t *value); #define JSON_REJECT_DUPLICATES 0x1 #define JSON_DISABLE_EOF_CHECK 0x2 +#define JSON_DECODE_ANY 0x4 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); diff --git a/src/load.c b/src/load.c index 3fdec8f..f5cbf68 100644 --- a/src/load.c +++ b/src/load.c @@ -820,9 +820,11 @@ 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; + if(!(flags & JSON_DECODE_ANY)) { + if(lex->token != '[' && lex->token != '{') { + error_set(error, lex, "'[' or '{' expected"); + return NULL; + } } result = parse_value(lex, flags, error); diff --git a/test/suites/api/test_load.c b/test/suites/api/test_load.c index 810b745..8143d46 100644 --- a/test/suites/api/test_load.c +++ b/test/suites/api/test_load.c @@ -50,6 +50,32 @@ static void disable_eof_check() json_decref(json); } +static void decode_any() +{ + json_t *json; + json_error_t error; + + json = json_loads("\"foo\"", JSON_DECODE_ANY, &error); + if (!json || !json_is_string(json)) + fail("json_load decoded any failed - string"); + json_decref(json); + + json = json_loads("42", JSON_DECODE_ANY, &error); + if (!json || !json_is_integer(json)) + fail("json_load decoded any failed - integer"); + json_decref(json); + + json = json_loads("true", JSON_DECODE_ANY, &error); + if (!json || !json_is_true(json)) + fail("json_load decoded any failed - boolean"); + json_decref(json); + + json = json_loads("null", JSON_DECODE_ANY, &error); + if (!json || !json_is_null(json)) + fail("json_load decoded any failed - null"); + json_decref(json); +} + static void load_wrong_args() { json_t *json; @@ -77,5 +103,6 @@ static void run_tests() file_not_found(); reject_duplicates(); disable_eof_check(); + decode_any(); load_wrong_args(); }