From 4aadd947667e28f5ce955de4961baed0a109cc7a Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Fri, 9 Jul 2010 00:21:26 +0200 Subject: [PATCH] core: fix json parsing of empty arrays and objects --- core/jsonArg.cpp | 30 +++++++++++++++++++++++------- core/tests/test_jsonarg.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/core/jsonArg.cpp b/core/jsonArg.cpp index 638fba36..dbc9abb4 100644 --- a/core/jsonArg.cpp +++ b/core/jsonArg.cpp @@ -137,17 +137,26 @@ bool array_parse(std::istream& input, AmArg& res) { if (!match("[", input)) { return false; } - + + res.assertArray(); + + if (match("]", input)) { + return true; + } + do { res.push(AmArg()); AmArg v; if (!json2arg(input, res.get(res.size()-1))) { + res.clear(); + return false; res.pop_back(); break; // TODO: return false???? } } while (match(",", input)); if (!match("]", input)) { + res.clear(); return false; } return true; @@ -158,26 +167,34 @@ bool object_parse(std::istream& input, AmArg& res) { return false; } + res.assertStruct(); + + if (match("}", input)) { + return true; + } + do { std::string key; if (!parse_string(input, &key)) { if (match("}",input,true)) { return true; } + res.clear(); return false; } if (!match(":", input)) { + res.clear(); return false; } res[key] = AmArg(); // using the reference if (!json2arg(input, res[key])) { - res.erase(key); - // TODO: return false? but: empty will return false in subtree as well - break; + res.clear(); + return false; } } while (match(",", input)); if (!match("}", input)) { + res.clear(); return false; } @@ -224,14 +241,13 @@ bool json2arg(std::istream& input, AmArg& res) { } if (array_parse(input, res)) { - res.type = AmArg::Array; return true; } if (object_parse(input, res)) { - res.type = AmArg::Struct; return true; } - res.invalidate(); + + res.clear(); return false; } diff --git a/core/tests/test_jsonarg.cpp b/core/tests/test_jsonarg.cpp index c803c695..bf18523f 100644 --- a/core/tests/test_jsonarg.cpp +++ b/core/tests/test_jsonarg.cpp @@ -15,4 +15,38 @@ FCTMF_SUITE_BGN(test_jsonarg) { fct_chk(json2arg(s.c_str(), rpc_params)); } FCT_TEST_END(); + FCT_TEST_BGN(json_empty_struct_parse) { + // string s = "{\"jsonrpc\": \"2.0\", \"result\": {\"timestamp\": 62, \"analysis\": {}}, \"id\": \"11\"}"; + string s = "{\"result\": {}}"; + AmArg rpc_params; + fct_chk(json2arg(s.c_str(), rpc_params)); + fct_chk(isArgStruct(rpc_params["result"])); + } FCT_TEST_END(); + + FCT_TEST_BGN(json_empty_array_parse) { + string s = "{\"result\": []}"; + AmArg rpc_params; + fct_chk(json2arg(s.c_str(), rpc_params)); + fct_chk(isArgArray(rpc_params["result"])); + } FCT_TEST_END(); + + FCT_TEST_BGN(json_error_array_parse) { + string s = "{\"result\": [ :1]}"; + AmArg rpc_params; + fct_chk(!json2arg(s.c_str(), rpc_params)); + } FCT_TEST_END(); + + FCT_TEST_BGN(json_error_object_parse) { + string s = "{\"result\": { :1}}"; + AmArg rpc_params; + fct_chk(!json2arg(s.c_str(), rpc_params)); + } FCT_TEST_END(); + + FCT_TEST_BGN(json_empty_string_key_parse) { + string s = "{\"result\": {\"\" :1}}"; + AmArg rpc_params; + fct_chk(json2arg(s.c_str(), rpc_params)); + fct_chk(rpc_params["result"][""].asInt()==1); + } FCT_TEST_END(); + } FCTMF_SUITE_END();