diff --git a/src/json.hpp b/src/json.hpp index 0e8eece3..78cc7093 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -9457,10 +9457,27 @@ basic_json_parser_63: { for (const auto& reference_token : reference_tokens) { - // error condition (cf. RFC 6901, Sect. 4) - if (reference_token.size() > 1 and reference_token[0] == '0') + // convert null values to arrays or objects before continuing + if (ptr->m_type == value_t::null) { - throw std::domain_error("array index must not begin with '0'"); + // check if reference token is a number + const bool nums = std::all_of(reference_token.begin(), + reference_token.end(), + [](const char x) + { + return std::isdigit(x); + }); + + // change value to array for numbers or "-" or to object + // otherwise + if (nums or reference_token == "-") + { + *ptr = value_t::array; + } + else + { + *ptr = value_t::object; + } } switch (ptr->m_type) @@ -9474,6 +9491,13 @@ basic_json_parser_63: case value_t::array: { + + // error condition (cf. RFC 6901, Sect. 4) + if (reference_token.size() > 1 and reference_token[0] == '0') + { + throw std::domain_error("array index must not begin with '0'"); + } + if (reference_token == "-") { // explicityly treat "-" as index beyond the end @@ -9487,37 +9511,6 @@ basic_json_parser_63: break; } - // null values are converted to arrays or objects - case value_t::null: - { - // check if reference token is a number - const bool nums = std::all_of(reference_token.begin(), - reference_token.end(), - [](const char x) - { - return std::isdigit(x); - }); - - if (nums) - { - // if reference token consists solely of numbers - // use it as array index -> create array - ptr = &ptr->operator[](static_cast(std::stoi(reference_token))); - } - else if (reference_token == "-") - { - // explicityly treat "-" as index beyond the end - // which is 0 for an empty array -> create array - ptr = &ptr->operator[](0); - } - else - { - // treat reference token as key -> create object - ptr = &ptr->operator[](reference_token); - } - break; - } - default: { throw std::out_of_range("unresolved reference token '" + reference_token + "'"); diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 757f8859..61196844 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -8754,10 +8754,27 @@ class basic_json { for (const auto& reference_token : reference_tokens) { - // error condition (cf. RFC 6901, Sect. 4) - if (reference_token.size() > 1 and reference_token[0] == '0') + // convert null values to arrays or objects before continuing + if (ptr->m_type == value_t::null) { - throw std::domain_error("array index must not begin with '0'"); + // check if reference token is a number + const bool nums = std::all_of(reference_token.begin(), + reference_token.end(), + [](const char x) + { + return std::isdigit(x); + }); + + // change value to array for numbers or "-" or to object + // otherwise + if (nums or reference_token == "-") + { + *ptr = value_t::array; + } + else + { + *ptr = value_t::object; + } } switch (ptr->m_type) @@ -8771,6 +8788,13 @@ class basic_json case value_t::array: { + + // error condition (cf. RFC 6901, Sect. 4) + if (reference_token.size() > 1 and reference_token[0] == '0') + { + throw std::domain_error("array index must not begin with '0'"); + } + if (reference_token == "-") { // explicityly treat "-" as index beyond the end @@ -8784,37 +8808,6 @@ class basic_json break; } - // null values are converted to arrays or objects - case value_t::null: - { - // check if reference token is a number - const bool nums = std::all_of(reference_token.begin(), - reference_token.end(), - [](const char x) - { - return std::isdigit(x); - }); - - if (nums) - { - // if reference token consists solely of numbers - // use it as array index -> create array - ptr = &ptr->operator[](static_cast(std::stoi(reference_token))); - } - else if (reference_token == "-") - { - // explicityly treat "-" as index beyond the end - // which is 0 for an empty array -> create array - ptr = &ptr->operator[](0); - } - else - { - // treat reference token as key -> create object - ptr = &ptr->operator[](reference_token); - } - break; - } - default: { throw std::out_of_range("unresolved reference token '" + reference_token + "'");