GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Add configurable maximum depth in ConvertFrom-Json with `-Depth` by adamgauthier · Pull Request #8199 · PowerShell/PowerShell

Conversation

@adamgauthier

@adamgauthier Adam Gauthier (adamgauthier) commented Nov 7, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

PR Summary

The ConvertFrom-Json cmdlet is currently limited to deserializing json objects with a maximum depth of 1024. An exception is thrown if the input's depth reaches that maximum.

This PR:

  • Adds an optional -Depth parameter to the cmdlet which lets the user to specify a maximum depth allowed for deserialization, which will overwrite the default maximum of 1024.

Closes #3182

PR Checklist

  • PR has a meaningful title
    • Use the present tense and imperative mood when describing your changes
  • Summarized changes
  • Change is not breaking
  • Make sure all .h, .cpp, .cs, .ps1 and .psm1 files have the correct copyright header
  • This PR is ready to merge and is not Work in Progress.
    • If the PR is work in progress, please add the prefix WIP: to the beginning of the title and remove the prefix when the PR is ready.
  • User-facing changes
    • User-facing Documentation needed
      • Issue filed - Issue link: Document -Depth parameter for ConvertFrom-Json MicrosoftDocs/PowerShell-Docs#3736
  • Testing - New and feature
    • Make sure you've added a new test if existing tests do not effectively test the code changed
      • Add [feature] if the change is significant or affects feature tests

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Platou and chuanjiao10 reacted with thumbs up emoji
All reactions
  • 👍 2 reactions
@adamgauthier
Adam Gauthier (adamgauthier) requested review from James Truher (JamesWTruher) and Paul Higinbotham (PaulHigin) as code owners November 7, 2018 05:46
@adamgauthier Adam Gauthier (adamgauthier) mentioned this pull request Nov 7, 2018
In ConvertFrom-Json, the max depth for deserialization is 1024, however, we should investigate if the current implementation can handle object of greater depth. #3182
Closed
iSazonov
Ilya (iSazonov) reviewed Nov 7, 2018
View reviewed changes

@iSazonov Ilya (iSazonov) left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need PowerShell Committee approvment:

  • Add new parameter -MaxDepth, should it be int or int? ?
  • Add new overload
public static object ConvertFromJson(string input, bool returnHashtable, int? maxDepth, out ErrorRecord error)

/cc Steve Lee (@SteveL-MSFT)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs Outdated

@iSazonov Ilya (iSazonov) Nov 7, 2018

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be:

Suggested change
public int? MaxDepth { get; set; }
public int MaxDepth { get; set; } = int.MaxValue;

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@vexx32 Rain Sallow (/u/ta11ow) (vexx32) Nov 7, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we have any default cmdlets with nullable input types, so I don't see any need for that. I would think that since it's a MaxDepth parameter we could either:

  1. Opt for uint (because negative depth is insensible) with a maximum set even perhaps at something comparable to the ConvertTo-Json command which has 2 as its default -MaxDepth, or
  2. Simply set the default to -1 and have the code paths treat that as "no maximum depth".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@iSazonov Ilya (iSazonov) Nov 7, 2018

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Underline type https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonSerializerSettings_MaxDepth.htm

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

vexx32 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@adamgauthier Adam Gauthier (adamgauthier) Nov 7, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback, as this is my first feature contribution, I wasn't sure how to implement everything 😅

Ilya (@iSazonov) your suggestion would mean there would be no way to differentiate no maximum depth and the user wanting a maximum depth of 2147483647. I think the value representing no maximum depth should really be outside of the user input range for maximum depth (1 - 2147483647)!

Rain Sallow (/u/ta11ow) (@vexx32) I could do a uint with range of 1 - int.MaxValue and use 0 as default value representing no maximum. I could also do int with -1 as default value representing no maximum. If that's what the team prefers, I don't mind, I was just using null as a way to represent the parameter not being specified. 😄

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@vexx32 Rain Sallow (/u/ta11ow) (vexx32) Nov 7, 2018

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you have a point there; a maximum depth of 0 is also pretty silly. However, given that the underlying json API uses int for these parameters, as Ilya (@iSazonov) pointed out, we can't safely use uint as it would allow the user to specify values that the underlying API can't handle.

