From 3f6391d5f419b57133c110ff7a801d8425d0f38f Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Wed, 9 Jan 2019 17:42:17 -0500 Subject: [PATCH 1/7] [Feature] Add configurable maximum depth in ConvertFrom-Json --- .../WebCmdlet/ConvertFromJsonCommand.cs | 9 +- .../commands/utility/WebCmdlet/JsonObject.cs | 40 +++++-- .../ConvertFrom-Json.Tests.ps1 | 103 ++++++++++++++++++ .../JsonObject.Tests.ps1 | 55 +++++++++- 4 files changed, 193 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs index f08d182bc06c..8badb3131c33 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs @@ -36,6 +36,13 @@ public class ConvertFromJsonCommand : Cmdlet [Parameter()] public SwitchParameter AsHashtable { get; set; } + /// + /// The maximum depth the json input is allowed to have. By default, it is 1024. For no maximum, set to 0. + /// + [Parameter] + [ValidateRange(ValidateRangeKind.NonNegative)] + public int Depth { get; set; } = 1024; + #endregion parameters #region overrides @@ -100,7 +107,7 @@ protected override void EndProcessing() private bool ConvertFromJsonHelper(string input) { ErrorRecord error = null; - object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, out error); + object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, Depth != 0 ? Depth : (int?) null, out error); if (error != null) { 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 5f341a77b2b6..46361821b56d 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs @@ -50,6 +50,23 @@ public static object ConvertFromJson(string input, out ErrorRecord error) /// if the parameter is true. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] public static object ConvertFromJson(string input, bool returnHashtable, out ErrorRecord error) + { + return ConvertFromJson(input, returnHashtable, maxDepth: 1024, out error); + } + + /// + /// Convert a Json string back to an object of type or + /// depending on parameter . + /// + /// The json text to convert. + /// True if the result should be returned as a + /// instead of a . + /// The max depth allowed when deserializing the json input. Set to null for no maximum. + /// An error record if the conversion failed. + /// A or a + /// if the parameter is true. + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + public static object ConvertFromJson(string input, bool returnHashtable, int? maxDepth, out ErrorRecord error) { if (input == null) { @@ -75,14 +92,18 @@ public static object ConvertFromJson(string input, bool returnHashtable, out Err // we just continue the deserialization. } - var obj = JsonConvert.DeserializeObject( - input, - new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.None, - MetadataPropertyHandling = MetadataPropertyHandling.Ignore, - MaxDepth = 1024 - }); + JsonSerializerSettings serializerSettings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.None, + MetadataPropertyHandling = MetadataPropertyHandling.Ignore + }; + + if (maxDepth != null) + { + serializerSettings.MaxDepth = maxDepth; + } + + var obj = JsonConvert.DeserializeObject(input, serializerSettings); switch (obj) { @@ -95,7 +116,8 @@ public static object ConvertFromJson(string input, bool returnHashtable, out Err return returnHashtable ? PopulateHashTableFromJArray(list, out error) : PopulateFromJArray(list, out error); - default: return obj; + default: + return obj; } } catch (JsonException je) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 index e4a32a5ee885..b16fa4a06463 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 @@ -7,6 +7,29 @@ Describe 'ConvertFrom-Json' -tags "CI" { @{ AsHashtable = $true } @{ AsHashtable = $false } ) + + $testCasesJsonDepthWithAndWithoutAsHashtableSwitch = @( + @{ Depth = 2; AsHashtable = $true } + @{ Depth = 2; AsHashtable = $false } + @{ Depth = 200; AsHashtable = $true } + @{ Depth = 200; AsHashtable = $false } + @{ Depth = 2000; AsHashtable = $true } + @{ Depth = 2000; AsHashtable = $false } + ) + + function GenerateNestedJson { + Param( + [int] $Depth + ) + + $nestedJson = "null" + + 1..$Depth | ForEach-Object { + $nestedJson = '{"' + $_ + '":' + $nestedJson + '}' + } + + return $nestedJson + } } It 'Can convert a single-line object with AsHashtable switch set to ' -TestCase $testCasesWithAndWithoutAsHashtableSwitch { @@ -52,4 +75,84 @@ Describe 'ConvertFrom-Json' -tags "CI" { $json | Should -BeOfType Hashtable } } + + It 'Can convert an object of depth 1024 by default with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { + Param($AsHashtable) + $nestedJson = GenerateNestedJson -Depth:1024 + + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable + + if ($AsHashtable) + { + $json | Should -BeOfType Hashtable + } + else + { + $json | Should -BeOfType PSCustomObject + } + } + + It 'Fails to convert an object of depth higher than 1024 by default with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { + Param($AsHashtable) + $nestedJson = GenerateNestedJson -Depth:1989 + + { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable } | + Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" + } + + It 'Can convert an object with depth less than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { + Param($AsHashtable, $Depth) + $nestedJson = GenerateNestedJson -Depth:($Depth - 1) + + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth + + if ($AsHashtable) + { + $json | Should -BeOfType Hashtable + } + else + { + $json | Should -BeOfType PSCustomObject + } + } + + It 'Can convert an object with depth equal to Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { + Param($AsHashtable, $Depth) + $nestedJson = GenerateNestedJson -Depth:$Depth + + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth + + if ($AsHashtable) + { + $json | Should -BeOfType Hashtable + } + else + { + $json | Should -BeOfType PSCustomObject + } + } + + It 'Can convert an object with depth equal to when Depth param is set to 0 and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { + Param($AsHashtable, $Depth) + $nestedJson = GenerateNestedJson -Depth:$Depth + + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:0 + + if ($AsHashtable) + { + $json | Should -BeOfType Hashtable + } + else + { + $json | Should -BeOfType PSCustomObject + } + } + + It 'Fails to convert an object with greater depth than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { + Param($AsHashtable, $Depth) + $nestedJson = GenerateNestedJson -Depth:($Depth + 1) + + { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth } | + Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" + } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 index a23d404bb1b2..03ee86ee5c25 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 @@ -5,9 +5,32 @@ Describe 'Unit tests for JsonObject' -tags "CI" { BeforeAll { $jsonWithEmptyKey = '{"": "Value"}' $jsonContainingKeysWithDifferentCasing = '{"key1": "Value1", "Key1": "Value2"}' + + $testCasesJsonDepthWithAndWithoutReturnHashTable = @( + @{ Depth = 2; ReturnHashTable = $true } + @{ Depth = 2; ReturnHashTable = $false } + @{ Depth = 200; ReturnHashTable = $true } + @{ Depth = 200; ReturnHashTable = $false } + @{ Depth = 2000; ReturnHashTable = $true } + @{ Depth = 2000; ReturnHashTable = $false } + ) + + function GenerateNestedJson { + Param( + [int] $Depth + ) + + $nestedJson = "null" + + 1..$Depth | ForEach-Object { + $nestedJson = '{"' + $_ + '":' + $nestedJson + '}' + } + + return $nestedJson + } } - It 'No error for valid string '''' with -ReturnHashTable:$' -TestCase @( + It 'No error for valid string '''' with -ReturnHashTable:' -TestCases @( @{ name = "null"; str = $null; ReturnHashTable = $true } @{ name = "empty"; str = ""; ReturnHashTable = $true } @{ name = "spaces"; str = " "; ReturnHashTable = $true } @@ -23,7 +46,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { $errRecord | Should -BeNullOrEmpty } - It 'Throw ArgumentException for invalid string '''' with -ReturnHashTable:$' -TestCase @( + It 'Throw ArgumentException for invalid string '''' with -ReturnHashTable:' -TestCases @( @{ name = "plain text"; str = "plaintext"; ReturnHashTable = $true } @{ name = "part"; str = '{"a" :'; ReturnHashTable = $true } @{ name = "plain text"; str = "plaintext"; ReturnHashTable = $false } @@ -34,7 +57,31 @@ Describe 'Unit tests for JsonObject' -tags "CI" { { [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($str, $ReturnHashTable, [ref]$errRecord) } | Should -Throw -ErrorId "ArgumentException" } - Context 'Empty key name' { + It 'Can Convert json with depth less than -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { + param ($Depth, $ReturnHashTable) + $errRecord = $null + $json = GenerateNestedJson -Depth:($Depth - 1) + [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) + $errRecord | Should -BeNullOrEmpty + } + + It 'Can Convert json with depth equal to -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { + param ($Depth, $ReturnHashTable) + $errRecord = $null + $json = GenerateNestedJson -Depth:$Depth + [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) + $errRecord | Should -BeNullOrEmpty + } + + It 'Throws ArgumentException for json with greater depth than -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { + param ($Depth, $ReturnHashTable) + $errRecord = $null + $json = GenerateNestedJson -Depth:($Depth + 1) + { [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) } | + Should -Throw -ErrorId "ArgumentException" + } + + Context 'Empty key name' { It 'Throw InvalidOperationException when json contains empty key name' { $errorRecord = $null [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($jsonWithEmptyKey, [ref]$errorRecord) @@ -51,7 +98,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { } Context 'Keys with different casing ' { - + It 'Throw InvalidOperationException when json contains key with different casing' { $errorRecord = $null [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($jsonContainingKeysWithDifferentCasing, [ref]$errorRecord) From ba5ee60a412e09800b626a8df4e0fc04a08821d6 Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Fri, 18 Jan 2019 15:47:06 -0500 Subject: [PATCH 2/7] [fixup!] [feature] Fix StyleCop issues and address code review --- .../WebCmdlet/ConvertFromJsonCommand.cs | 4 +- .../commands/utility/WebCmdlet/JsonObject.cs | 16 ++-- .../ConvertFrom-Json.Tests.ps1 | 89 ++++++++++++------- .../JsonObject.Tests.ps1 | 10 +-- 4 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs index 8badb3131c33..4dfd55e3806c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs @@ -37,7 +37,7 @@ public class ConvertFromJsonCommand : Cmdlet public SwitchParameter AsHashtable { get; set; } /// - /// The maximum depth the json input is allowed to have. By default, it is 1024. For no maximum, set to 0. + /// Gets or sets the maximum depth the json input is allowed to have. By default, it is 1024. For no maximum, set to 0. /// [Parameter] [ValidateRange(ValidateRangeKind.NonNegative)] @@ -107,7 +107,7 @@ protected override void EndProcessing() private bool ConvertFromJsonHelper(string input) { ErrorRecord error = null; - object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, Depth != 0 ? Depth : (int?) null, out error); + object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, Depth != 0 ? Depth : (int?)null, out error); if (error != null) { 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 46361821b56d..77726e64d3d8 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs @@ -16,7 +16,7 @@ namespace Microsoft.PowerShell.Commands /// /// JsonObject class. /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Preferring Json over JSON")] public static class JsonObject { private class DuplicateMemberHashSet : HashSet @@ -32,7 +32,7 @@ public DuplicateMemberHashSet(int capacity) : base(capacity, StringComparer.Ordi /// The json text to convert. /// An error record if the conversion failed. /// A PSObject. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Preferring Json over JSON")] public static object ConvertFromJson(string input, out ErrorRecord error) { return ConvertFromJson(input, returnHashtable: false, out error); @@ -48,7 +48,7 @@ public static object ConvertFromJson(string input, out ErrorRecord error) /// An error record if the conversion failed. /// A or a /// if the parameter is true. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Preferring Json over JSON")] public static object ConvertFromJson(string input, bool returnHashtable, out ErrorRecord error) { return ConvertFromJson(input, returnHashtable, maxDepth: 1024, out error); @@ -65,7 +65,7 @@ public static object ConvertFromJson(string input, bool returnHashtable, out Err /// An error record if the conversion failed. /// A or a /// if the parameter is true. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Preferring Json over JSON")] public static object ConvertFromJson(string input, bool returnHashtable, int? maxDepth, out ErrorRecord error) { if (input == null) @@ -95,14 +95,10 @@ public static object ConvertFromJson(string input, bool returnHashtable, int? ma JsonSerializerSettings serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, - MetadataPropertyHandling = MetadataPropertyHandling.Ignore + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + MaxDepth = maxDepth }; - if (maxDepth != null) - { - serializerSettings.MaxDepth = maxDepth; - } - var obj = JsonConvert.DeserializeObject(input, serializerSettings); switch (obj) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 index b16fa4a06463..059fad78e5ec 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 @@ -1,43 +1,46 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -Describe 'ConvertFrom-Json' -tags "CI" { - BeforeAll { - $testCasesWithAndWithoutAsHashtableSwitch = @( - @{ AsHashtable = $true } - @{ AsHashtable = $false } - ) +function New-NestedJson { + Param([int] $Depth) - $testCasesJsonDepthWithAndWithoutAsHashtableSwitch = @( - @{ Depth = 2; AsHashtable = $true } - @{ Depth = 2; AsHashtable = $false } - @{ Depth = 200; AsHashtable = $true } - @{ Depth = 200; AsHashtable = $false } - @{ Depth = 2000; AsHashtable = $true } - @{ Depth = 2000; AsHashtable = $false } - ) + $nestedJson = "true" - function GenerateNestedJson { - Param( - [int] $Depth - ) + $Depth..1 | ForEach-Object { + $nestedJson = '{"' + $_ + '":' + $nestedJson + '}' + } - $nestedJson = "null" + return $nestedJson +} - 1..$Depth | ForEach-Object { - $nestedJson = '{"' + $_ + '":' + $nestedJson + '}' - } +function Count-ObjectDepth { + Param([PSCustomObject] $InputObject) - return $nestedJson + for ($i=1; $i -le 100000; $i++) + { + $InputObject = Select-Object -InputObject:$InputObject -ExpandProperty:$i + if ($InputObject -Eq $true) + { + return $i } } +} + +Describe 'ConvertFrom-Json Unit Tests' -tags "CI" { - It 'Can convert a single-line object with AsHashtable switch set to ' -TestCase $testCasesWithAndWithoutAsHashtableSwitch { + BeforeAll { + $testCasesWithAndWithoutAsHashtableSwitch = @( + @{ AsHashtable = $true } + @{ AsHashtable = $false } + ) + } + + It 'Can convert a single-line object with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) ('{"a" : "1"}' | ConvertFrom-Json -AsHashtable:$AsHashtable).a | Should -Be 1 } - It 'Can convert one string-per-object with AsHashtable switch set to ' -TestCase $testCasesWithAndWithoutAsHashtableSwitch { + It 'Can convert one string-per-object with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) $json = @('{"a" : "1"}', '{"a" : "x"}') | ConvertFrom-Json -AsHashtable:$AsHashtable $json.Count | Should -Be 2 @@ -48,7 +51,7 @@ Describe 'ConvertFrom-Json' -tags "CI" { } } - It 'Can convert multi-line object with AsHashtable switch set to ' -TestCase $testCasesWithAndWithoutAsHashtableSwitch { + It 'Can convert multi-line object with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) $json = @('{"a" :', '"x"}') | ConvertFrom-Json -AsHashtable:$AsHashtable $json.a | Should -Be 'x' @@ -58,7 +61,7 @@ Describe 'ConvertFrom-Json' -tags "CI" { } } - It 'Can convert an object with Newtonsoft.Json metadata properties with AsHashtable switch set to ' -TestCase $testCasesWithAndWithoutAsHashtableSwitch { + It 'Can convert an object with Newtonsoft.Json metadata properties with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) $id = 13 $type = 'Calendar.Months.December' @@ -78,7 +81,7 @@ Describe 'ConvertFrom-Json' -tags "CI" { It 'Can convert an object of depth 1024 by default with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) - $nestedJson = GenerateNestedJson -Depth:1024 + $nestedJson = New-NestedJson -Depth:1024 $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable @@ -94,15 +97,29 @@ Describe 'ConvertFrom-Json' -tags "CI" { It 'Fails to convert an object of depth higher than 1024 by default with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) - $nestedJson = GenerateNestedJson -Depth:1989 + $nestedJson = New-NestedJson -Depth:1025 { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable } | Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" } +} + +Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { + + BeforeAll { + $testCasesJsonDepthWithAndWithoutAsHashtableSwitch = @( + @{ Depth = 2; AsHashtable = $true } + @{ Depth = 2; AsHashtable = $false } + @{ Depth = 200; AsHashtable = $true } + @{ Depth = 200; AsHashtable = $false } + @{ Depth = 2000; AsHashtable = $true } + @{ Depth = 2000; AsHashtable = $false } + ) + } It 'Can convert an object with depth less than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) - $nestedJson = GenerateNestedJson -Depth:($Depth - 1) + $nestedJson = New-NestedJson -Depth:($Depth - 1) $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth @@ -114,11 +131,13 @@ Describe 'ConvertFrom-Json' -tags "CI" { { $json | Should -BeOfType PSCustomObject } + + (Count-ObjectDepth -InputObject:$json) | Should -Be ($Depth - 1) } It 'Can convert an object with depth equal to Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) - $nestedJson = GenerateNestedJson -Depth:$Depth + $nestedJson = New-NestedJson -Depth:$Depth $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth @@ -130,11 +149,13 @@ Describe 'ConvertFrom-Json' -tags "CI" { { $json | Should -BeOfType PSCustomObject } + + (Count-ObjectDepth -InputObject:$json) | Should -Be $Depth } It 'Can convert an object with depth equal to when Depth param is set to 0 and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) - $nestedJson = GenerateNestedJson -Depth:$Depth + $nestedJson = New-NestedJson -Depth:$Depth $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:0 @@ -146,11 +167,13 @@ Describe 'ConvertFrom-Json' -tags "CI" { { $json | Should -BeOfType PSCustomObject } + + (Count-ObjectDepth -InputObject:$json) | Should -Be $Depth } It 'Fails to convert an object with greater depth than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) - $nestedJson = GenerateNestedJson -Depth:($Depth + 1) + $nestedJson = New-NestedJson -Depth:($Depth + 1) { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth } | Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 index 03ee86ee5c25..c5d581f8de31 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 @@ -15,12 +15,12 @@ Describe 'Unit tests for JsonObject' -tags "CI" { @{ Depth = 2000; ReturnHashTable = $false } ) - function GenerateNestedJson { + function New-NestedJson { Param( [int] $Depth ) - $nestedJson = "null" + $nestedJson = "true" 1..$Depth | ForEach-Object { $nestedJson = '{"' + $_ + '":' + $nestedJson + '}' @@ -60,7 +60,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { It 'Can Convert json with depth less than -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { param ($Depth, $ReturnHashTable) $errRecord = $null - $json = GenerateNestedJson -Depth:($Depth - 1) + $json = New-NestedJson -Depth:($Depth - 1) [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) $errRecord | Should -BeNullOrEmpty } @@ -68,7 +68,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { It 'Can Convert json with depth equal to -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { param ($Depth, $ReturnHashTable) $errRecord = $null - $json = GenerateNestedJson -Depth:$Depth + $json = New-NestedJson -Depth:$Depth [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) $errRecord | Should -BeNullOrEmpty } @@ -76,7 +76,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { It 'Throws ArgumentException for json with greater depth than -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { param ($Depth, $ReturnHashTable) $errRecord = $null - $json = GenerateNestedJson -Depth:($Depth + 1) + $json = New-NestedJson -Depth:($Depth + 1) { [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) } | Should -Throw -ErrorId "ArgumentException" } From 7c6d50ddd4080e7ffb7aca705ade5f85e3caeb44 Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Mon, 21 Jan 2019 17:56:35 -0500 Subject: [PATCH 3/7] [fixup!] [feature] Remove 0 option for no maximum --- .../WebCmdlet/ConvertFromJsonCommand.cs | 4 ++-- .../ConvertFrom-Json.Tests.ps1 | 18 ------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs index 4dfd55e3806c..200791dacd69 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs @@ -40,7 +40,7 @@ public class ConvertFromJsonCommand : Cmdlet /// Gets or sets the maximum depth the json input is allowed to have. By default, it is 1024. For no maximum, set to 0. /// [Parameter] - [ValidateRange(ValidateRangeKind.NonNegative)] + [ValidateRange(ValidateRangeKind.Positive)] public int Depth { get; set; } = 1024; #endregion parameters @@ -107,7 +107,7 @@ protected override void EndProcessing() private bool ConvertFromJsonHelper(string input) { ErrorRecord error = null; - object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, Depth != 0 ? Depth : (int?)null, out error); + object result = JsonObject.ConvertFromJson(input, AsHashtable.IsPresent, Depth, out error); if (error != null) { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 index 059fad78e5ec..185abca70168 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 @@ -153,24 +153,6 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { (Count-ObjectDepth -InputObject:$json) | Should -Be $Depth } - It 'Can convert an object with depth equal to when Depth param is set to 0 and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { - Param($AsHashtable, $Depth) - $nestedJson = New-NestedJson -Depth:$Depth - - $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:0 - - if ($AsHashtable) - { - $json | Should -BeOfType Hashtable - } - else - { - $json | Should -BeOfType PSCustomObject - } - - (Count-ObjectDepth -InputObject:$json) | Should -Be $Depth - } - It 'Fails to convert an object with greater depth than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) $nestedJson = New-NestedJson -Depth:($Depth + 1) From 27c141f61b61b034d47a3de8a4526a750c426f23 Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Sat, 9 Feb 2019 01:45:34 -0500 Subject: [PATCH 4/7] Remove colon for parameters per convention Co-Authored-By: louistio --- .../ConvertFrom-Json.Tests.ps1 | 26 +++++++++---------- .../JsonObject.Tests.ps1 | 6 ++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 index 185abca70168..fc735603ef66 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 @@ -18,8 +18,8 @@ function Count-ObjectDepth { for ($i=1; $i -le 100000; $i++) { - $InputObject = Select-Object -InputObject:$InputObject -ExpandProperty:$i - if ($InputObject -Eq $true) + $InputObject = Select-Object -InputObject $InputObject -ExpandProperty $i + if ($InputObject -eq $true) { return $i } @@ -81,9 +81,9 @@ Describe 'ConvertFrom-Json Unit Tests' -tags "CI" { It 'Can convert an object of depth 1024 by default with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) - $nestedJson = New-NestedJson -Depth:1024 + $nestedJson = New-NestedJson -Depth 1024 - $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable + $json = $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable if ($AsHashtable) { @@ -97,9 +97,9 @@ Describe 'ConvertFrom-Json Unit Tests' -tags "CI" { It 'Fails to convert an object of depth higher than 1024 by default with AsHashtable switch set to ' -TestCases $testCasesWithAndWithoutAsHashtableSwitch { Param($AsHashtable) - $nestedJson = New-NestedJson -Depth:1025 + $nestedJson = New-NestedJson -Depth 1025 - { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable } | + { $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable } | Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" } } @@ -119,9 +119,9 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { It 'Can convert an object with depth less than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) - $nestedJson = New-NestedJson -Depth:($Depth - 1) + $nestedJson = New-NestedJson -Depth ($Depth - 1) - $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth + $json = $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable -Depth:$Depth if ($AsHashtable) { @@ -132,14 +132,14 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { $json | Should -BeOfType PSCustomObject } - (Count-ObjectDepth -InputObject:$json) | Should -Be ($Depth - 1) + (Count-ObjectDepth -InputObject $json) | Should -Be ($Depth - 1) } It 'Can convert an object with depth equal to Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) $nestedJson = New-NestedJson -Depth:$Depth - $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth + $json = $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable -Depth $Depth if ($AsHashtable) { @@ -150,14 +150,14 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { $json | Should -BeOfType PSCustomObject } - (Count-ObjectDepth -InputObject:$json) | Should -Be $Depth + (Count-ObjectDepth -InputObject $json) | Should -Be $Depth } It 'Fails to convert an object with greater depth than Depth param set to and AsHashtable switch set to ' -TestCases $testCasesJsonDepthWithAndWithoutAsHashtableSwitch { Param($AsHashtable, $Depth) - $nestedJson = New-NestedJson -Depth:($Depth + 1) + $nestedJson = New-NestedJson -Depth ($Depth + 1) - { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth:$Depth } | + { $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable -Depth $Depth } | Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 index c5d581f8de31..c07e7af6ab81 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 @@ -60,7 +60,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { It 'Can Convert json with depth less than -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { param ($Depth, $ReturnHashTable) $errRecord = $null - $json = New-NestedJson -Depth:($Depth - 1) + $json = New-NestedJson -Depth ($Depth - 1) [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) $errRecord | Should -BeNullOrEmpty } @@ -68,7 +68,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { It 'Can Convert json with depth equal to -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { param ($Depth, $ReturnHashTable) $errRecord = $null - $json = New-NestedJson -Depth:$Depth + $json = New-NestedJson -Depth $Depth [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) $errRecord | Should -BeNullOrEmpty } @@ -76,7 +76,7 @@ Describe 'Unit tests for JsonObject' -tags "CI" { It 'Throws ArgumentException for json with greater depth than -Depth: with -ReturnHashTable:' -TestCases $testCasesJsonDepthWithAndWithoutReturnHashTable { param ($Depth, $ReturnHashTable) $errRecord = $null - $json = New-NestedJson -Depth:($Depth + 1) + $json = New-NestedJson -Depth ($Depth + 1) { [Microsoft.PowerShell.Commands.JsonObject]::ConvertFromJson($json, $ReturnHashTable, $Depth, [ref]$errRecord) } | Should -Throw -ErrorId "ArgumentException" } From 541524e62a9c28fbf7cbbac1094de0cd5e49ba58 Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Sat, 9 Feb 2019 01:47:20 -0500 Subject: [PATCH 5/7] [fixup!] [feature] Use ValidateRange in New-NestedJson --- .../ConvertFrom-Json.Tests.ps1 | 8 ++++++-- .../Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 index fc735603ef66..71cfe72a45ba 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 @@ -2,7 +2,11 @@ # Licensed under the MIT License. function New-NestedJson { - Param([int] $Depth) + Param( + [ValidateRange(1, 2048)] + [int] + $Depth + ) $nestedJson = "true" @@ -16,7 +20,7 @@ function New-NestedJson { function Count-ObjectDepth { Param([PSCustomObject] $InputObject) - for ($i=1; $i -le 100000; $i++) + for ($i=1; $i -le 2048; $i++) { $InputObject = Select-Object -InputObject $InputObject -ExpandProperty $i if ($InputObject -eq $true) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 index c07e7af6ab81..2c61abd2915f 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 @@ -17,12 +17,14 @@ Describe 'Unit tests for JsonObject' -tags "CI" { function New-NestedJson { Param( - [int] $Depth + [ValidateRange(1, 2048)] + [int] + $Depth ) $nestedJson = "true" - 1..$Depth | ForEach-Object { + $Depth..1 | ForEach-Object { $nestedJson = '{"' + $_ + '":' + $nestedJson + '}' } From eecc8997699ed42f5db5200c0029d23cac871660 Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Sat, 9 Feb 2019 15:47:54 -0500 Subject: [PATCH 6/7] [fixup!] [feature] Use colon for -AsHashtable --- .../ConvertFrom-Json.Tests.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 index 71cfe72a45ba..8160864dd3c7 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 @@ -87,7 +87,7 @@ Describe 'ConvertFrom-Json Unit Tests' -tags "CI" { Param($AsHashtable) $nestedJson = New-NestedJson -Depth 1024 - $json = $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable if ($AsHashtable) { @@ -103,7 +103,7 @@ Describe 'ConvertFrom-Json Unit Tests' -tags "CI" { Param($AsHashtable) $nestedJson = New-NestedJson -Depth 1025 - { $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable } | + { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable } | Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" } } @@ -125,7 +125,7 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { Param($AsHashtable, $Depth) $nestedJson = New-NestedJson -Depth ($Depth - 1) - $json = $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable -Depth:$Depth + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth $Depth if ($AsHashtable) { @@ -143,7 +143,7 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { Param($AsHashtable, $Depth) $nestedJson = New-NestedJson -Depth:$Depth - $json = $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable -Depth $Depth + $json = $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth $Depth if ($AsHashtable) { @@ -161,7 +161,7 @@ Describe 'ConvertFrom-Json -Depth Tests' -tags "Feature" { Param($AsHashtable, $Depth) $nestedJson = New-NestedJson -Depth ($Depth + 1) - { $nestedJson | ConvertFrom-Json -AsHashtable $AsHashtable -Depth $Depth } | + { $nestedJson | ConvertFrom-Json -AsHashtable:$AsHashtable -Depth $Depth } | Should -Throw -ErrorId "System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand" } } From dc398544a7a20c8d8a0daccd55f5e093903cf01e Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Mon, 11 Feb 2019 02:14:47 -0500 Subject: [PATCH 7/7] [fixup!] [feature] Capitalize JSON in comments and use Parameter() Co-Authored-By: louistio --- .../commands/utility/WebCmdlet/ConvertFromJsonCommand.cs | 4 ++-- .../commands/utility/WebCmdlet/JsonObject.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs index ea212359a678..3556c1ac39cd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs @@ -37,9 +37,9 @@ public class ConvertFromJsonCommand : Cmdlet public SwitchParameter AsHashtable { get; set; } /// - /// Gets or sets the maximum depth the json input is allowed to have. By default, it is 1024. For no maximum, set to 0. + /// Gets or sets the maximum depth the JSON input is allowed to have. By default, it is 1024. /// - [Parameter] + [Parameter()] [ValidateRange(ValidateRangeKind.Positive)] public int Depth { get; set; } = 1024; 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 710e0ea2052b..a2770b699a24 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs @@ -135,10 +135,10 @@ public static object ConvertFromJson(string input, bool returnHashtable, out Err } /// - /// Convert a Json string back to an object of type or + /// Convert a JSON string back to an object of type or /// depending on parameter . /// - /// The json text to convert. + /// The JSON text to convert. /// True if the result should be returned as a /// instead of a . /// The max depth allowed when deserializing the json input. Set to null for no maximum.