From 0032f200e9a318b4b17d1663289d3bf03ee67fc3 Mon Sep 17 00:00:00 2001 From: Martijn Vels Date: Thu, 30 Mar 2023 09:44:24 -0700 Subject: [PATCH] Fix IsEagerSerializeSafe() and kParseError behavior PiperOrigin-RevId: 520664827 --- src/google/protobuf/message_unittest.inc | 32 +++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 914e3e9f33..881e5e7886 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -596,6 +596,33 @@ TEST(MESSAGE_TEST_NAME, AllAddMethodsOnRepeatedStringField) { msg.clear_repeated_string(); } +// Helper functions to touch any nested lazy field +void TouchLazy(UNITTEST::NestedTestAllTypes* msg); +void TouchLazy(UNITTEST::TestAllTypes* msg); +void TouchLazy(UNITTEST::TestAllTypes::NestedMessage* msg) {} + +void TouchLazy(UNITTEST::TestAllTypes* msg) { + if (msg->has_optional_lazy_message()) { + TouchLazy(msg->mutable_optional_lazy_message()); + } + if (msg->has_optional_unverified_lazy_message()) { + TouchLazy(msg->mutable_optional_unverified_lazy_message()); + } + for (auto& child : *msg->mutable_repeated_lazy_message()) { + TouchLazy(&child); + } +} + +void TouchLazy(UNITTEST::NestedTestAllTypes* msg) { + if (msg->has_child()) TouchLazy(msg->mutable_child()); + if (msg->has_payload()) TouchLazy(msg->mutable_payload()); + for (auto& child : *msg->mutable_repeated_child()) { + TouchLazy(&child); + } + if (msg->has_lazy_child()) TouchLazy(msg->mutable_lazy_child()); + if (msg->has_eager_child()) TouchLazy(msg->mutable_eager_child()); +} + TEST(MESSAGE_TEST_NAME, SuccessAfterParsingFailure) { UNITTEST::NestedTestAllTypes o, p, q; constexpr int kDepth = 5; @@ -610,7 +637,10 @@ TEST(MESSAGE_TEST_NAME, SuccessAfterParsingFailure) { serialized[serialized.size() - 1] = 0xFF; EXPECT_FALSE(p.ParseFromString(serialized)); - // Subsequent serialization should be parsed correctly. + // If the affected byte is inside a lazy message, we have no guarantee that it + // serializes into error free data because serialization needs to preserve + // const correctness on lazy fields: `touch` all lazy fields. + TouchLazy(&p); EXPECT_TRUE(q.ParseFromString(p.SerializeAsString())); }