Skip to content

Commit 014f676

Browse files
Fix JSON printing of Any of an empty message in C++Proto.
This check was likely based on confusion about presence: if the 'bytes' field of Any supported presence and was unset it would be a malformed message. However, as a Proto3 message the bytes field is implicit presence, and an empty message serializes to 0-bytes. It is perfectly valid to pack an empty message into an Any, and there's no distinguishing between "they forgot to set the value" and "actual zero-length serialization". This wasn't caught by a user sooner since it is already allowed when allow_legacy_nonconformant_behavior is on, and that setting is on by default and rarely disabled. #24937 PiperOrigin-RevId: 848253357
1 parent dd7c6f8 commit 014f676

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

src/google/protobuf/json/internal/unparser.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,9 +745,6 @@ absl::Status WriteAny(JsonWriter& writer, const Msg<Traits>& msg,
745745
return absl::OkStatus();
746746
} else if (!has_type_url) {
747747
return absl::InvalidArgumentError("broken Any: missing type URL");
748-
} else if (!has_value &&
749-
!writer.options().allow_legacy_nonconformant_behavior) {
750-
return absl::InvalidArgumentError("broken Any: missing value");
751748
}
752749

753750
writer.Write("{");

src/google/protobuf/json/json_test.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,23 @@ TEST_P(JsonTest, TestOverwriteRepeated) {
11791179
}
11801180

11811181

1182+
TEST_P(JsonTest, TestAny) {
1183+
// Not setting 'value' is legal because it is the the representation of an
1184+
// empty message (since 'bytes' is an implicit presence field).
1185+
google::protobuf::Any any;
1186+
any.set_type_url("type.googleapis.com/proto3.TestMessage");
1187+
EXPECT_THAT(
1188+
ToJson(any),
1189+
IsOkAndHolds(R"({"@type":"type.googleapis.com/proto3.TestMessage"})"));
1190+
EXPECT_THAT(
1191+
ToJson(any, {.allow_legacy_nonconformant_behavior = false}),
1192+
IsOkAndHolds(R"({"@type":"type.googleapis.com/proto3.TestMessage"})"));
1193+
1194+
auto round_trip = ToProto<google::protobuf::Any>(*ToJson(any));
1195+
ASSERT_OK(round_trip);
1196+
EXPECT_THAT(any, testing::EqualsProto(*round_trip));
1197+
}
1198+
11821199
TEST_P(JsonTest, TestDuration) {
11831200
auto m = ToProto<proto3::TestDuration>(R"json(
11841201
{

0 commit comments

Comments
 (0)