I think we need some clarification on whether the json API itself has a defined specification for "no maximum depth" and what that would look like.

Mark Kraus (@markekraus) I know you worked on Invoke-RestMethod a good bit, do you have any insight to offer on the json API that might help here?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@adamgauthier Adam Gauthier (adamgauthier) Nov 7, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rain Sallow (/u/ta11ow) (@vexx32) I meant I could do uint with [ValidateRange(1, int.MaxValue)], effectively not allowing user input values outside the underlying API. (but we'll have to cast the value so it might just be better to use int directly?)

Also, I was proposing 0 because the underlying API doesn't allow 0 for MaxDepth, only 1 - int.MaxValue (it throws an exception at runtime, see here).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

vexx32 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@vexx32 Rain Sallow (/u/ta11ow) (vexx32) Nov 7, 2018

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's just funny at that point. If you're going to throw that early... why not just make it uint haha!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

adamgauthier reacted with laugh emoji
All reactions
  • 😄 1 reaction

@markekraus Mark Kraus (markekraus) Nov 9, 2018

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underlying type is an int, so we should probably accept an int with the [ValidateRange(1, int.MaxValue)]. realistically, an JSON with a depth greater than int32.MaxValue is probably bad JSON to begin with.... A nullable type for this would be weird. accepting -1 is also weird.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

vexx32 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@iSazonov Ilya (iSazonov) added the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Nov 7, 2018
@SteveL-MSFT

Steve Lee (SteveL-MSFT) commented Nov 7, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

@PowerShell/powershell-committee reviewed this, the design should be that there is a -Depth parameter (which aligns with ConvertTo-Json) which defaults to 1024 and the user can change as needed. This is to preserve existing behavior.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@SteveL-MSFT Steve Lee (SteveL-MSFT) added Committee-Reviewed PS-Committee has reviewed this and made a decision and removed Review - Committee The PR/Issue needs a review from the PowerShell Committee labels Nov 7, 2018
@adamgauthier

Adam Gauthier (adamgauthier) commented Nov 8, 2018

Copy link
Copy Markdown
Contributor Author

Steve Lee (@SteveL-MSFT) with all due respect, may I ask to reconsider this decision? The -Depth parameter in ConvertTo-Json does not have the same behavior as the -MaxDepth I implemented here:

-Depth in ConvertTo-Json will quietly suppress conversion after the depth level specified (2 by default), for example:

PS C:\> ConvertTo-Json (ConvertFrom-Json '{"1":{"2":{"3":{"4":{"5":1}}}}}')
{
  "1": {
    "2": {
      "3": "@{4=}"
    }
  }
}

-MaxDepth as implemented here strictly fails the conversion if the depth of the json exceeds the value, the same way ConvertFrom-Json currently fails if the depth is higher than 1024 and ConvertTo-Json currently fails if the depth is higher than 100. With this in mind, -MaxDepth could also be implemented for ConvertTo-Json and is not equivalent to its -Depth parameter.

Furthermore, I believe the current -Depth parameter of ConvertTo-Json is not intuitive and has caused a lot of confusion for users in the past (there are lots of threads about it on StackOverflow, for example). What json serializer do you expect to stop serializing at third depth level by default? This leads to the user having to know beforehand what depth his input has in order for conversion to work properly (an unrealistic thing to expect). I don't think we should model new parameters aligning with it.

I also think putting 1024 as the default is a bad idea. This would make it so there is no way to say "I don't want a maximum depth" (which is the most common scenario). It would also lead to the same problem ConvertTo-Json currently has: we expect the user to know beforehand what is the depth of his input.

I know it would be a breaking change to have no maximum be the new default, but is it really a common scenario that someone is relying on the default behavior failing with input of depth higher than 1024? I think handling higher depth with this new parameter is the perfect opportunity to change the default behavior to something more intuitive: the cmdlets should handle whatever is thrown at them, if the user expects the input to cause a DoS in their system (which I assume was the reason for this default max depth), then they should specify a maximum depth optionally.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov

Ilya (iSazonov) commented Nov 8, 2018

Copy link
Copy Markdown
Collaborator

So we should discuss:

  • Depth vs MaxDepth
  • Defaults
  • Nullable type for the parameter

My thoughts:

  • Depth name looks good to be consistent with ConvertTo-Json.
  • Current default is 2 in ConvertTo-Json. What is history why we use the value? Seems for ConvertFrom-Json the default should be larger. And defaults for both cmdlets should be the same for better UX: $source | ConvertFrom-Json | ConvertTo-Json is expected to return $source.
  • I believe nullable type has no sense in scripts.

/cc Mark Kraus (@markekraus) Michael Klement (@mklement0) What do you think?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@SteveL-MSFT

Steve Lee (SteveL-MSFT) commented Nov 8, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Adam Gauthier (@louistio) to be clear, the decision regarding -Depth is simply the name of the parameter not the semantics. At the time of discussion, we were not aware of the limitation of "maxdepth" would fail the entire operation rather than serialize up to 1024. This (to me) seems broken, but would be a breaking change. In light of that information, it's worth discussing again the the committee to see if there should be two parameters (which would be confusing to the user) or accept a breaking change at the limit.

It would also be useful if you can provide examples where the current limit of 1024 is insufficient.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@SteveL-MSFT Steve Lee (SteveL-MSFT) added Review - Committee The PR/Issue needs a review from the PowerShell Committee and removed Committee-Reviewed PS-Committee has reviewed this and made a decision labels Nov 8, 2018
@adamgauthier

Adam Gauthier (adamgauthier) commented Nov 8, 2018

Copy link
Copy Markdown
Contributor Author

Steve Lee (@SteveL-MSFT) Thank you! To be clear the naming is not a big concern to me, it's more about the bad user experience of having a default that I described later in my post. 😄

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@joeyaiello

Joey Aiello (joeyaiello) commented Nov 15, 2018

Copy link
Copy Markdown
Contributor

@PowerShell/powershell-committee had a very bikeshed conversation about this, and we understand the parallel concepts argument with this rough visualization:

ConvertTo-Json          -Depth                               (MaxDepth is internal as 100)
                   (produces partial)
ConvertFrom-Json        [-Depth]                             (MaxDepth is internal as 1024 and settable)
   (doesn't make sense because we don't have types)          (could be called -MaxDepth, could be called -Depth for PS consistency)

Does anyone else actually care?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rjmholt

Rob Holt (rjmholt) commented Nov 15, 2018

Copy link
Copy Markdown
Collaborator

Two cents:

  • The MaxDepth internal value in ConvertTo-Json must have a low default because PowerShell must be secure by default -- omitting a parameter shouldn't open up a DoS attack, but setting it to a high (or negative - to turn off) value => you're on your own
  • MaxDepth makes sense as a settable parameter that a user can specify to avoid errors with large objects
  • Exposing that, it should be symmetric with anything on ConvertFrom-Json where symmetry makes sense
markekraus reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov

Ilya (iSazonov) commented Nov 15, 2018

Copy link
Copy Markdown
Collaborator

Mark Kraus (@markekraus) Michael Klement (@mklement0) Have you any thoughts about consistency of Depth parameters?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov Ilya (iSazonov) added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Nov 16, 2018
@markekraus

Mark Kraus (markekraus) commented Nov 18, 2018

Copy link
Copy Markdown
Contributor

I agree with Rob Holt (@rjmholt)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov

Ilya (iSazonov) commented Nov 18, 2018

Copy link
Copy Markdown
Collaborator

Joey Aiello (@joeyaiello) Steve Lee (@SteveL-MSFT) Seems we can make final conclusion and continue the PR.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mklement0

Michael Klement (mklement0) commented Nov 18, 2018

Copy link
Copy Markdown
Contributor

In terms of naming, -Depth is currently consistently being used to denote a maximum recursion depth.

Regrettably, exceeding that maximum depth doesn't cause an error in ConvertTo-Json, but results in near-useless .psobject.ToString() serialization of property values that exceed the depth.
In combination with the low default -Depth value of 2, that makes for frequent user frustration, as Adam Gauthier (@louistio) notes - the current ConvertTo-Json behavior frequently amounts to quiet de-facto failure.

In a utopian world, unencumbered by backward-compatibility concerns:

  • Having a high-enough default that accommodates most use cases, yet prevents DoS attacks, as Rob Holt (@rjmholt) suggests, makes sense.

  • Exceeding that default must fail.

  • You should be able to opt out of the default fail-if-exceeded limit with an explicit -MaxDepth value, again with failure if exceeded; to avoid the awkwardness of -MaxDepth ([int]::MaxValue) or -MaxDepth -1, an additional -NoMaxDepth switch could be considered, if really needed.

  • You should be able to intentionally cut off recursion with -Depth, similar to how Get-ChildItem uses the parameter: while there may be additional levels, you choose to ignore them.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier

Adam Gauthier (adamgauthier) commented Nov 18, 2018

Copy link
Copy Markdown
Contributor Author

Rob Holt (@rjmholt) Fair point about powershell being secure by default.

Michael Klement (@mklement0) I agree with everything you're saying, I think you basically put into words what I was struggling to convey. I like the idea of another switch for no -NoMaxDepth, more elegant than another invalid value!

I would like to implement an equivalent to -MaxDepth for ConvertTo-Json too, to allow users to change the current default 100 value. If we're naming this parameter -Depth, it would conflict with the current ConvertTo-Json parameter, unless the team decides to break its backwards compatibility and make it explicitly fail from now on. In my opinion this is the best option because the current behavior of that parameter is a pain for powershell users for the reasons I explained above but I understand the backward compatibility concerns.

mklement0 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markekraus

Mark Kraus (markekraus) commented Nov 19, 2018

Copy link
Copy Markdown
Contributor

Adam Gauthier (@louistio) What would be the difference between -Depth and -MaxDepth on ConvertTo-Json

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier

Adam Gauthier (adamgauthier) commented Nov 19, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

Mark Kraus (@markekraus) As mentioned above, the behavior difference resides in the cmdlet failing on input exceeding the maximum depth. -Depth silently suppresses exceeding depth (soft) and -MaxDepth fails the execution (hard).

Currently ConvertTo-Json has a default soft depth of 2 (configurable with -Depth) and default hard max depth of 100 (non configurable). ConvertFrom-Json has no concept of soft max depth and a default hard max depth of 1024 (non configurable - what this PR adds).

What I'm saying is I'd be fine with changing ConvertTo-Json's -Depth into a hard max depth but I know this is compatibility breaking.

mklement0 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markekraus

Mark Kraus (markekraus) commented Nov 19, 2018

Copy link
Copy Markdown
Contributor

I think it would be confusing to have both Depth and Max Depth. We should have one for the depth and one to adjust the behavior of that depth.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mklement0

Michael Klement (mklement0) commented Nov 19, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

True, having both -MaxDepth and -Depth could be confusing; on further reflection, all we need is
-Depth
:

-Depth can be the opt-in, I-know-that-many-levels-is-all-I-need-or-I-really-want-that-many-levels parameter.

(What is conceptually) -MaxDepth needn't be user-facing (but needs to be documented): it can a fixed, documented limit that is chosen high enough to (a) accommodate most use cases while (b) preventing DoS attacks - and exceeding that limit causes an error.

-Depth then does double duty:

  • You use it for data whose depth falls below the documented, fixed max. depth, in case you intentionally want to cut it off at the specified depth.

  • You also use it for data that you do want whose depth happens to exceed the internal (but documented) max. depth that you do want to serialize/deserialize in full nonetheless.

I personally then don't see a need for any other parameters - I think opting into levels beyond the fixed limit with an explicit number or even with -Depth ([int]::MaxValue) (without the need for an abstract -NoMaxDepth switch) strikes me as acceptable, because I presume this to be a rare use case.

In the absence of using -Depth in a given command:

  • You either live happily ever after, given that most commands won't hit the fixed limit.

  • You are alerted to a problem through the error that is reported if your data unexpectedly exceeds the fixed limit (in which case you'll need to use -Depth, if using that many levels is really your intent).

As for required changes and backward compatibility:

  • Remove the default -Depth of 2 from ConvertTo-Json (from what I understand, it already has a fixed, internal limit of 100 beyond which it fails).

  • Document the fixed limits.

  • The only way in which existing code could be impacted is in that payloads generated with ConvertTo-Json could now increase, if users previously implied on the implicit cut-off at depth 2 - that strikes me as a Bucket 3: Unlikely Grey Area change.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markekraus

Mark Kraus (markekraus) commented Nov 19, 2018

Copy link
Copy Markdown
Contributor

There are 2 things: 1) The maximum depth you want to convert and 2) the behavior of that conversion. They both need to be configurable, IMO and just relying on a single param for both would be a pain.

