Skip to content

Fix Issue in Select-Object where Hashtable members (e.g., Keys) cannot be used with -Property or -ExpandProperty - #11097

Merged
Dongbo Wang (daxian-dbw) merged 11 commits into
PowerShell:masterfrom
vexx32:SelectObjectCommand-DictionaryProperties
Jun 19, 2020
Merged

Fix Issue in Select-Object where Hashtable members (e.g., Keys) cannot be used with -Property or -ExpandProperty#11097
Dongbo Wang (daxian-dbw) merged 11 commits into
PowerShell:masterfrom
vexx32:SelectObjectCommand-DictionaryProperties

Conversation

@vexx32

@vexx32 Rain Sallow (/u/ta11ow) (vexx32) commented Nov 18, 2019

Copy link
Copy Markdown
Collaborator

PR Summary

Prior to this PR, a hashtable piped into Select-Object -[Expand]Property Keys where the user expected Keys to retrieve the property value from the hashtable rather than the dictionary entry would return no value (in the case of -ExpandProperty, an error would be emitted, stating that the property could not be found).

This PR fixes this issue, and examines hashtable members as well as their key/value entries. The logic is designed such that hashtable key/values are still prioritised over hashtable members, so if a user creates a hashtable such as @{ Keys = "None" } and then selects the Keys property via Select-Object, it will have the same result as using $ht.Keys already does: the returned value will always prioritise an actual key/value entry over the hashtable members.

Note that this means creating a hashtable with a key named Keys will prevent access to the Keys member on the hashtable in this manner. This new behaviour is consistent with existing behaviour with retrieval of hashtable keys, and also consistent with dot-property access behaviour with hashtables -- you can access $ht.Keys up until you add a key with the name Keys, at which point you will always get that key value back.

Tests have been added to cover these cases explicitly.

PR Context

Users should be able to utilise hashtables as actual hashtable objects as well as pseudo-PSObjects where appropriate. It is disingenuous for these commands to pretend hashtables don't have other members which may be desired in some circumstances.

This PR fixes #11094

PR Checklist

@vexx32 Rain Sallow (/u/ta11ow) (vexx32) added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Nov 18, 2019
@vexx32

Rain Sallow (/u/ta11ow) (vexx32) commented Nov 18, 2019

Copy link
Copy Markdown
Collaborator Author

Note for reviewers -- the Select-Object test file hasn't been updated in a long time (still using tabs instead of spaces) so I included a format-only commit 6544c98 to sort that separately. You'll probably want to review that commit individually and then the following one for added tests.

No existing tests were modified in this PR apart from the formatting fixes. I only did a quick tabs-to-spaces and then auto-format commit, so if there are specific style issues you also want to fix while I'm there let me know, we can fix them either here or in a follow up PR as necessary. 🙂

@vexx32

Copy link
Copy Markdown
Collaborator Author

Also, I think the Codacy suggestion to make IfHashtableWrapAsPSCustomObject() a static method can be ignored. 😄

@vexx32

Rain Sallow (/u/ta11ow) (vexx32) commented Nov 18, 2019

Copy link
Copy Markdown
Collaborator Author

Hmm, interesting. Didn't expect to break that, but there you have it.

@vexx32

Copy link
Copy Markdown
Collaborator Author

PoshChan-Bot (@PoshChan) please remind me in 17 hours

@iSazonov Ilya (iSazonov) changed the title Select-Object - 🐛 Fix Issue where Hashtable members (e.g., Keys) cannot be used with -Property or -ExpandProperty Fix Issue in Select-Object where Hashtable members (e.g., Keys) cannot be used with -Property or -ExpandProperty Nov 18, 2019
@iSazonov

Copy link
Copy Markdown
Collaborator

Rain Sallow (/u/ta11ow) (@vexx32) The PR description is more complex than the fix :-)

@PoshChan

Copy link
Copy Markdown
Collaborator

Rain Sallow (/u/ta11ow) (@vexx32), this is the reminder you requested 17 hours ago

@vexx32

