From 78b5d5c4e98c8fb8ffd87a5681ce87e151e4bbad Mon Sep 17 00:00:00 2001 From: Joel Sallow <32407840+vexx32@users.noreply.github.com> Date: Thu, 26 Aug 2021 11:57:09 -0400 Subject: [PATCH 1/2] (#15949) CurrentCulture for datetime conversion Add-History was not respecting the culture settings and throwing when given any non-US datetime format. Fixed by ensuring we use the current culture for the conversion. --- .../engine/hostifaces/History.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/engine/hostifaces/History.cs b/src/System.Management.Automation/engine/hostifaces/History.cs index e1100b97487..dc74a46213f 100644 --- a/src/System.Management.Automation/engine/hostifaces/History.cs +++ b/src/System.Management.Automation/engine/hostifaces/History.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Management.Automation; using System.Management.Automation.Host; @@ -1449,14 +1450,14 @@ void ProcessRecord() // Read StartExecutionTime property object temp = GetPropertyValue(mshObject, "StartExecutionTime"); - if (temp == null || !LanguagePrimitives.TryConvertTo(temp, out DateTime startExecutionTime)) + if (temp == null || !LanguagePrimitives.TryConvertTo(temp, CultureInfo.CurrentCulture, out DateTime startExecutionTime)) { break; } // Read EndExecutionTime property temp = GetPropertyValue(mshObject, "EndExecutionTime"); - if (temp == null || !LanguagePrimitives.TryConvertTo(temp, out DateTime endExecutionTime)) + if (temp == null || !LanguagePrimitives.TryConvertTo(temp, CultureInfo.CurrentCulture, out DateTime endExecutionTime)) { break; } From 51cc480cd7a9b828fd76f8ff0ccc9074a79d16c7 Mon Sep 17 00:00:00 2001 From: Joel Sallow <32407840+vexx32@users.noreply.github.com> Date: Thu, 26 Aug 2021 12:14:01 -0400 Subject: [PATCH 2/2] (#15949) Add regression test --- .../History.Tests.ps1 | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/History.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/History.Tests.ps1 index 6841778af19..dc1b8b81b4d 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/History.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/History.Tests.ps1 @@ -49,6 +49,58 @@ Describe "History cmdlet test cases" -Tags "CI" { } } + Context 'Conversions and Culture tests' { + + BeforeAll { + $cultureTestCases = @( + @{ + Culture = 'en-us' + StartTime = '08/18/2021 16:43:50' + EndTime = '08/18/2021 16:44:50' + } + @{ + Culture = 'en-au' + StartTime = '18/08/2021 16:43:50' + EndTime = '18/08/2021 16:44:50' + } + ) + + $oldCulture = [cultureinfo]::CurrentCulture + } + + AfterEach { + [cultureinfo]::CurrentCulture = $oldCulture + } + + It "respects current culture settings when handling datetime conversions" -TestCases $cultureTestCases { + param($Culture, $StartTime, $EndTime) + + [cultureinfo]::CurrentCulture = [cultureinfo]::GetCultureInfo($Culture) + + $history = [PSCustomObject] @{ + CommandLine = "test-command" + ExecutionStatus = [Management.Automation.Runspaces.PipelineState]::Completed + StartExecutionTime = $StartTime + EndExecutionTime = $EndTime + } + + { $history | Add-History -ErrorAction Stop } | Should -Not -Throw -Because 'the datetime should be converted according to the current culture' + } + + It "throws an error when asked to convert a date format that doesn't match the current culture" { + [cultureinfo]::CurrentCulture = [cultureinfo]::GetCultureInfo('en-au') + $history = [PSCustomObject] @{ + CommandLine = "test-command" + ExecutionStatus = [Management.Automation.Runspaces.PipelineState]::Completed + StartExecutionTime = '08/18/2021 16:43:50' + EndExecutionTime = '08/18/2021 16:44:50' + } + + $errorMessage = 'Cannot add history because the input object has a format that is not valid.' + { $history | Add-History -ErrorAction Stop } | Should -Throw -ExpectedMessage $errorMessage + } + } + It "Tests Invoke-History on a cmdlet that generates output on all streams" { $streamSpammer = ' function StreamSpammer