There are a very large number of objects passed to ConvertTo-Json where only having a max depth that errors would make them impossible objects to convert. We need the ability to squash. This includes object types that have parent child mappings. There would no way to convert those without squashing.

Consider the Current behavior:

cmdlet Max depth Default Depth Depth Configurable Default Behavior Behavior Configurable
ConvertTo-Json 100 2 yes Silently Squash no
ConvertFrom-Json 1024 1024 no Error no

I would ultimately like to see it as this:

cmdlet Max depth Default Depth Depth Configurable Default Behavior Behavior Configurable
ConvertTo-Json Int32.MaxValue 2 yes Error yes
ConvertFrom-Json Int32.MaxValue 1024 yes Error yes

Ideally we would would want a -Depth param that sets the max depth and an -Squash ( or something). we still need default depths (2 for ConvertTo-Json and 1024 for ConverFrom-Json). it would be nice to add the ability to change the behavior of ConvertTo-Json, but that's a bit out of scope for this PR. It would also be nice to be able to squash with ConvertFrom-Json but that i also a bit out of scope for this PR (or maybe it is easier than I think?).

But, keeping in mind that we could add parameters to control the behavior later, for this PR all we need is to add -Depth to ConvertFrom-Json with a default of 1024, of type Int, with a ValidateRange of 1 to Int32.MaxValue. I don't see a pressing need to change the behavior of ConvertTo-Json in the same PR, but if it was I would recommend changing the internal max depth from 100 to Int.MaxValue (Keeping Depth at a default of 2). That way we are safe from DoS by default, but let the user hold their fate in their own hands should they wish to try an absurdly deep object.