Copy link
Copy Markdown
Collaborator Author

That was simpler than I expected! 🎉

@vexx32

Copy link
Copy Markdown
Collaborator Author

PoshChan-Bot (@PoshChan) please retry macos

@PoshChan

Copy link
Copy Markdown
Collaborator

Rain Sallow (/u/ta11ow) (@vexx32), successfully started retry of PowerShell-CI-macOS

@ghost

Copy link
Copy Markdown

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Mainainer, Please provide feedback and/or mark it as Waiting on Author

@ghost ghost added the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Jun 10, 2020
@ghost ghost removed this from the 7.1.0-preview.4 milestone Jun 10, 2020
@ghost ghost removed the Review - Needed The PR is being reviewed label Jun 10, 2020
- Fix an issue where Select-Object and similar could not resolve
member names from hashtables due to them carelessly converting them.

- Allows both hashtable keys/values and actual members to be referenced.
Precedence is given to the hashtable keys first to avoid collisions.
- Add test for Count & Length members
- Use base target object instead of wrapping hashtable
@vexx32
Rain Sallow (/u/ta11ow) (vexx32) force-pushed the SelectObjectCommand-DictionaryProperties branch from 6de53fe to 74e066c Compare June 11, 2020 02:23
@iSazonov

Copy link
Copy Markdown
Collaborator

Rain Sallow (/u/ta11ow) (@vexx32) Please look CI failures.

 - Still had tab stops in some places, replaced everything with spaces.
 - removed some accidentally duplicated code
 - 'Format Document' to ensure consistent indentation.

 Sorry about the diff, this file was a bit of a mess 🙏
@vexx32
Rain Sallow (/u/ta11ow) (vexx32) force-pushed the SelectObjectCommand-DictionaryProperties branch from 8beeb21 to cfea794 Compare June 11, 2020 15:59
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 Outdated
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 Outdated
Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/Select-Object.Tests.ps1 Outdated
@ghost ghost added Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept and removed Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept labels Jun 12, 2020
@daxian-dbw

Copy link
Copy Markdown
Member

Rain Sallow (/u/ta11ow) (@vexx32) The test failure in mac CI is a known issue. Can you please check on the Windows failure?

@vexx32

Copy link
Copy Markdown
Collaborator Author

That's one I haven't seen before. Something to do with remoting? Not sure what to make of it 😅

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Management.Automation.Remoting.PrioritySendDataCollection.ReadOrRegisterCallback(OnDataAvailableCallback callback, DataPriorityType& priorityType) in D:\a\1\s\src\System.Management.Automation\engine\remoting\fanin\PriorityCollection.cs:line 240
   at System.Management.Automation.Remoting.Client.WSManClientCommandTransportManager.SendOneItem() in D:\a\1\s\src\System.Management.Automation\engine\remoting\fanin\WSManTransportManager.cs:line 3975

   at System.Management.Automation.Remoting.Client.WSManClientCommandTransportManager.OnRemoteCmdSendCompleted(IntPtr operationContext, Int32 flags, IntPtr error, IntPtr shellOperationHandle, IntPtr commandOperationHandle, IntPtr operationHandle, IntPtr data) in D:\a\1\s\src\System.Management.Automation\engine\remoting\fanin\WSManTransportManager.cs:line 3681
