Cap the number of errors returned from JSON parsing.

pull/21985/head
Mark D. Roth 5 years ago
parent ff22a394d6
commit 2fe2637b39
  1. 35
      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<grpc_error*> errors_;
bool truncated_errors_ = false;
Json root_value_;
std::vector<Json*> 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,

Loading…
Cancel
Save