A bit of flavor text: A JSON object over 1024 in depth is an outlier. Other than abused/broken APIs or contrived examples, I have rarely seen a legit JSON objet that is deeper than ~30. On the flip-side, infinitely deep objects are very commonly thrown at ConvertTo-Json. (Based on my experience, YMMV.)

rjmholt reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov

Ilya (iSazonov) commented Nov 19, 2018

Copy link
Copy Markdown
Collaborator

I don't see a pressing need to change the behavior of ConvertTo-Json in the same PR, but if it was I would recommend

I think it is better to make both changes for Depth in the PR to get clean history and continue with rest ideas in follow PRs.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mklement0

Michael Klement (mklement0) commented Nov 26, 2018 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Thanks for the analysis, Mark Kraus (@markekraus), but I still think -Depth is enough, for both ConvertTo-Json and ConvertFrom-Json:

  • In the absence of -Depth, exceeding the documented, hard-coded max. depth will result in an error.

  • Use of -Depth never results in an error, and is used intentionally to:

    • truncate the object tree at the specified level (whether or not that level is below or above the hard-coded max. depth)
    • opt-into object trees that are deeper than the hard-coded max. depth

To put it differently: the hard-coded max. depth is then no longer a default value for -Depth, it is a built-in safety mechanism that can be overridden with -Depth, if needed (which, with reasonably high defaults, will rarely be necessary).

