Use rapidjson::kParseIterativeFlag when parsing JSON keysets. This makes sure that the stack size remains constant while parsing. PiperOrigin-RevId: 623736071 Change-Id: I76fdf60f2a754afceae97bada6ce242ed4dc6e8c (cherry picked from commit 570e4156e80fd0673a735986537cb15a452606b4)
diff --git a/tink/BUILD.bazel b/tink/BUILD.bazel index 6e68067..27515b8 100644 --- a/tink/BUILD.bazel +++ b/tink/BUILD.bazel
@@ -364,8 +364,6 @@ ":keyset_reader", "//proto:tink_cc_proto", "//tink/util:enums", - "//tink/util:errors", - "//tink/util:protobuf_helper", "//tink/util:status", "//tink/util:statusor", "@com_google_absl//absl/memory", @@ -852,9 +850,11 @@ srcs = ["core/json_keyset_reader_test.cc"], deps = [ ":json_keyset_reader", + ":keyset_reader", "//proto:aes_eax_cc_proto", "//proto:aes_gcm_cc_proto", "//proto:tink_cc_proto", + "//tink/util:statusor", "//tink/util:test_matchers", "//tink/util:test_util", "@com_google_absl//absl/strings",
diff --git a/tink/CMakeLists.txt b/tink/CMakeLists.txt index 9f8db69..45aa936 100644 --- a/tink/CMakeLists.txt +++ b/tink/CMakeLists.txt
@@ -342,8 +342,6 @@ absl::strings rapidjson tink::util::enums - tink::util::errors - tink::util::protobuf_helper tink::util::status tink::util::statusor tink::proto::tink_cc_proto @@ -795,8 +793,10 @@ core/json_keyset_reader_test.cc DEPS tink::core::json_keyset_reader + tink::core::keyset_reader gmock absl::strings + tink::util::statusor tink::util::test_matchers tink::util::test_util tink::proto::aes_eax_cc_proto
diff --git a/tink/core/json_keyset_reader.cc b/tink/core/json_keyset_reader.cc index 43f6a94..f93b6a5 100644 --- a/tink/core/json_keyset_reader.cc +++ b/tink/core/json_keyset_reader.cc
@@ -28,6 +28,9 @@ #include "absl/strings/str_cat.h" #include "include/rapidjson/document.h" #include "include/rapidjson/error/en.h" +#include "include/rapidjson/rapidjson.h" +#include "include/rapidjson/reader.h" +#include "tink/keyset_reader.h" #include "tink/util/enums.h" #include "tink/util/status.h" #include "tink/util/statusor.h" @@ -252,7 +255,8 @@ serialized_keyset = &serialized_keyset_from_stream; } rapidjson::Document json_doc(rapidjson::kObjectType); - if (json_doc.Parse(serialized_keyset->c_str()).HasParseError()) { + if (json_doc.Parse<rapidjson::kParseIterativeFlag>(serialized_keyset->c_str()) + .HasParseError()) { return util::Status( absl::StatusCode::kInvalidArgument, absl::StrCat( @@ -278,7 +282,8 @@ serialized_keyset = &serialized_keyset_from_stream; } rapidjson::Document json_doc; - if (json_doc.Parse(serialized_keyset->c_str()).HasParseError()) { + if (json_doc.Parse<rapidjson::kParseIterativeFlag>(serialized_keyset->c_str()) + .HasParseError()) { return util::Status( absl::StatusCode::kInvalidArgument, absl::StrCat("Invalid JSON EncryptedKeyset: Error (offset ",
diff --git a/tink/core/json_keyset_reader_test.cc b/tink/core/json_keyset_reader_test.cc index 9dff5be..1af3235 100644 --- a/tink/core/json_keyset_reader_test.cc +++ b/tink/core/json_keyset_reader_test.cc
@@ -27,11 +27,13 @@ #include "gtest/gtest.h" #include "absl/strings/escaping.h" #include "absl/strings/substitute.h" +#include "tink/util/statusor.h" #include "tink/util/test_matchers.h" #include "tink/util/test_util.h" #include "proto/aes_eax.pb.h" #include "proto/aes_gcm.pb.h" #include "proto/tink.pb.h" +#include "tink/keyset_reader.h" namespace crypto { namespace tink { @@ -395,6 +397,23 @@ EXPECT_THAT(read_result, Not(IsOk())); } + +TEST_F(JsonKeysetReaderTest, parseRecursiveJsonStringFails) { + std::string recursive_json; + for (int i = 0; i < 1000000; i++) { + recursive_json.append("{\"a\":"); + } + recursive_json.append("1"); + for (int i = 0; i < 1000000; i++) { + recursive_json.append("}"); + } + util::StatusOr<std::unique_ptr<KeysetReader>> reader = + JsonKeysetReader::New(recursive_json); + ASSERT_THAT(reader, IsOk()); + util::StatusOr<std::unique_ptr<Keyset>> keyset = (*reader)->Read(); + EXPECT_THAT(keyset, Not(IsOk())); +} + } // namespace } // namespace tink } // namespace crypto