diff options
-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 |