If you have a "runaway" tree of infinite depth, then the hard-coded max. will save you.
If you actually do need more depth, you can opt in with -Depth.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@SteveL-MSFT

Steve Lee (SteveL-MSFT) commented Nov 28, 2018

Copy link
Copy Markdown
Member

@PowerShell/powershell-committee appreciates the discussion and we still suggest that we have the single -Depth defaulting to 1024 on ConvertFrom-Json to preserve existing behavior and not have any changes to erroring out vs truncation as it seems that there is no practical reason to force symmetry between the two while incurring a breaking change.

markekraus reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier Adam Gauthier (adamgauthier) changed the title Deserialize objects with greather depth than 1024 in ConvertFrom-Json Add configurable maximum depth in ConvertFrom-Json with -Depth Jan 10, 2019
@iSazonov

Ilya (iSazonov) commented Jan 10, 2019

Copy link
Copy Markdown
Collaborator

Mark Kraus (@markekraus) Michael Klement (@mklement0) Steve Lee (@SteveL-MSFT) Please update your review.

Adam Gauthier (@louistio) Please fix StyleCop issues.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

SteveL-MSFT
Steve Lee (SteveL-MSFT) requested changes Jan 10, 2019
View reviewed changes
Comment thread src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs Outdated
MetadataPropertyHandling = MetadataPropertyHandling.Ignore
};

