From: Adam Sitnik Date: Wed, 19 Jun 2019 08:06:28 +0000 (+0200) Subject: writing to too small buffer should throw an exception (dotnet/corefx#37661) X-Git-Tag: submit/tizen/20210909.063632~11031^2~1248 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4d2714cd93f847ab35734e7f1aaa9e209db3e00;p=platform%2Fupstream%2Fdotnet%2Fruntime.git writing to too small buffer should throw an exception (dotnet/corefx#37661) fixes dotnet/corefx#35231 Commit migrated from https://github.com/dotnet/corefx/commit/721a570b005c53a839947603dcf76f8a3e5fc56a --- diff --git a/src/libraries/System.Memory/src/System/Buffers/BuffersExtensions.cs b/src/libraries/System.Memory/src/System/Buffers/BuffersExtensions.cs index a038df9..94ec060 100644 --- a/src/libraries/System.Memory/src/System/Buffers/BuffersExtensions.cs +++ b/src/libraries/System.Memory/src/System/Buffers/BuffersExtensions.cs @@ -110,6 +110,9 @@ namespace System.Buffers /// /// Writes contents of to /// + /// + /// Thrown when the is shorter than the . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Write(this IBufferWriter writer, ReadOnlySpan value) { @@ -139,6 +142,12 @@ namespace System.Buffers if (input.Length > 0) { destination = writer.GetSpan(); + + if (destination.IsEmpty) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.writer); + } + continue; } diff --git a/src/libraries/System.Memory/src/System/ThrowHelper.cs b/src/libraries/System.Memory/src/System/ThrowHelper.cs index a4b606e..98fa8a4 100644 --- a/src/libraries/System.Memory/src/System/ThrowHelper.cs +++ b/src/libraries/System.Memory/src/System/ThrowHelper.cs @@ -120,6 +120,7 @@ namespace System array, culture, manager, - count + count, + writer, } } diff --git a/src/libraries/System.Memory/tests/BuffersExtensions/BuffersExtensionsTests.cs b/src/libraries/System.Memory/tests/BuffersExtensions/BuffersExtensionsTests.cs index eefc9c40..445c348 100644 --- a/src/libraries/System.Memory/tests/BuffersExtensions/BuffersExtensionsTests.cs +++ b/src/libraries/System.Memory/tests/BuffersExtensions/BuffersExtensionsTests.cs @@ -29,6 +29,75 @@ namespace System.Buffers.Tests Assert.Equal("Hello World!", bufferWriter.ToString()); } + [Fact] + public void WritingEmptyBufferToSingleSegmentEmptyBufferWriterDoesNothing() + { + IBufferWriter bufferWriter = new MultiSegmentArrayBufferWriter( + new byte[][] { Array.Empty() } + ); + + bufferWriter.Write(Array.Empty()); // This is equivalent to: Span.Empty.CopyTo(Span.Empty); + } + + [Fact] + public void WritingEmptyBufferToMultipleSegmentEmptyBufferWriterDoesNothing() + { + IBufferWriter bufferWriter = new MultiSegmentArrayBufferWriter( + new byte[][] { Array.Empty(), Array.Empty() } + ); + + bufferWriter.Write(Array.Empty()); + } + + [Theory] + [InlineData(1, 0)] + [InlineData(10, 9)] + public void WritingToTooSmallSingleSegmentBufferFailsWithException(int inputSize, int destinationSize) + { + IBufferWriter bufferWriter = new MultiSegmentArrayBufferWriter( + new byte[][] { new byte[destinationSize] } + ); + + Assert.Throws(paramName: "writer", testCode: () => bufferWriter.Write(new byte[inputSize])); + } + + [Theory] + [InlineData(10, 2, 2)] + [InlineData(10, 9, 0)] + public void WritingToTooSmallMultiSegmentBufferFailsWithException(int inputSize, int firstSegmentSize, int secondSegmentSize) + { + IBufferWriter bufferWriter = new MultiSegmentArrayBufferWriter( + new byte[][] { + new byte[firstSegmentSize], + new byte[secondSegmentSize] + } + ); + + Assert.Throws( + paramName: "writer", + testCode: () => bufferWriter.Write(new byte[inputSize])); + } + + private class MultiSegmentArrayBufferWriter : IBufferWriter + { + private readonly T[][] _segments; + private int _segmentIndex; + + public MultiSegmentArrayBufferWriter(T[][] segments) => _segments = segments; + + public void Advance(int size) + { + if (size != _segments[_segmentIndex].Length) + throw new NotSupportedException("By design"); + + _segmentIndex++; + } + + public Memory GetMemory(int sizeHint = 0) => _segmentIndex < _segments.Length ? _segments[_segmentIndex] : Memory.Empty; + + public Span GetSpan(int sizeHint = 0) => _segmentIndex < _segments.Length ? _segments[_segmentIndex] : Span.Empty; + } + private class TestBufferWriterSingleSegment : IBufferWriter { private byte[] _buffer = new byte[1000];