diff --git a/doc/apiref.rst b/doc/apiref.rst index 6ab7a6f..48ff979 100644 --- a/doc/apiref.rst +++ b/doc/apiref.rst @@ -793,6 +793,15 @@ macros can be ORed together to obtain *flags*. .. versionadded:: 2.1 +``JSON_DISABLE_EOF_CHECK`` + By default, the decoder expects that its whole input constitutes a + valid JSON text, and issues an error if there's extra data after + the otherwise valid JSON input. With this flag enabled, the decoder + stops after decoding a valid JSON array or object, and thus allows + extra data after the JSON text. + + .. versionadded:: 2.1 + The following functions perform the actual JSON decoding. .. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error) diff --git a/src/jansson.h b/src/jansson.h index 9bdbb11..79f7ed5 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -217,6 +217,7 @@ json_t *json_deep_copy(json_t *value); /* 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); diff --git a/src/load.c b/src/load.c index 3dc8ac0..8a53f13 100644 --- a/src/load.c +++ b/src/load.c @@ -827,11 +827,13 @@ static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) if(!result) return NULL; - lex_scan(lex, error); - if(lex->token != TOKEN_EOF) { - error_set(error, lex, "end of file expected"); - json_decref(result); - result = 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; diff --git a/test/suites/api/test_load.c b/test/suites/api/test_load.c index 83143fb..2a60eb3 100644 --- a/test/suites/api/test_load.c +++ b/test/suites/api/test_load.c @@ -32,10 +32,29 @@ static void reject_duplicates() check_error("duplicate object key near '\"foo\"'", "", 1, 16, 16); } +static void disable_eof_check() +{ + json_error_t error; + json_t *json; + + const char *text = "{\"foo\": 1} garbage"; + + if(json_loads(text, 0, &error)) + fail("json_loads did not detect garbage after JSON text"); + check_error("end of file expected near 'garbage'", "", 1, 18, 18); + + json = json_loads(text, JSON_DISABLE_EOF_CHECK, &error); + if(!json) + fail("json_loads failed with JSON_DISABLE_EOF_CHECK"); + + json_decref(json); +} + int main() { file_not_found(); reject_duplicates(); + disable_eof_check(); return 0; }