diff options
author | Scott James Remnant <keybuk@google.com> | 2021-12-11 18:18:14 -0800 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2021-12-12 18:20:11 +0000 |
commit | f6565f1b050f654b4f501d8cda8da49f1fc1b041 (patch) | |
tree | 69b62759b6b17003eff17cbe79737f2284aa71f6 /pw_protobuf | |
parent | 28072eb8427f2dac1c43fdfe7532daf690aaaa00 (diff) | |
download | pigweed-f6565f1b050f654b4f501d8cda8da49f1fc1b041.tar.gz |
pw_protobuf: fix ReadDelimitedBytes read range
Bug: 580
Change-Id: I99219cb463869f64ac1ecf5ddab86bb7ced6714a
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/73600
Reviewed-by: Yecheng Zhao <zyecheng@google.com>
Commit-Queue: Scott James Remnant <keybuk@google.com>
Diffstat (limited to 'pw_protobuf')
-rw-r--r-- | pw_protobuf/stream_decoder.cc | 2 | ||||
-rw-r--r-- | pw_protobuf/stream_decoder_test.cc | 30 |
2 files changed, 31 insertions, 1 deletions
diff --git a/pw_protobuf/stream_decoder.cc b/pw_protobuf/stream_decoder.cc index 6670dcf02..d3fe8f6cb 100644 --- a/pw_protobuf/stream_decoder.cc +++ b/pw_protobuf/stream_decoder.cc @@ -349,7 +349,7 @@ StatusWithSize StreamDecoder::ReadDelimitedField(std::span<std::byte> out) { return StatusWithSize::ResourceExhausted(); } - Result<ByteSpan> result = reader_.Read(out); + Result<ByteSpan> result = reader_.Read(out.first(delimited_field_size_)); if (!result.ok()) { return StatusWithSize(result.status(), 0); } diff --git a/pw_protobuf/stream_decoder_test.cc b/pw_protobuf/stream_decoder_test.cc index 6f4804479..ec20a8372 100644 --- a/pw_protobuf/stream_decoder_test.cc +++ b/pw_protobuf/stream_decoder_test.cc @@ -15,6 +15,8 @@ #include "pw_protobuf/stream_decoder.h" #include "gtest/gtest.h" +#include "pw_status/status.h" +#include "pw_status/status_with_size.h" #include "pw_stream/memory_stream.h" namespace pw::protobuf { @@ -546,5 +548,33 @@ TEST(StreamDecoder, GetLengthDelimitedPayloadBounds) { decoder.GetLengthDelimitedPayloadBounds().status()); } +TEST(StreamDecoder, ReadDelimitedField_DoesntOverConsume) { + // clang-format off + constexpr uint8_t encoded_proto[] = { + // type=string, k=1, v="Hello world" + 0x0a, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', + // type=int32, k=2, v=42 + 0x10, 0x2a, + }; + // clang-format on + + stream::MemoryReader reader(std::as_bytes(std::span(encoded_proto))); + StreamDecoder decoder(reader); + + ASSERT_EQ(OkStatus(), decoder.Next()); + + // This buffer is much larger than the string. + char buffer[128]; + const StatusWithSize size = decoder.ReadString(buffer); + EXPECT_EQ(size.status(), OkStatus()); + EXPECT_EQ(size.size(), 11u); + + // Make sure we can still read the next field. + ASSERT_EQ(OkStatus(), decoder.Next()); + const pw::Result<int32_t> result = decoder.ReadInt32(); + EXPECT_EQ(result.status(), OkStatus()); + EXPECT_EQ(result.value(), 42); +} + } // namespace } // namespace pw::protobuf |