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 d9f607448d9..04d68b5bdcc 100644 --- a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs +++ b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs @@ -210,6 +210,22 @@ public void UnsafeWrap() 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 7828658672f..063b5435628 100644 --- a/csharp/src/Google.Protobuf/ByteString.cs +++ b/csharp/src/Google.Protobuf/ByteString.cs @@ -325,7 +325,7 @@ public CodedInputStream CreateCodedInput() 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 {