Add JSON_DISABLE_EOF_CHECK decoding flag

With this flag enabled, the decoder stops after a valid JSON input and
thus allows extra data after it.

Fixes GH-25.
This commit is contained in:
Petri Lehtinen 2011-05-29 21:19:28 +03:00
parent 9febdf333c
commit a76ba52f34
4 changed files with 36 additions and 5 deletions

View File

@ -793,6 +793,15 @@ macros can be ORed together to obtain *flags*.
.. versionadded:: 2.1 .. 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. The following functions perform the actual JSON decoding.
.. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error) .. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error)

View File

@ -217,6 +217,7 @@ json_t *json_deep_copy(json_t *value);
/* decoding */ /* decoding */
#define JSON_REJECT_DUPLICATES 0x1 #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_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_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error);

View File

@ -827,11 +827,13 @@ static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)
if(!result) if(!result)
return NULL; return NULL;
lex_scan(lex, error); if(!(flags & JSON_DISABLE_EOF_CHECK)) {
if(lex->token != TOKEN_EOF) { lex_scan(lex, error);
error_set(error, lex, "end of file expected"); if(lex->token != TOKEN_EOF) {
json_decref(result); error_set(error, lex, "end of file expected");
result = NULL; json_decref(result);
result = NULL;
}
} }
return result; return result;

View File

@ -32,10 +32,29 @@ static void reject_duplicates()
check_error("duplicate object key near '\"foo\"'", "<string>", 1, 16, 16); check_error("duplicate object key near '\"foo\"'", "<string>", 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'", "<string>", 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() int main()
{ {
file_not_found(); file_not_found();
reject_duplicates(); reject_duplicates();
disable_eof_check();
return 0; return 0;
} }