Fix parsing of empty json objects/arrays and recover parse errors

Fixes #694
This commit is contained in:
Maxime Coste 2016-06-11 13:41:46 +01:00
parent 3059b3a253
commit 04d24b22bd

View File

@ -295,7 +295,9 @@ parse_json(const char* pos, const char* end)
if (*pos == '[') if (*pos == '[')
{ {
JsonArray array; JsonArray array;
++pos; if (*++pos == ']')
return Result{std::move(array), pos+1};
while (true) while (true)
{ {
Value element; Value element;
@ -317,7 +319,9 @@ parse_json(const char* pos, const char* end)
if (*pos == '{') if (*pos == '{')
{ {
JsonObject object; JsonObject object;
++pos; if (*++pos == '}')
return Result{std::move(object), pos+1};
while (true) while (true)
{ {
Value name_value; Value name_value;
@ -350,6 +354,9 @@ parse_json(const char* pos, const char* end)
throw runtime_error("Could not parse json"); throw runtime_error("Could not parse json");
} }
std::tuple<Value, const char*>
parse_json(StringView json) { return parse_json(json.begin(), json.end()); }
void JsonUI::eval_json(const Value& json) void JsonUI::eval_json(const Value& json)
{ {
const JsonObject& object = json.as<JsonObject>(); const JsonObject& object = json.as<JsonObject>();
@ -418,7 +425,16 @@ void JsonUI::parse_requests(EventMode mode)
{ {
Value json; Value json;
const char* pos; const char* pos;
std::tie(json, pos) = parse_json(m_requests.begin(), m_requests.end()); try
{
std::tie(json, pos) = parse_json(m_requests);
}
catch (runtime_error& error)
{
write_stderr(format("error while parsing requests '{}': '{}'",
m_requests, error.what()));
}
if (json) if (json)
{ {
try try
@ -440,9 +456,16 @@ void JsonUI::parse_requests(EventMode mode)
UnitTest test_json_parser{[]() UnitTest test_json_parser{[]()
{ {
StringView json = R"({ "jsonrpc": "2.0", "method": "keys", "params": [ "b", "l", "a", "h" ] })"; {
auto value = std::get<0>(parse_json(json.begin(), json.end())); auto value = std::get<0>(parse_json(R"({ "jsonrpc": "2.0", "method": "keys", "params": [ "b", "l", "a", "h" ] })"));
kak_assert(value); kak_assert(value);
}
{
auto value = std::get<0>(parse_json("{}"));
kak_assert(value and value.is_a<JsonObject>());
kak_assert(value.as<JsonObject>().empty());
}
}}; }};
} }