diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index c3436d4119..3b5f16c389 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -414,6 +414,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // Provides access to protected GetOwningArena to generated messages. static Arena* GetOwningArena(const T* p) { return p->GetOwningArena(); } + static void InternalSwap(T* a, T* b) { a->InternalSwap(b); } + static Arena* GetArenaForAllocationInternal( const T* p, std::true_type /*is_derived_from*/) { return p->GetArenaForAllocation(); diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index 79800f135c..4b7c5c9d91 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -202,7 +202,6 @@ inline VerifySimpleType VerifyInt32TypeToVerifyCustom(VerifyInt32Type t) { static_cast(VerifyInt32Type::kCustom)]; } - } // namespace bool IsLazy(const FieldDescriptor* field, const Options& options, diff --git a/src/google/protobuf/compiler/cpp/options.h b/src/google/protobuf/compiler/cpp/options.h index 148866ff6e..5d935e9e6e 100644 --- a/src/google/protobuf/compiler/cpp/options.h +++ b/src/google/protobuf/compiler/cpp/options.h @@ -80,7 +80,7 @@ struct Options { bool annotate_accessor = false; bool unused_field_stripping = false; bool unverified_lazy_message_sets = false; - bool unverified_lazy = true; + bool unverified_lazy = false; bool profile_driven_inline_string = true; bool message_owned_arena_trial = false; bool force_split = false; diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 53bfd2d233..008c192253 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -1363,11 +1363,8 @@ class Map { } template void insert(InputIt first, InputIt last) { - for (InputIt it = first; it != last; ++it) { - iterator exist_it = find(it->first); - if (exist_it == end()) { - operator[](it->first) = it->second; - } + for (; first != last; ++first) { + try_emplace(first->first, first->second); } } void insert(std::initializer_list values) { diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index d2ef2d96d4..fa2bbbf599 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -285,6 +285,58 @@ TEST(MESSAGE_TEST_NAME, MergeFromUninitialized) { EXPECT_TRUE(TestUtil::EqualsToSerialized(q, p.SerializePartialAsString())); } +TEST(MESSAGE_TEST_NAME, ExplicitLazyExceedRecursionLimit) { + UNITTEST::NestedTestAllTypes original, parsed; + // Build proto with recursion depth of 3. + original.mutable_lazy_child() + ->mutable_child() + ->mutable_payload() + ->set_optional_int32(-1); + std::string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + + // User annotated LazyField ([lazy = true]) is eagerly verified and should + // catch the recursion limit violation. + io::ArrayInputStream array_stream(serialized.data(), serialized.size()); + io::CodedInputStream input_stream(&array_stream); + input_stream.SetRecursionLimit(2); + EXPECT_FALSE(parsed.ParseFromCodedStream(&input_stream)); + + // Lazy read results in parsing error which can be verified by not having + // expected value. + EXPECT_NE(parsed.lazy_child().child().payload().optional_int32(), -1); +} + +TEST(MESSAGE_TEST_NAME, NestedExplicitLazyExceedRecursionLimit) { + UNITTEST::NestedTestAllTypes original, parsed; + // Build proto with recursion depth of 5, with nested annotated LazyField. + original.mutable_lazy_child() + ->mutable_child() + ->mutable_lazy_child() + ->mutable_child() + ->mutable_payload() + ->set_optional_int32(-1); + std::string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + + // User annotated LazyField ([lazy = true]) is eagerly verified and should + // catch the recursion limit violation. + io::ArrayInputStream array_stream(serialized.data(), serialized.size()); + io::CodedInputStream input_stream(&array_stream); + input_stream.SetRecursionLimit(4); + EXPECT_FALSE(parsed.ParseFromCodedStream(&input_stream)); + + // Lazy read results in parsing error which can be verified by not having + // expected value. + EXPECT_NE(parsed.lazy_child() + .child() + .lazy_child() + .child() + .payload() + .optional_int32(), + -1); +} + TEST(MESSAGE_TEST_NAME, ParseFailsIfSubmessageTruncated) { UNITTEST::NestedTestAllTypes o, p; constexpr int kDepth = 5;