diff --git a/src/core/lib/json/json_reader.cc b/src/core/lib/json/json_reader.cc index c9f1451491f..5667f03d52b 100644 --- a/src/core/lib/json/json_reader.cc +++ b/src/core/lib/json/json_reader.cc @@ -26,6 +26,7 @@ #include "src/core/lib/json/json.h" #define GRPC_JSON_MAX_DEPTH 255 +#define GRPC_JSON_MAX_ERRORS 16 namespace grpc_core { @@ -113,6 +114,7 @@ class JsonReader { uint16_t unicode_char_ = 0; uint16_t unicode_high_surrogate_ = 0; std::vector errors_; + bool truncated_errors_ = false; Json root_value_; std::vector stack_; @@ -171,11 +173,15 @@ Json* JsonReader::CreateAndLinkValue() { Json* parent = stack_.back(); if (parent->type() == Json::Type::OBJECT) { if (parent->object_value().find(key_) != parent->object_value().end()) { - char* msg; - gpr_asprintf(&msg, "duplicate key \"%s\" at index %" PRIuPTR, - key_.c_str(), CurrentIndex()); - errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg)); - gpr_free(msg); + if (errors_.size() == GRPC_JSON_MAX_ERRORS) { + truncated_errors_ = true; + } else { + char* msg; + gpr_asprintf(&msg, "duplicate key \"%s\" at index %" PRIuPTR, + key_.c_str(), CurrentIndex()); + errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg)); + gpr_free(msg); + } } value = &(*parent->mutable_object())[std::move(key_)]; } else { @@ -189,11 +195,15 @@ Json* JsonReader::CreateAndLinkValue() { bool JsonReader::StartContainer(Json::Type type) { if (stack_.size() == GRPC_JSON_MAX_DEPTH) { - char* msg; - gpr_asprintf(&msg, "exceeded max stack depth (%d) at index %" PRIuPTR, - GRPC_JSON_MAX_DEPTH, CurrentIndex()); - errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg)); - gpr_free(msg); + if (errors_.size() == GRPC_JSON_MAX_ERRORS) { + truncated_errors_ = true; + } else { + char* msg; + gpr_asprintf(&msg, "exceeded max stack depth (%d) at index %" PRIuPTR, + GRPC_JSON_MAX_DEPTH, CurrentIndex()); + errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg)); + gpr_free(msg); + } return false; } Json* value = CreateAndLinkValue(); @@ -808,6 +818,11 @@ JsonReader::Status JsonReader::Run() { grpc_error* JsonReader::Parse(StringView input, Json* output) { JsonReader reader(input); Status status = reader.Run(); + if (reader.truncated_errors_) { + reader.errors_.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "too many errors encountered during JSON parsing -- fix reported " + "errors and try again to see additional errors")); + } if (status == Status::GRPC_JSON_INTERNAL_ERROR) { char* msg; gpr_asprintf(&msg, "internal error in JSON parser at index %" PRIuPTR,