From 1de749fbaadf7b1ee3e2bf83c8e02695d1d8c512 Mon Sep 17 00:00:00 2001 From: Michael Klement Date: Thu, 18 May 2017 00:54:15 -0400 Subject: [PATCH] Fix for Get-Content -Delimiter including the delimiter in the array elements returned (#3706) - functional changes --- .../namespaces/FileSystemContentStream.cs | 14 ++++++++++- .../Get-Content.Tests.ps1 | 23 +++++++++---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs index 6648c9de52..0ba8af6293 100644 --- a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs +++ b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs @@ -725,7 +725,19 @@ namespace Microsoft.PowerShell.Commands // We've reached the end of file or end of line. if (content.Length > 0) - blocks.Add(content.ToString()); + { + // Add the block read to the ouptut array list, trimming a trailing delimiter, if present. + // Note: If -Tail was specified, we get here in the course of 2 distinct passes: + // - Once while reading backward simply to determine the appropriate *start position* for later forward reading, ignoring the content of the blocks read (in reverse). + // - Then again during forward reading, for regular output processing; it is only then that trimming the delimiter is necessary. + // (Trimming it during backward reading would not only be unnecessary, but could interfere with determining the correct start position.) + string contentString = content.ToString(); + blocks.Add( + !readBackward && contentString.EndsWith(actualDelimiter, StringComparison.Ordinal) + ? contentString.Substring(0, content.Length - actualDelimiter.Length) + : contentString + ); + } int peekResult = readBackward ? _backReader.Peek() : _reader.Peek(); if (peekResult != -1) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 index c35e5a19cc..e72cebc5c7 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 @@ -63,11 +63,11 @@ Describe "Get-Content" -Tags "CI" { Get-Content -Path $testPath2 -Last 1 | Should Be $fifthline } It "Should be able to get content within a different drive" { - pushd env: + Push-Location env: $expectedoutput = [Environment]::GetEnvironmentVariable("PATH"); { Get-Content PATH } | Should Not Throw Get-Content PATH | Should Be $expectedoutput - popd + Pop-Location } #[BugId(BugDatabase.WindowsOutOfBandReleases, 906022)] It "should throw 'PSNotSupportedException' when you set-content to an unsupported provider" -Skip:($IsLinux -Or $IsOSX) { @@ -102,29 +102,28 @@ Describe "Get-Content" -Tags "CI" { for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} $result=get-content -path $testPath -delimiter "," -tail 2 $result.Length | Should Be 2 - if ($IsWindows) {$expected = "World3`r`nHello4,","World4`r`n" - } else {$expected = "World3`nHello4,","World4`n"} + $expected = "World3${nl}Hello4", "World4${nl}" for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} $result=get-content -path $testPath -delimiter "o" -tail 3 $result.Length | Should Be 3 - if ($IsWindows) {$expected = "rld3`r`nHello","4,Wo","rld4" - } else {$expected = "rld3`nHello","4,Wo","rld4"} - for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i].Trim() | Should BeExactly $expected[$i]} + $expected = "rld3${nl}Hell", '4,W', "rld4${nl}" + for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} $result=get-content -path $testPath -encoding:Byte -tail 10 $result.Length | Should Be 10 if ($IsWindows) { - $expected = "52","44","87","111","114","108","100","52","13","10" - for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} + $expected = 52, 44, 87, 111, 114, 108, 100, 52, 13, 10 + } else { + $expected = 111, 52, 44, 87, 111, 114, 108, 100, 52, 10 } + for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} } #[BugId(BugDatabase.WindowsOutOfBandReleases, 905829)] It "should get-content that matches the input string"{ set-content $testPath "Hello,llllWorlld","Hello2,llllWorlld2" $result=get-content $testPath -delimiter "ll" $result.Length | Should Be 9 - if ($IsWindows) {$expected = "Hell","o,ll","ll","Worll","d`r`nHell","o2,ll","ll","Worll","d2`r`n" - } else {$expected = "Hell","o,ll","ll","Worll","d`nHell","o2,ll","ll","Worll","d2`n"} - for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} + $expected = 'He', 'o,', '', 'Wor', "d${nl}He", 'o2,', '', 'Wor', "d2${nl}" + for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} } It "Should support NTFS streams using colon syntax" -Skip:(!$IsWindows) {