-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Fix for #6855 - Measure-Object should handle scriptblock properties. #6934
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
Fix for #6855 - Measure-Object should handle scriptblock properties. #6934
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.
If we use pipeline make sense use some values:
$result = "a,b,c", "d,e" | Measure-Object -Word {$_ -split ','}
$result.Words | Should -Be 5There 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 move the function and tests in new Context block?
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.
Moved into a separate Describe.
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.
Please add empty new line.
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.
Added.
|
We should get PowerShell Committee conclusion for new public API. |
|
@iSazonov We reviewed this in the last committee meeting and approved the name. I thought @SteveL-MSFT had updated the bug to reflect this but I don't see it. |
|
@BrucePay Thanks! I am extecting that the PR will marked by the label. |
|
Oops - I had the wrong issue number in the comment so you might have looked at the wrong issue. #6855 is, in fact, marked "Committee Reviewed". |
iSazonov
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 with one minor 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.
Could you please use C# 7 syntax?
if (PSObject.Base(target) as Hashtable targetAsHash) |
@SteveL-MSFT Says we're ignoring CodeFactor issues for now. |
|
@iSazonov FYI - Most of my team has been involved with helping port existing Windows PowerShell modules owned by other teams to work with PSCore6 so you may find us not as active. Hopefully we'll be back to fully engaged by end of June (or mostly engaged). |
|
I'm glad that this process began. I do not see this leading to corrections in PowerShell Core - it convinces me that PowerShell Core is very good! 😄 |
daxian-dbw
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.
/cc @PaulHigin Now that PSPropertyExpression is publically exposed and it has the ability to run scripts, Paul you may want to check if this will introduce any security concerns to the ConstrainedLanguage mode.
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 could be a breaking change when it comes to the ConstrainedLanguage mode.
@{prop = 3} | measure-object Count works in ConstrainedLanguage mode today, but with this change, the conversion from Hashtable to PSCustomObject will throw exception.
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.
Hmm - true - good catch. It's pretty obscure and currently the only useful scenario for piping hashtables into measure-object (other than instance-counting). Still, we should probably get a committee review on this.
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 you please change the name to WrapHashtableAsPSCustomObject? C# method naming conversion suggests using verbs or verb phrases to name methods.
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 point of the rule is that the names of methods should be imperative which this is. There are other examples of (type 1) conditional clauses in .NET such as ThrowIfCancellationRequested on System.Threading.CancellationToken.
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.
OK. #Closed
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.
If we want to handle hashtable specially, shall we expand that to IDictionary? LanguagePrimitives.ConvertPSObjectToType is able to convert IDictionary to PSObject.
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 goal is to match the behaviour of [PSCustomObject] @{a=1; b=2}. Currently casting Dictionary<T,T> to PSCustomObject doesn't result in a custom object so I don't think we should introduce that behaviour here.
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.
Understood. Good to know that we are matching the behavior of [PSCustomObject] @{a=1; b=2}.
daxian-dbw
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.
Waiting on the committee's review.
|
@daxian-dbw @BrucePay Sorry for the late review. To answer Dongbo's question, from a security point of view I think this is Ok. MshExpression (now PSPropertyExpression) takes a ScriptBlock in its constructor which it will invoke. But as long as the passed in ScriptBlock is created in a constrained environment it will be marked accordingly and the script block will be invoked with CL mode constraints. A constructor also takes a string "expression", but as near as I can tell it is never evaluated as script and is used to look up properties. Is this correct? However, we should include a CL mode test to ensure the expression scriptblock is run in CL mode. |
@PaulHigin Yes, that's correct. It's for property lookup. |
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.
@PaulHigin I would like you to take another look at this change. PSPropertyExpression is added to CoreTypes, and that means users can call its methods in ConstrainedLanguage mode. Do you have any concerns about 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.
Thanks, I didn't see that. If this type is going to be white listed then it needs to go through a separate/full security review. I see that some internal methods are now public, and these along with constructors need to be reviewed for vulnerabilities. Please set up a meeting for this.
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 - it's only intended to be a type accelerator. I added it in the wrong place. I'll move it to the TypeAccelerators() method where it should be.
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, I agree it should be moved :)
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.
Thanks, I didn't see that. If this type is going to be white listed then it needs to go through a separate/full security review. I see that some internal methods are now public, and these along with constructors need to be reviewed for vulnerabilities. Please set up a meeting for this.
|
@PowerShell/powershell-committee reviewed this and is fine with this breaking change which is likely only an edge case, but the positive impact for most users is beneficial |
…operties. Fixed by renaming MshExpression to PSPropertyExpression and making it
public. Then in MeasureObjectCommand, lifting it up to the parameter level. Previously the implementation exposed the Property as string and
wrapped it internally as a PSPropertyExpression. Now the parameter type is PSPropertyExpression directly allowing for both wildcard strings
and scriptblocks. PSPropertyExpression now lives in a public namespace where it can be used by cmdlet and script authors to easily add the
same type of functionality to their commands. I also modified PSPropertyExpression to handle hashtables properly as objects so
@{prop = 3} | measure-object prop
and
@{prop = 3} | measure-object {$_.prop}
will work the same. (Previously the example using just the property name would fail.)
Added missing type accelerator test, cleaned up tests.
6ba5c16 to
a7386a9
Compare
|
@PaulHigin New commits have been pushed. Can you please update your review? Thanks |
PaulHigin
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
|
@BrucePay I just noticed that we didn't run feature tests for this PR CI. Can you please push another commit with |
|
@BrucePay I have submitted a dummy commit to trigger the feature test run for this PR. |
Prior to this change, the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` did not specifically address using those cmdlets against **hashtable** input. In PowerShell 6 an improvement (see PowerShell/PowerShell#6934) enabled users to reference the values of **hashtable** keys in these commands without having to specify calculated properties. This change: - Updates the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` in versions 7.0 and above to show how users can group, select, and sort **hashtable** objects by their key values - Updates the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` in Windows PowerShell 5.1 to show how users can group, select, and sort **hashtable** objects with calculated properties - Cleans up Vale linting warnings across those files - Fixes AB#20552 - Resolves MicrosoftDocs#9311
Prior to this change, the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` did not specifically address using those cmdlets against **hashtable** input. In PowerShell 6 an improvement (see PowerShell/PowerShell#6934) enabled users to reference the values of **hashtable** keys in these commands without having to specify calculated properties. This change: - Updates the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` in versions 7.0 and above to show how users can group, select, and sort **hashtable** objects by their key values - Updates the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` in Windows PowerShell 5.1 to show how users can group, select, and sort **hashtable** objects with calculated properties - Cleans up Vale linting warnings across those files - Fixes AB#20552 - Resolves MicrosoftDocs#9311
Prior to this change, the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` did not specifically address using those cmdlets against **hashtable** input. In PowerShell 6 an improvement (see PowerShell/PowerShell#6934) enabled users to reference the values of **hashtable** keys in these commands without having to specify calculated properties. This change: - Updates the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` in versions 7.0 and above to show how users can group, select, and sort **hashtable** objects by their key values - Updates the documentation for `Group-Object`, `Select-Object`, and `Sort-Object` in Windows PowerShell 5.1 to show how users can group, select, and sort **hashtable** objects with calculated properties - Cleans up Vale linting warnings across those files - Fixes AB#20552 - Resolves #9311
PR Summary
Fixed issue #6855 by renaming the class that does all the work from
MshExpressiontoPSPropertyExpression, making the class public and then inMeasureObjectCommand, lifting it up to the parameter level. Previously the implementation exposed the-Propertyasstringthen wrapped it internally as aPSPropertyExpression. Now the parameter type isPSPropertyExpressiondirectly allowing for both wildcard strings and scriptblocks. Note that this is technically a breaking change (the public type of the parameter has changed) but this was reviewed by the committee and approved. (The vast majority of changes in this PR are due to the renaming. The code changes are relatively small.)PSPropertyExpressionnow lives in a public namespace where it can be used by cmdlet and script authors to easily add the same type of functionality to their commands.I also modified
PSPropertyExpressionto treat hashtables as objects so thatand
will work the identically. (Previously the example using just the property name would just fail.)
Breaking Change Summary
This PR brings in a breaking change in an edge case:
It has been reviewed by the committee and agreed to accept this breaking change.
Please see the discussion at #6934 (comment) for more information.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.[feature]if the change is significant or affects feature tests