diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2016-06-11 13:41:46 +0100 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2016-06-11 13:42:25 +0100 |
| commit | 04d24b22bdb3093f8919e36ebdea31e49d013ed8 (patch) | |
| tree | a4acbc93948261606e8d469309f45b0761c68049 /src | |
| parent | 3059b3a253dd491270a97cf492992fba70e9befe (diff) | |
Fix parsing of empty json objects/arrays and recover parse errors
Fixes #694
Diffstat (limited to 'src')
| -rw-r--r-- | src/json_ui.cc | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/json_ui.cc b/src/json_ui.cc index 9b562026..53da6ee7 100644 --- a/src/json_ui.cc +++ b/src/json_ui.cc @@ -295,7 +295,9 @@ parse_json(const char* pos, const char* end) if (*pos == '[') { JsonArray array; - ++pos; + if (*++pos == ']') + return Result{std::move(array), pos+1}; + while (true) { Value element; @@ -317,7 +319,9 @@ parse_json(const char* pos, const char* end) if (*pos == '{') { JsonObject object; - ++pos; + if (*++pos == '}') + return Result{std::move(object), pos+1}; + while (true) { Value name_value; @@ -350,6 +354,9 @@ parse_json(const char* pos, const char* end) 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) { const JsonObject& object = json.as<JsonObject>(); @@ -418,7 +425,16 @@ void JsonUI::parse_requests(EventMode mode) { Value json; 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) { try @@ -440,9 +456,16 @@ void JsonUI::parse_requests(EventMode mode) 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())); - kak_assert(value); + { + auto value = std::get<0>(parse_json(R"({ "jsonrpc": "2.0", "method": "keys", "params": [ "b", "l", "a", "h" ] })")); + kak_assert(value); + } + + { + auto value = std::get<0>(parse_json("{}")); + kak_assert(value and value.is_a<JsonObject>()); + kak_assert(value.as<JsonObject>().empty()); + } }}; } |
