From 9bf512ff5d6b9803c1098b71bbbd1b07338692fa Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Mon, 28 Sep 2020 09:22:40 -0700 Subject: [PATCH] Emit warning if `ConvertTo-Json` exceeds `-Depth` value (#13692) --- .../commands/utility/WebCmdlet/JsonObject.cs | 13 +++++++++++++ .../resources/WebCmdletStrings.resx | 3 +++ .../SecureString.Tests.ps1 | 9 ++++++--- .../Microsoft.PowerShell.Utility/Json.Tests.ps1 | 7 +++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs index 2b15f15098..2b9bce8fd8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs @@ -457,6 +457,7 @@ namespace Microsoft.PowerShell.Commands { // Pre-process the object so that it serializes the same, except that properties whose // values cannot be evaluated are treated as having the value null. + _maxDepthWarningWritten = false; object preprocessedObject = ProcessValue(objectToProcess, currentDepth: 0, in context); var jsonSettings = new JsonSerializerSettings { @@ -484,6 +485,8 @@ namespace Microsoft.PowerShell.Commands } } + private static bool _maxDepthWarningWritten; + /// /// Return an alternate representation of the specified object that serializes the same JSON, except /// that properties that cannot be evaluated are treated as having the value null. @@ -561,6 +564,16 @@ namespace Microsoft.PowerShell.Commands { if (currentDepth > context.MaxDepth) { + if (!_maxDepthWarningWritten && context.Cmdlet != null) + { + _maxDepthWarningWritten = true; + string maxDepthMessage = string.Format( + CultureInfo.CurrentCulture, + WebCmdletStrings.JsonMaxDepthReached, + context.MaxDepth); + context.Cmdlet.WriteWarning(maxDepthMessage); + } + if (pso != null && pso.ImmediateBaseObjectIsEmpty) { // The obj is a pure PSObject, we convert the original PSObject to a string, diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx index 397718a09b..bb9b3002d6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/WebCmdletStrings.resx @@ -261,4 +261,7 @@ Retrying after interval of {0} seconds. Status code for previous attempt: {1} + + Resulting JSON is truncated as serialization has exceeded the set depth of {0}. + diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 index 1a0f7e0095..6b8f45d509 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 @@ -1,5 +1,9 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] +param() + Describe "SecureString conversion tests" -Tags "CI" { BeforeAll { $string = "ABCD" @@ -24,9 +28,8 @@ Describe "SecureString conversion tests" -Tags "CI" { } It "can convert back from a secure string" { - $secret = "abcd" - $ss1 = ConvertTo-SecureString -AsPlainText -Force $secret + $ss1 = ConvertTo-SecureString -AsPlainText -Force $string $ss2 = ConvertFrom-SecureString $ss1 | ConvertTo-SecureString - $ss2 | ConvertFrom-SecureString -AsPlainText | Should -Be $secret + $ss2 | ConvertFrom-SecureString -AsPlainText | Should -Be $string } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 index acd3f095d8..35926eab9d 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Json.Tests.ps1 @@ -1463,4 +1463,11 @@ Describe "Json Bug fixes" -Tags "Feature" { $result = "[1,","2,","3]" | ConvertFrom-Json $result.Count | Should -Be 3 } + + It 'ConvertTo-Json will output warning if depth is exceeded.' { + $a = @{ a = @{ b = @{ c = @{ d = 1 } } } } + $json = $a | ConvertTo-Json -Depth 2 -WarningVariable warningMessage -WarningAction SilentlyContinue + $json | Should -Not -BeNullOrEmpty + $warningMessage | Should -Not -BeNullOrEmpty + } }