if (maxDepth != null)

@SteveL-MSFT Steve Lee (SteveL-MSFT) Jan 10, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.MaxDepth == null means no limit, so it doesn't seem this check is necessary

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Outdated
@{ Depth = 2; AsHashtable = $false }
@{ Depth = 200; AsHashtable = $true }
@{ Depth = 200; AsHashtable = $false }
@{ Depth = 2000; AsHashtable = $true }

@SteveL-MSFT Steve Lee (SteveL-MSFT) Jan 10, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long does this take to run? If longer than 2 secs, we should have them as Feature tests instead of CI.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Outdated

It 'Fails to convert an object of depth higher than 1024 by default with AsHashtable switch set to <AsHashtable>' -TestCases $testCasesWithAndWithoutAsHashtableSwitch {
Param($AsHashtable)
$nestedJson = GenerateNestedJson -Depth:1989

@SteveL-MSFT Steve Lee (SteveL-MSFT) Jan 10, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't 1025 be sufficient? no need to spend extra cpu here

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Outdated
@{ Depth = 2000; AsHashtable = $false }
)

function GenerateNestedJson {

@SteveL-MSFT Steve Lee (SteveL-MSFT) Jan 10, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer New-NestedJson

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Adam Gauthier (adamgauthier) added 3 commits January 18, 2019 15:47
@adamgauthier
[fixup!] [feature] Fix StyleCop issues and address code review
ba5ee60
@adamgauthier
[fixup!] [feature] Remove 0 option for no maximum
7c6d50d
@adamgauthier
Merge remote-tracking branch 'upstream/master' into convertfrom-json-…
c71ff00
…max-depth
SteveL-MSFT
Steve Lee (SteveL-MSFT) requested changes Feb 2, 2019
View reviewed changes
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Outdated
function Count-ObjectDepth {
Param([PSCustomObject] $InputObject)

for ($i=1; $i -le 100000; $i++)

@SteveL-MSFT Steve Lee (SteveL-MSFT) Feb 2, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you have a max depth for checking here, you should probably enforce this limit on new-nestedjson. Also, I'm not sure we need to test this deep, perhaps 2048 is sufficient

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

iSazonov and adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 2 reactions
@iSazonov Ilya (iSazonov) self-assigned this Feb 2, 2019
iSazonov
Ilya (iSazonov) reviewed Feb 8, 2019
View reviewed changes

@iSazonov Ilya (iSazonov) left a comment

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adam Gauthier (@louistio) Have you time to continue?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/ConvertFrom-Json.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/JsonObject.Tests.ps1 Resolved

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier
Remove colon for parameters per convention
27c141f
Co-Authored-By: louistio <[email protected]>
@adamgauthier

Adam Gauthier (adamgauthier) commented Feb 9, 2019

Copy link
Copy Markdown
Contributor Author

Ilya (@iSazonov) Hey! Sorry, I wasn't aware of the colon convention 😅 I applied your suggestions through GitHub's integrated tool, but there seems to be error when running the tests without the colons! I get errors like:

ConvertFrom-Json : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

I'm not super familiar as to why removing colons would cause this, could you point me into the right direction? Thanks!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier
[fixup!] [feature] Use ValidateRange in New-NestedJson
541524e
@iSazonov

Ilya (iSazonov) commented Feb 9, 2019

Copy link
Copy Markdown
Collaborator

Adam Gauthier (@louistio) Sorry, colons is needed for asHashtable but not for Depth.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier
[fixup!] [feature] Use colon for -AsHashtable
eecc899
@iSazonov

Ilya (iSazonov) commented Feb 10, 2019

Copy link
Copy Markdown
Collaborator

Steve Lee (@SteveL-MSFT) Mark Kraus (@markekraus) Please update your review.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

markekraus
Mark Kraus (markekraus) suggested changes Feb 10, 2019
View reviewed changes

@markekraus Mark Kraus (markekraus) left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor cleanup requested.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertFromJsonCommand.cs Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@markekraus @adamgauthier
[fixup!] [feature] Capitalize JSON in comments and use Parameter()
dc39854
Co-Authored-By: louistio <[email protected]>
markekraus
Mark Kraus (markekraus) approved these changes Feb 11, 2019
View reviewed changes
@iSazonov

Ilya (iSazonov) commented Feb 11, 2019

Copy link
Copy Markdown
Collaborator

Steve Lee (@SteveL-MSFT) Please update your review.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

SteveL-MSFT
Steve Lee (SteveL-MSFT) approved these changes Feb 19, 2019
View reviewed changes
@iSazonov

Ilya (iSazonov) commented Feb 20, 2019

Copy link
Copy Markdown
Collaborator

Adam Gauthier (@louistio) Please update the PR description and we'll merge.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier

Adam Gauthier (adamgauthier) commented Feb 20, 2019

Copy link
Copy Markdown
Contributor Author

Ilya (@iSazonov) description updated, I believe this still requires documentation changes, not sure if that prevents from merging.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov

Ilya (iSazonov) commented Feb 20, 2019

Copy link
Copy Markdown
Collaborator

Adam Gauthier (@louistio) Please open new Issue in PowerShell-Docs repo and add a reference to the PR description.

adamgauthier reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@adamgauthier Adam Gauthier (adamgauthier) mentioned this pull request Feb 20, 2019
Document -Depth parameter for ConvertFrom-Json MicrosoftDocs/PowerShell-Docs#3736
Closed
2 of 8 tasks
@adamgauthier

Adam Gauthier (adamgauthier) commented Feb 20, 2019

Copy link
Copy Markdown
Contributor Author

Ilya (@iSazonov) done!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@iSazonov
Ilya (iSazonov) merged commit caf8ac6 into PowerShell:master Feb 20, 2019
@iSazonov

Ilya (iSazonov) commented Feb 20, 2019

Copy link
Copy Markdown
Collaborator

Adam Gauthier (@louistio) Thanks for great work!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Dec 17, 2025
Add PSJsonSerializerV2 experimental feature for ConvertTo-Json using System.Text.Json #26624
Closed
Add PSJsonSerializerV2 experimental feature for ConvertTo-Json using System.Text.Json #26637
Closed
Thatgfsj (Thatgfsj) pushed a commit to Thatgfsj-contribs/PowerShell that referenced this pull request Aug 6, 2026
@adamgauthier @iSazonov
Add configurable maximum depth in ConvertFrom-Json with -Depth (Pow…
5335c4e
…erShell#8199)

Adds an optional -Depth parameter to the cmdlet which lets the user to specify a maximum depth allowed for deserialization, which will overwrite the default maximum of 1024.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@iSazonov Ilya (iSazonov) iSazonov left review comments
@SteveL-MSFT Steve Lee (SteveL-MSFT) SteveL-MSFT approved these changes
@JamesWTruher James Truher (JamesWTruher) Awaiting requested review from JamesWTruher
@PaulHigin Paul Higinbotham (PaulHigin) Awaiting requested review from PaulHigin
+3 more reviewers
@iRon7 iRon7 iRon7 left review comments
@vexx32 Rain Sallow (/u/ta11ow) (vexx32) vexx32 left review comments
@markekraus Mark Kraus (markekraus) markekraus approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@iSazonov Ilya (iSazonov)

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log Committee-Reviewed PS-Committee has reviewed this and made a decision

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

In ConvertFrom-Json, the max depth for deserialization is 1024, however, we should investigate if the current implementation can handle object of greater depth.

Uh oh!

There was an error while loading. Please reload this page.

9 participants

@adamgauthier @SteveL-MSFT @iSazonov @joeyaiello @rjmholt @markekraus @mklement0 @iRon7 @vexx32
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.