From 9041b5d1813ec818bae7954be0dc975d57e06852 Mon Sep 17 00:00:00 2001 From: Tanay Parikh Date: Mon, 10 May 2021 11:30:42 -0700 Subject: [PATCH] Backport #32277 to 3.1 (#32482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Update guard logic to permit writing 0 length buffers. This can happen in certain globalized scenarios (ex. `¿` with Portugese) where the first char needs to be encoded. Patch https://github.com/dotnet/aspnetcore/issues/31299 for 3.1 by cherry-picking the https://github.com/dotnet/aspnetcore/pull/32277 squash commit. ## Customer Impact Writing 0-length char buffers leads to an ArgumentOutOfRangeException. This may occur in a globalization context with certain chars such as `¿`. https://github.com/dotnet/aspnetcore/issues/31299#issuecomment-833078949 Also impacts Orchard: https://github.com/dotnet/aspnetcore/issues/31299#issue-842325059 ## Regression? - [ ] Yes - [x] No [If yes, specify the version the behavior has regressed from] ## Risk - [ ] High - [ ] Medium - [x] Low Low risk as we've just updated the logic slightly to permit 0 length buffers. ## Verification - [x] Manual (required) - [x] Automated ## Packaging changes reviewed? - [ ] Yes - [ ] No - [x] N/A Addresses https://github.com/dotnet/aspnetcore/issues/31299 --- eng/common/tools.ps1 | 2 +- .../src/Buffers/ViewBufferTextWriter.cs | 11 ++++++++--- .../test/Buffers/ViewBufferTextWriterTest.cs | 18 +++++++++++++++++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 2205c9e81173..198e3423aa6d 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -323,7 +323,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = } $msbuildVersionDir = if ([int]$vsMajorVersion -lt 16) { "$vsMajorVersion.0" } else { "Current" } - return $global:_MSBuildExe = Join-Path $vsInstallDir "MSBuild\$msbuildVersionDir\Bin\msbuild.exe" + return $global:_MSBuildExe = Join-Path $vsInstallDir "MSBuild\$msbuildVersionDir\Bin\amd64\msbuild.exe" } function InitializeVisualStudioEnvironmentVariables([string] $vsInstallDir, [string] $vsMajorVersion) { diff --git a/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBufferTextWriter.cs b/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBufferTextWriter.cs index 6eca8ddcb40e..3a7380d87a18 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBufferTextWriter.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBufferTextWriter.cs @@ -110,16 +110,21 @@ public override void Write(char[] buffer, int index, int count) throw new ArgumentNullException(nameof(buffer)); } - if (index < 0 || index >= buffer.Length) + if (index < 0) { throw new ArgumentOutOfRangeException(nameof(index)); } - if (count < 0 || (buffer.Length - index < count)) + if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } + if (buffer.Length - index < count) + { + throw new ArgumentOutOfRangeException(nameof(buffer.Length)); + } + Buffer.AppendHtml(new string(buffer, index, count)); } @@ -326,4 +331,4 @@ public override async Task FlushAsync() await _inner.FlushAsync(); } } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.ViewFeatures/test/Buffers/ViewBufferTextWriterTest.cs b/src/Mvc/Mvc.ViewFeatures/test/Buffers/ViewBufferTextWriterTest.cs index 7a0c5bb46c2e..63583495a97f 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/Buffers/ViewBufferTextWriterTest.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/Buffers/ViewBufferTextWriterTest.cs @@ -124,6 +124,22 @@ public async Task WriteLines_WritesCharBuffer() Assert.Equal(new[] { newLine, newLine }, actual); } + [Fact] + public void Write_WritesEmptyCharBuffer() + { + // Arrange + var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 4); + var writer = new ViewBufferTextWriter(buffer, Encoding.UTF8); + var charBuffer = new char[0]; + + // Act + writer.Write(charBuffer, 0, 0); + + // Assert + var actual = GetValues(buffer); + Assert.Equal(new[] { string.Empty }, actual); + } + [Fact] public async Task Write_WritesStringBuffer() { @@ -170,4 +186,4 @@ public override string ToString() } } } -} \ No newline at end of file +}