aboutsummaryrefslogtreecommitdiff
path: root/pw_protobuf
diff options
context:
space:
mode:
authorScott James Remnant <keybuk@google.com>2021-12-11 18:18:14 -0800
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2021-12-12 18:20:11 +0000
commitf6565f1b050f654b4f501d8cda8da49f1fc1b041 (patch)
tree69b62759b6b17003eff17cbe79737f2284aa71f6 /pw_protobuf
parent28072eb8427f2dac1c43fdfe7532daf690aaaa00 (diff)
downloadpigweed-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.cc2
-rw-r--r--pw_protobuf/stream_decoder_test.cc30
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