Emit an error if user tries to iterate arrays out of order
This commit is contained in:
parent
fe726b0f80
commit
22b3ea93a8
|
@ -35,6 +35,7 @@ enum error_code {
|
|||
INVALID_URI_FRAGMENT, ///< Invalid URI fragment
|
||||
UNEXPECTED_ERROR, ///< indicative of a bug in simdjson
|
||||
PARSER_IN_USE, ///< parser is already in use.
|
||||
OUT_OF_ORDER_ITERATION, ///< tried to iterate an array or object out of order
|
||||
/** @private Number of error codes */
|
||||
NUM_ERROR_CODES
|
||||
};
|
||||
|
|
|
@ -52,6 +52,7 @@ simdjson_really_inline object::object(const value_iterator &_iter) noexcept
|
|||
}
|
||||
|
||||
simdjson_really_inline object_iterator object::begin() noexcept {
|
||||
// TODO make it a runtime error if this is violated
|
||||
// Expanded version of SIMDJSON_ASSUME( iter.at_field_start() || !iter.is_open() )
|
||||
SIMDJSON_ASSUME( (iter._json_iter->token.index == iter._start_position + 1) || (iter._json_iter->_depth < iter._depth) );
|
||||
return iter;
|
||||
|
|
|
@ -10,7 +10,9 @@ simdjson_really_inline value_iterator::value_iterator(json_iterator *json_iter,
|
|||
}
|
||||
|
||||
simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator::start_object() noexcept {
|
||||
if (*advance_container_start("object") != '{') { return incorrect_type_error("Not an object"); }
|
||||
const uint8_t *json;
|
||||
SIMDJSON_TRY( advance_container_start("object", json) );
|
||||
if (*json != '{') { return incorrect_type_error("Not an object"); }
|
||||
return started_object();
|
||||
}
|
||||
|
||||
|
@ -248,7 +250,9 @@ simdjson_warn_unused simdjson_really_inline error_code value_iterator::field_val
|
|||
}
|
||||
|
||||
simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator::start_array() noexcept {
|
||||
if (*advance_container_start("array") != '[') { return incorrect_type_error("Not an array"); }
|
||||
const uint8_t *json;
|
||||
SIMDJSON_TRY( advance_container_start("array", json) );
|
||||
if (*json != '[') { return incorrect_type_error("Not an array"); }
|
||||
return started_array();
|
||||
}
|
||||
|
||||
|
@ -428,15 +432,20 @@ simdjson_really_inline const uint8_t *value_iterator::advance_start(const char *
|
|||
_json_iter->ascend_to(depth()-1);
|
||||
return result;
|
||||
}
|
||||
simdjson_really_inline const uint8_t *value_iterator::advance_container_start(const char *type) const noexcept {
|
||||
// If we're not at the position anymore, we don't want to advance the cursor.
|
||||
if (is_at_container_start()) { return peek_start(); }
|
||||
|
||||
simdjson_really_inline error_code value_iterator::advance_container_start(const char *type, const uint8_t *&json) const noexcept {
|
||||
logger::log_start_value(*_json_iter, _start_position, depth(), type);
|
||||
|
||||
// If we're not at the position anymore, we don't want to advance the cursor.
|
||||
if (!is_at_start()) {
|
||||
if (!is_at_container_start()) { return OUT_OF_ORDER_ITERATION; }
|
||||
json = peek_start();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Get the JSON and advance the cursor, decreasing depth to signify that we have retrieved the value.
|
||||
assert_at_start();
|
||||
return _json_iter->advance();
|
||||
json = _json_iter->advance();
|
||||
return SUCCESS;
|
||||
}
|
||||
simdjson_really_inline const uint8_t *value_iterator::advance_root_scalar(const char *type) const noexcept {
|
||||
logger::log_value(*_json_iter, _start_position, depth(), type);
|
||||
|
|
|
@ -274,7 +274,7 @@ protected:
|
|||
simdjson_really_inline const uint8_t *peek_start() const noexcept;
|
||||
simdjson_really_inline uint32_t peek_start_length() const noexcept;
|
||||
simdjson_really_inline const uint8_t *advance_start(const char *type) const noexcept;
|
||||
simdjson_really_inline const uint8_t *advance_container_start(const char *type) const noexcept;
|
||||
simdjson_really_inline error_code advance_container_start(const char *type, const uint8_t *&json) const noexcept;
|
||||
simdjson_really_inline const uint8_t *advance_root_scalar(const char *type) const noexcept;
|
||||
simdjson_really_inline const uint8_t *advance_non_root_scalar(const char *type) const noexcept;
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ namespace internal {
|
|||
{ INVALID_JSON_POINTER, "Invalid JSON pointer syntax." },
|
||||
{ INVALID_URI_FRAGMENT, "Invalid URI fragment syntax." },
|
||||
{ UNEXPECTED_ERROR, "Unexpected error, consider reporting this problem as you may have found a bug in simdjson" },
|
||||
{ PARSER_IN_USE, "Cannot parse a new document while a document is still in use." }
|
||||
{ PARSER_IN_USE, "Cannot parse a new document while a document is still in use." },
|
||||
{ OUT_OF_ORDER_ITERATION, "Objects and arrays can only be iterated when they are first encountered." }
|
||||
}; // error_messages[]
|
||||
|
||||
} // namespace internal
|
||||
|
|
Loading…
Reference in New Issue