cql3: Fix invalid JSON parsing for JSON objects with ASCII keys

For JSON objects represented as map<ascii, int>, don't treat ASCII keys
as a nested JSON string. We were doing that prior to the patch, which
led to parsing errors.

Included the error offset where JSON parsing failed for
rjson::parse related functions to help identify parsing errors
better.

Fixes: #7949

Signed-off-by: Michael Huang <michaelhly@gmail.com>

Closes scylladb/scylladb#15499
This commit is contained in:
Michael Huang
2023-09-21 10:42:06 -04:00
committed by Avi Kivity
parent e600f35d1e
commit 75109e9519
3 changed files with 21 additions and 12 deletions

View File

@@ -109,7 +109,9 @@ public:
rapidjson::GenericReader<encoding, encoding, allocator> reader(&the_allocator);
reader.Parse(stream, *this);
if (reader.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", rapidjson::GetParseError_En(reader.GetParseErrorCode())));
throw rjson::error(
format("Parsing JSON failed: {} at {}",
rapidjson::GetParseError_En(reader.GetParseErrorCode()), reader.GetErrorOffset()));
}
//NOTICE: The handler has parsed the string, but in case of rapidjson::GenericDocument
// the data now resides in an internal stack_ variable, which is private instead of
@@ -308,7 +310,8 @@ rjson::value parse(std::string_view str, size_t max_nested_level) {
guarded_yieldable_json_handler<document, false> d(max_nested_level);
d.Parse(str.data(), str.size());
if (d.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", GetParseError_En(d.GetParseError())));
throw rjson::error(format("Parsing JSON failed: {} at {}",
GetParseError_En(d.GetParseError()), d.GetErrorOffset()));
}
rjson::value& v = d;
return std::move(v);
@@ -318,7 +321,8 @@ rjson::value parse(chunked_content&& content, size_t max_nested_level) {
guarded_yieldable_json_handler<document, false> d(max_nested_level);
d.Parse(std::move(content));
if (d.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", GetParseError_En(d.GetParseError())));
throw rjson::error(format("Parsing JSON failed: {} at {}",
GetParseError_En(d.GetParseError()), d.GetErrorOffset()));
}
rjson::value& v = d;
return std::move(v);
@@ -342,7 +346,8 @@ rjson::value parse_yieldable(std::string_view str, size_t max_nested_level) {
guarded_yieldable_json_handler<document, true> d(max_nested_level);
d.Parse(str.data(), str.size());
if (d.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", GetParseError_En(d.GetParseError())));
throw rjson::error(format("Parsing JSON failed: {} at {}",
GetParseError_En(d.GetParseError()), d.GetErrorOffset()));
}
rjson::value& v = d;
return std::move(v);
@@ -352,7 +357,8 @@ rjson::value parse_yieldable(chunked_content&& content, size_t max_nested_level)
guarded_yieldable_json_handler<document, true> d(max_nested_level);
d.Parse(std::move(content));
if (d.HasParseError()) {
throw rjson::error(format("Parsing JSON failed: {}", GetParseError_En(d.GetParseError())));
throw rjson::error(format("Parsing JSON failed: {} at {}",
GetParseError_En(d.GetParseError()), d.GetErrorOffset()));
}
rjson::value& v = d;
return std::move(v);