diff options
| author | Frank LENORMAND <lenormf@gmail.com> | 2019-11-13 10:30:25 +0100 |
|---|---|---|
| committer | Frank LENORMAND <lenormf@gmail.com> | 2019-11-17 09:27:46 +0100 |
| commit | 19f1754a2a9db3f6a84b2e611b8956fd51ad748e (patch) | |
| tree | 08fbf9d33c28d2b27b543a7f57bec814e07f4f96 /src | |
| parent | 7cdbe1d3d24c1cc13bd7cbc3fe252f1e88747ffb (diff) | |
src json: Limit the recursion depth to 100
Diffstat (limited to 'src')
| -rw-r--r-- | src/json.cc | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/json.cc b/src/json.cc index dcb4005a..82db4576 100644 --- a/src/json.cc +++ b/src/json.cc @@ -40,11 +40,16 @@ String to_json(StringView str) static bool is_digit(char c) { return c >= '0' and c <= '9'; } -JsonResult parse_json(const char* pos, const char* end) +static constexpr size_t max_parsing_depth = 100; + +JsonResult parse_json_impl(const char* pos, const char* end, size_t depth) { if (not skip_while(pos, end, is_blank)) return {}; + if (depth >= max_parsing_depth) + throw runtime_error("maximum parsing depth reached"); + if (is_digit(*pos) or *pos == '-') { auto digit_end = pos + 1; @@ -90,7 +95,7 @@ JsonResult parse_json(const char* pos, const char* end) while (true) { - auto [element, new_pos] = parse_json(pos, end); + auto [element, new_pos] = parse_json_impl(pos, end, depth+1); if (not element) return {}; pos = new_pos; @@ -116,7 +121,7 @@ JsonResult parse_json(const char* pos, const char* end) while (true) { - auto [name_value, name_end] = parse_json(pos, end); + auto [name_value, name_end] = parse_json_impl(pos, end, depth+1); if (not name_value) return {}; pos = name_end; @@ -126,7 +131,7 @@ JsonResult parse_json(const char* pos, const char* end) if (*pos++ != ':') throw runtime_error("expected :"); - auto [element, element_end] = parse_json(pos, end); + auto [element, element_end] = parse_json_impl(pos, end, depth+1); if (not element) return {}; pos = element_end; @@ -145,7 +150,8 @@ JsonResult parse_json(const char* pos, const char* end) throw runtime_error("unable to parse json"); } -JsonResult parse_json(StringView json) { return parse_json(json.begin(), json.end()); } +JsonResult parse_json(const char* pos, const char* end) { return parse_json_impl(pos, end, 0); } +JsonResult parse_json(StringView json) { return parse_json_impl(json.begin(), json.end(), 0); } UnitTest test_json_parser{[]() { @@ -170,6 +176,16 @@ UnitTest test_json_parser{[]() kak_assert(value and value.is_a<JsonObject>()); kak_assert(value.as<JsonObject>().empty()); } + + { + String big_nested_array = {"", max_parsing_depth*2+2}; + for (size_t i = 0; i < max_parsing_depth+1; i++) + { + big_nested_array[i] = '['; + big_nested_array[i+max_parsing_depth+1] = ']'; + } + kak_expect_throw(runtime_error, parse_json(big_nested_array)); + } }}; } |
