Skip to content

Commit 2ec322e

Browse files
Fix issue where BinaryToJson a Skip()'s failure on unknown fields was ignored instead of resulting in a parse failure.
This harmonizes the BinaryToJson behavior with wire_format.cc skip unknown: it still has the odd implication of truncating the length varint, but it will now correctly parse-fail if the length is larger than the remaining bytes (before it just skipped to the end of the buffer) and also parse-fail if the 32nd bit is set (which is viewed as a negative length by CodedInputStream and would have just continued parsing without skipping anything) Fixes #25092 PiperOrigin-RevId: 852791222
1 parent 262d725 commit 2ec322e

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ PROTOBUF_NOINLINE static absl::Status MakeTooDeepError() {
199199
return absl::InvalidArgumentError("allowed depth exceeded");
200200
}
201201

202+
PROTOBUF_NOINLINE static absl::Status MakeMalformedLengthDelimError() {
203+
return absl::InvalidArgumentError("malformed length-delimited field");
204+
}
205+
202206
absl::Status UntypedMessage::Decode(io::CodedInputStream& stream,
203207
absl::optional<int32_t> current_group) {
204208
std::vector<int32_t> group_stack;
@@ -256,8 +260,9 @@ absl::Status UntypedMessage::Decode(io::CodedInputStream& stream,
256260
if (!stream.ReadVarint32(&x)) {
257261
return MakeUnexpectedEofError();
258262
}
259-
// TODO: Remove this suppression.
260-
(void)stream.Skip(x);
263+
if (!stream.Skip(x)) {
264+
return MakeMalformedLengthDelimError();
265+
}
261266
continue;
262267
}
263268
case WireFormatLite::WIRETYPE_START_GROUP: {

src/google/protobuf/json/json_test.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,16 @@ TEST_P(JsonTest, UnknownGroupField) {
14421442
EXPECT_EQ(out, "{}");
14431443
}
14441444

1445+
TEST_P(JsonTest, MalformedLengthDelimitedField) {
1446+
std::string out;
1447+
// An unknown length delimited field where the length is larger than
1448+
// the remaining input.
1449+
absl::Status s = BinaryToJsonString(resolver_.get(),
1450+
"type.googleapis.com/proto3.TestMessage",
1451+
"\xC2\x3E\x80\x80\x80\x80\x08", &out);
1452+
ASSERT_THAT(s, StatusIs(absl::StatusCode::kInvalidArgument));
1453+
}
1454+
14451455
// JSON values get special treatment when it comes to pre-existing values in
14461456
// their repeated fields, when parsing through their dedicated syntax.
14471457
TEST_P(JsonTest, ClearPreExistingRepeatedInJsonValues) {

0 commit comments

Comments
 (0)