From 9848fe2bf7406a84ea3198c7ed94db4451071f25 Mon Sep 17 00:00:00 2001 From: Mark Young Date: Wed, 16 Jun 2021 16:11:06 +1200 Subject: [PATCH] [csharp] ByteString.CreateCodedInput should use ArraySegment offset and count CreateCodedInput is created from the underlying array behind the ByteString. If this was created from a larger array (via Memory or ArrayPool etc) then the CodedInput refers to the wrong section of memory. Change is to add the offset and count like the other methods that use the ArraySegment (ToString, ToBase64, WriteTo). --- .../src/Google.Protobuf.Test/ByteStringTest.cs | 16 ++++++++++++++++ csharp/src/Google.Protobuf/ByteString.cs | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs index d9f607448d..04d68b5bdc 100644 --- a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs +++ b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs @@ -210,6 +210,22 @@ namespace Google.Protobuf Assert.AreEqual(byte.MaxValue, s[0]); } + [Test] + public void CreateCodedInput_FromArraySegment() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); + CodedInputStream codedInputStream = bs.CreateCodedInput(); + + byte[] bytes = codedInputStream.ReadRawBytes(3); + + Assert.AreEqual(3, bytes.Length); + Assert.AreEqual(2, bytes[0]); + Assert.AreEqual(3, bytes[1]); + Assert.AreEqual(4, bytes[2]); + Assert.IsTrue(codedInputStream.IsAtEnd); + } + [Test] public void WriteToStream() { diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs index 7828658672..063b543562 100644 --- a/csharp/src/Google.Protobuf/ByteString.cs +++ b/csharp/src/Google.Protobuf/ByteString.cs @@ -325,7 +325,7 @@ namespace Google.Protobuf if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment) && segment.Count == bytes.Length) { // Fast path. ByteString was created with a complete array. - return new CodedInputStream(segment.Array); + return new CodedInputStream(segment.Array, segment.Offset, segment.Count); } else {