From ceb496e5f086a7fc922b8f7e2b1bc38410752306 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 19 Jun 2015 17:28:22 -0600 Subject: [PATCH] json: fully parse input string I was adding a JSON test, and was shocked to find out our parser treated the input string of "1" as invalid JSON. It turns out that YAJL specifically documents that it buffers input, and that if the last input read could be a prefix to a longer token, then you have to explicitly tell the parser that the buffer has ended before that token will be processed. It doesn't help that yajl 2 renamed the function from what it was in yajl 1. * src/util/virjson.c (virJSONValueFromString): Complete parse, in case buffer ends in possible token prefix. * tests/jsontest.c (mymain): Expose the problem. Signed-off-by: Eric Blake --- src/util/virjson.c | 4 +++- tests/jsontest.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/util/virjson.c b/src/util/virjson.c index 40ec613a4f..7d4ece6465 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -38,6 +38,7 @@ # define yajl_size_t size_t # else # define yajl_size_t unsigned int +# define yajl_complete_parse yajl_parse_complete # endif #endif @@ -1610,7 +1611,8 @@ virJSONValueFromString(const char *jsonstring) if (yajl_parse(hand, (const unsigned char *)jsonstring, - strlen(jsonstring)) != yajl_status_ok) { + strlen(jsonstring)) != yajl_status_ok || + yajl_complete_parse(hand) != yajl_status_ok) { unsigned char *errstr = yajl_get_error(hand, 1, (const unsigned char*)jsonstring, strlen(jsonstring)); diff --git a/tests/jsontest.c b/tests/jsontest.c index c08094639e..f226c9251e 100644 --- a/tests/jsontest.c +++ b/tests/jsontest.c @@ -304,6 +304,12 @@ mymain(void) DO_TEST_PARSE("string", "[ \"The meaning of life\" ]"); DO_TEST_PARSE_FAIL("unterminated string", "[ \"The meaning of lif ]"); + DO_TEST_PARSE("integer", "1"); + DO_TEST_PARSE("boolean", "true"); + DO_TEST_PARSE("null", "null"); + DO_TEST_PARSE_FAIL("incomplete keyword", "tr"); + DO_TEST_PARSE_FAIL("overdone keyword", "truest"); + DO_TEST_PARSE_FAIL("unknown keyword", "huh"); DO_TEST_PARSE_FAIL("object with numeric keys", "{ 1:1, 2:1, 3:2 }"); DO_TEST_PARSE_FAIL("unterminated object", "{ \"1\":1, \"2\":1, \"3\":2");