An error has occurred that was not properly handled. Additional information is shown below. The PowerShell process will exit.
Execution of {& $powershell $PSFlags -c $command} by build.psm1: line 1332 failed with exit code -1073741819
At D:\a\1\s\build.psm1:2191 char:17
+                 throw $errorMessage
+                 ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (Execution of {& $po…it code -1073741819:String) [], RuntimeException
+ FullyQualifiedErrorId : Execution of {& $powershell $PSFlags -c $command} by build.psm1: line 1332 failed with exit code -1073741819
##[error]PowerShell exited with code '1'.

@daxian-dbw

Copy link
Copy Markdown
Member

PoshChan-Bot (@PoshChan) please retry windows

@PoshChan

Copy link
Copy Markdown
Collaborator

Dongbo Wang (@daxian-dbw), did not find any matching pull request checks

@iSazonov Ilya (iSazonov) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Tests contain many style fixes - please move it in separate PR.

{
members = target.Members.Match(
_stringValue,
PSMemberTypes.Properties | PSMemberTypes.PropertySet | PSMemberTypes.Dynamic);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We evaluate this again. Maybe put this in a variable before line 172?

@vexx32 Rain Sallow (/u/ta11ow) (vexx32) Jun 16, 2020

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is evaluated against the wrapped target object in the prior case.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I mean PSMemberTypes.Properties | PSMemberTypes.PropertySet | PSMemberTypes.Dynamic

Comment on lines +18 to +20
$result = $(Select-Object -InputObject $dirObject -Last $TestLength).Length
$expected = $dirObject.Length
{ $dirObject | Select-Object } | Should -Not -Throw

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should -Not -Throw is not good test.
Why do we remove one test below? And why do we need $expected above? Why do we change the tests at all?

@daxian-dbw

Dongbo Wang (daxian-dbw) commented Jun 15, 2020

Copy link
Copy Markdown
Member

Ilya (@iSazonov) It was called out at #11097 (comment) that there is a format-only commit included.
I'm fine to keep that commit in this PR because this test file was seldom touched.

BTW Ilya (@iSazonov), it's easier to review after ignoring the white space characters: https://github.com/PowerShell/PowerShell/pull/11097/files?w=1

@daxian-dbw Dongbo Wang (daxian-dbw) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree with Ilya (@iSazonov), something is wrong in the changes of these couple of tests.

$result = $(Select-Object -InputObject $dirObject -Last $TestLength).Length
$expected = $dirObject.Length

$result | Should -Be $expected

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

$result | Should -Be $expected shouldn't be removed here.

{ $dirObject | select } | Should -Not -Throw
$result = $(Select-Object -InputObject $dirObject -Last $TestLength).Length
$expected = $dirObject.Length
{ $dirObject | Select-Object } | Should -Not -Throw

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You need to keep the It "Should be able to use the alias" { here.

$dirObject[$TestLength].Size | Should -Be ($orig2 + 1)
}

It "Select-Object with Property First Last Overlap should work"{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this test case removed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Weird, not sure, will add it back.

$obj.psobject.TypeNames[0] | Should -BeLike "Selected*"
$obj.psobject.TypeNames[1] | Should -Not -BeLike "Selected*"
$p = Get-Process -Id $pid | Select-Object -Property Process* -ExcludeProperty ProcessorAffinity -ExpandProperty Modules
$p[0].psobject.Properties.Item("ProcessorAffinity") | Should -BeNullOrEmpty

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The new code should be moved after $obj.psobject.TypeNames[2] | Should .. line below.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Looks like this got duplicated from above (L#328-329) somehow. Sorry about that, really not sure what on earth happened here. Will remove.

@ghost ghost added Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept and removed Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept labels Jun 16, 2020
Some of the Select-Object tests got a bit mangled during format.
This commit should restore them all back to proper order.
@vexx32

Copy link
Copy Markdown
Collaborator Author

Apologies about the mangled tests, not sure how that happened. Should be all fixed up now. 💖 😊

@daxian-dbw
Dongbo Wang (daxian-dbw) merged commit 02af121 into PowerShell:master Jun 19, 2020
@vexx32
Rain Sallow (/u/ta11ow) (vexx32) deleted the SelectObjectCommand-DictionaryProperties branch June 20, 2020 00:46
@ghost

Copy link
Copy Markdown

🎉v7.1.0-preview.4 has been released which incorporates this pull request.:tada:

Handy links:

Thatgfsj (Thatgfsj) pushed a commit to Thatgfsj/PowerShell that referenced this pull request Aug 6, 2026
… cannot be used with `-Property` or `-ExpandProperty` (PowerShell#11097)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Select-Object -ExpandProperty does not work with Hashtable members

5 participants