-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Make ConvertFrom-Json deserialize an array of objects with multiple lines. #3823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make ConvertFrom-Json deserialize an array of objects with multiple lines. #3823
Conversation
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.
Should this be a && so we check for existence of [ and ] ? If any of those is missing it is an invalid array anyways.
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.
No, this should be an '||' because we are trying to detect an invalid array. These are some examples:
- '["a"'
- '['
- '"a"]'
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.
Trim will only remove newline characters at the start and end. To remove all newline characters use Replace instead. And .ToCharArray() is unnecessary.
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.
Fixed.
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.
Use a String.Empty instead of "". More efficient as it does not create a new zero length string.
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.
Fixed.
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.
Maybe a && here as well?
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.
Same as the comment above.
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.
Use [Environment]::NewLine instead
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.
Test code updated as per Jim's recommendation below.
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.
Can the variations be converted to use -TestCase for It? So if one of the Should fails the others are still run.
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've implemented two different test cases instead.
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.
this should just be:
$array = [pscustomobject]@{ objectName = "object1Name"; objectValue = "object1Value" },
[pscustomobject]@{ objectName = "object2Name"; objectValue = "object2Value" }
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.
Great suggestion. I will update the test code.
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'm wondering if this (or the above) needs to be done with a file at all. Does the following cover the case?
$result = "[1,","2,","3]" | convertfrom-json
$result.count | Should be 3
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.
Test code updated.
adityapatwardhan
left a comment
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.
LGTM
|
tests are much cleaner now - LGTM |
|
@JamesWTruher can you mark your review as Approved? |
|
@PowerShell/powershell-maintainers : This is ready to be merged, please let me know if you need anything else. Thanks. |
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 comment says contains, but the code says starts with/ends with.
Besides that, it just looks more complicated than it needs to be, e.g. 2 calls to IndexOf, then strip newlines then spaces. Why not just use a regex, like:
if (Regex.Match(input, "(^\s*\[)|(\s*\]$)"))
{
JArray.Parse(input);
}I'd also like to see some sort of note about whether or not this is considered a NewtonSoft bug - ideally a link to an issue so we can track it.
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.
as these markers for
Do you mean these markers are for?
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 comment doesn't match the code. Carriage return is \r, but Environemnt.NewLine is \r\n on windows and \n on Unix. And what if the json string is has \r\n but we are calling ConvertFrom-Json on Unix?
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.
Do we care about other white spaces? For example what if there is \t?
By the way, new lines are white spaces too.
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.
white spaces include new lines.
[char]::IsWhiteSpace([environment]::NewLine, 0)
True
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.
is can be
Typo
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 comments here are confusing to me -- what is the buffer here? Could you please make the comments easier to understand?
|
@Francisco-Gamino One more question -- why do you have to remove all white spaces before calling |
|
Please update the title and description based on the instructions in Contributing - Pull Request Submission
|
|
Chatted with @Francisco-Gamino offline, and it turns out the |
…of strings which represent a JSON content.
…s as a single string.
|
@lzybkr: Thank you Jason for your suggestion. Using regular expressions makes the code much simpler. |
| // To work around this, we need to identify when input is a Json array, and then try to parse it via JArray.Parse(). | ||
|
|
||
| // If input starts with '[' or ends with ']' (ignoring white spaces). | ||
| if ((Regex.Match(input, @"(^\s*\[)|(\s*\]$)")).Success) |
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 reg expression used here seems not right ... @Francisco-Gamino let's discuss it tomorrow.
Addressing issue #3284: ConvertFrom-JSON fails to parse syntactically-correct JSON array
For PowerShell on CoreCLR, we use Json.Net. However, this deserialzer does not throw an exception if an invalid array is passed, so we need to add extra logic to handle this. An invalid array can occurred when the user reads a file via get-content as a collection of PSObjects. E.g.,
Added tests for the following: