diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs index cbd9d4c36b4..1ec99fc8113 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs @@ -967,7 +967,8 @@ internal string ConvertPropertyNamesCSV(IList propertyNames) AppendStringWithEscapeAlways(_outputString, propertyName); break; case BaseCsvWritingCommand.QuoteKind.AsNeeded: - if (propertyName.Contains(_delimiter)) + + if (propertyName.AsSpan().IndexOfAny(_delimiter, '\n', '"') != -1) { AppendStringWithEscapeAlways(_outputString, propertyName); } @@ -1038,7 +1039,7 @@ internal string ConvertPSObjectToCSV(PSObject mshObject, IList propertyN AppendStringWithEscapeAlways(_outputString, value); break; case BaseCsvWritingCommand.QuoteKind.AsNeeded: - if (value != null && value.Contains(_delimiter)) + if (value != null && value.AsSpan().IndexOfAny(_delimiter, '\n', '"') != -1) { AppendStringWithEscapeAlways(_outputString, value); } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 index 494051507f7..2a121a7c16c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertTo-Csv.Tests.ps1 @@ -159,5 +159,44 @@ Describe "ConvertTo-Csv" -Tags "CI" { $result[0] | Should -BeExactly "`"FirstColumn`"rSecondColumn" $result[1] | Should -BeExactly "Hellor" } + + It "UseQuotes AsNeeded Escapes Delimiters" { + $testDelimitersObject = [pscustomobject]@{ "FirstColumn" = "Hello,"; "Second,Column" = "World" }; + + $result = $testDelimitersObject | ConvertTo-Csv -UseQuotes AsNeeded -Delimiter ',' + + $result[0] | Should -BeExactly "FirstColumn,`"Second,Column`"" + $result[1] | Should -BeExactly "`"Hello,`",World" + + $result = $testDelimitersObject | ConvertTo-Csv -UseQuotes AsNeeded -Delimiter "r" + + $result[0] | Should -BeExactly "`"FirstColumn`"rSecond,Column" + $result[1] | Should -BeExactly "Hello,r`"World`"" + } + + It "UseQuotes AsNeeded Escapes Newlines" { + $testCRLFObject = [pscustomobject]@{ "First`r`nColumn" = "Hello`r`nWorld" }; + $testLFObject = [pscustomobject]@{ "First`nColumn" = "Hello`nWorld" }; + + $result = $testCRLFObject | ConvertTo-Csv -UseQuotes AsNeeded + + $result[0] | Should -BeExactly "`"First`r`nColumn`"" + $result[1] | Should -BeExactly "`"Hello`r`nWorld`"" + + $result = $testLFObject | ConvertTo-Csv -UseQuotes AsNeeded + + $result[0] | Should -BeExactly "`"First`nColumn`"" + $result[1] | Should -BeExactly "`"Hello`nWorld`"" + } + + It "UseQuotes AsNeeded Escapes Quotes" { + $testQuotesObject = [pscustomobject]@{ "First`"Column" = "`"Hello`" World" }; + + $result = $testQuotesObject | ConvertTo-Csv -UseQuotes AsNeeded + + $result[0] | Should -BeExactly "`"First`"`"Column`"" + $result[1] | Should -BeExactly "`"`"`"Hello`"`" World`"" + } + } }