Skip to content

Add Get-StringHash and Get-FileHash cmdlets#3024

Merged
lzybkr merged 7 commits intoPowerShell:masterfrom
iSazonov:gethash
Feb 4, 2017
Merged

Add Get-StringHash and Get-FileHash cmdlets#3024
lzybkr merged 7 commits intoPowerShell:masterfrom
iSazonov:gethash

Conversation

@iSazonov
Copy link
Copy Markdown
Collaborator

Close #2731

  1. Rewrite Get-FileHash on C# and refactoring tests
    The original Get-FileHash output type is Microsoft.Powershell.Utility.FileHash. The type was defined by ExtendedTypeDefinition. It is not C# type and reported as PSCustomObject.
    Therefore, the output type was changed and now it is native C# type Microsoft.PowerShell.Commands.FileHashInfo.

  2. Add new cmdlet Get-StringHash and add tests
    The original idea was to add a InputString parameter to the common cmdlet but due to a conflict with the Path parameter (paths is strings too!) I had to make a new cmdlet to provide a pipeline support for the InputString parameter.

@PowerShellTeam PowerShellTeam added the Review - Needed The PR is being reviewed label Jan 20, 2017
Copy link
Copy Markdown
Contributor

@lzybkr lzybkr left a comment

Choose a reason for hiding this comment

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

@PowerShell/powershell-committee - needs to review the new cmdlet - parameters, output type, allowing null.

$hashSHA256forEmptyString = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"

# Keep "sHA1" below! It is for testing that the cmdlet accept a hash algorithm name in any case!
$testcases =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

With the use of a common variable name, this should be moved closer to the use to limit the scope.

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.

Fixed.


Context "Default result tests" {
It "Should default to correct hash (SHA256)" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider removing some of the blank lines just after or just before opening/closing braces.

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.

Fixed.

$result[1] | Should Be $hashSHA256forEmptyString
}

It "Should be able to set the default hash algorithm" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This test is unnecessary - there is no reason to test PSDefaultParameterValues on specific cmdlets, the generic tests for PSDefaultParameterValues are sufficient.

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.

It is from original tests.
Removed.


It "Should not throw for empty or null input string" {
Get-StringHash -InputString "" | Should Be $hashSHA256forEmptyString
Get-StringHash -InputString $null | Should Be $null
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this really desirable? Allowing $null?

Copy link
Copy Markdown
Collaborator Author

@iSazonov iSazonov Jan 24, 2017

Choose a reason for hiding this comment

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

I thought about this example:

$stringarray | Get-StringHash 

If the string array contains a null string member then we throw - is this the desired behavior?
The following example does not cause a exception:

"a",$null | Select-String -Pattern ".*"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$null is not passed through the pipeline and Select-String allows $null anyway, so that's not a good example.

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.

Yes, but key is that null string don't throw an exception here.

@@ -0,0 +1,62 @@
Describe "Get-StringHash" -Tags "CI" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would expect very few changes to this feature once merged, so maybe we don't need the tests in CI.

Copy link
Copy Markdown
Collaborator Author

@iSazonov iSazonov Jan 24, 2017

Choose a reason for hiding this comment

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

We can change it after the merger. (Or just before.)

/// <summary>
/// Create FileHashInfo object and output it
/// </summary>
private void WriteHashResult(String Algorithm, String hash, String path)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use lowercase string.

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.

Fixed.

/// </summary>
/// <value></value>
[Parameter(Position = 1)]
[ValidateSet(HashAlgorithmNames.SHA1,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The PowerShell version supports additional algorithms - why are they not included here?

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.

It is from original cmdlet and HashAlgorithmNames class.
If there are other useful algorithms, please give a link.
And whether we should do something specifically for Mac?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

According to the ValidateSet use here, the original function has:

  • MACTripleDES
  • MD5
  • RIPEMD160
  • SHA1
  • SHA256
  • SHA384
  • SHA512

I suppose it's not surprising that a couple of these are missing for .Net Core.

We should probably add the missing algorithms for Windows PowerShell or explore alternative implementations to that we can have completely portable scripts.

/cc @SteveL-MSFT

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.

@lzybkr if .Net Core doesn't support those, we should treat it as a separate issue (not block this PR). however, we should see if .Net Core will implement them or why they no longer support it (patents? no longer secure?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe these are hashing algorithms, so security isn't the issue. My guess is less demand.

But the real question here - are we OK with a PR that would be a breaking change to Windows PowerShell if we took this code back to Windows as is?

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 security concern is that hashes are used to determine if something (like a file/package) has been modified. However, SHA1, for example, has been proven that you can generate collisions meaning that it is feasible someone could modify a file and produce the same resulting SHA1 hash so it appears to be legit.

We can discuss this at the Committee meeting.

It "Should default to correct hash algorithm" {
$result = Get-FileHash $testDocument
BeforeAll {
New-Variable testDocument -Value (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath assets) -ChildPath testablescript.ps1) -Scope Global -Force
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A test shouldn't normally create a variable in global scope.

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.

Fixed.

}

$result.Algorithm | Should Be "MD5"
It "Should be able to set the default hash algorithm" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This test should not be necessary, PSDefaultParameterValues is already well tested.

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.

Removed.

$result.Algorithm | Should Be "SHA256"
}
# Keep "sHA1" below! It is for testing that the cmdlet accept a hash algorithm name in any case!
$testcases =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should be moved closer to the use to limit the scope of the variable.

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.

Fixed.

@lzybkr lzybkr added the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Jan 23, 2017
@{ algorithm = "SHA384"; hash = "656215B6A07011E625206F43E57873F49AD7B36DFCABB70F6CDCE2303D7A603E55D052774D26F339A6D80A264340CB8C" },
@{ algorithm = "SHA512"; hash = "C688C33027D89ACAC920545471C8053D8F64A54E21D0415F1E03766DDCDA215420E74FAFD1DC399864C6B6B5723A3358BD337339906797A39090B02229BF31FE" },
@{ algorithm = "MD5"; hash = "7B09811D1631C9FD46B39D1D35522F0A" }
New-Variable testDocument -Value (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath assets) -ChildPath testablescript.ps1) -Force
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can't this just use $testDocument = Join-Path ...?

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.

Fixed.

@iSazonov
Copy link
Copy Markdown
Collaborator Author

@PowerShell/powershell-committeeTeam
Should we introduce a new type 'Microsoft.PowerShell.Commands.StringHashInfo' for Get-StringHash output similar to Get-FileHash output?

+ $testDocument' in test
@SteveL-MSFT SteveL-MSFT added the Breaking-Change breaking change that may affect users label Jan 26, 2017
@lzybkr
Copy link
Copy Markdown
Contributor

lzybkr commented Jan 26, 2017

@PowerShell/powershell-committee has decided we need an RFC for the Get-StringHash cmdlet.

The biggest concern was how PowerShell will convert anything to string, so the cmdlet will happily hash objects in a potentially unexpected way.

The output type was also of some concern when combined with allowing null because it will be difficult to match input with output. We think the output needs the original object in addition to the hash.

@lzybkr lzybkr 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 Jan 26, 2017
@lzybkr
Copy link
Copy Markdown
Contributor

lzybkr commented Jan 26, 2017

The committee also agreed that we do not need any updates with regards to the algorithms supported - we've marked the PR wit Breaking Change so we can document the difference between Windows PowerShell and PowerShell Core.

@iSazonov
Copy link
Copy Markdown
Collaborator Author

What will be the road map for the PR?
Could I remove Get-StringHash code from the PR?

I do not have the forces for the RFC to write the big text correctly in English.
Can we ask the author @rkeithhill of the Get-StringHash idea to start this RFC?

@lzybkr
Copy link
Copy Markdown
Contributor

lzybkr commented Jan 26, 2017

By all means - remove Get-StringHash from the PR.

Your English seems more than sufficient to write a RFC, but if @rkeithhill is up for it, I assume he'll jump in.

Removed for future RFC.
@iSazonov
Copy link
Copy Markdown
Collaborator Author

@lzybkr I create new PR with RFC PowerShell/PowerShell-RFC#63

Now Get-StringHash was removed from the PR.
Travis again temporary failed 😕

@iSazonov
Copy link
Copy Markdown
Collaborator Author

@lzybkr Should I do something else in the PR?

@lzybkr lzybkr self-assigned this Feb 4, 2017
@lzybkr lzybkr merged commit 2981806 into PowerShell:master Feb 4, 2017
@iSazonov
Copy link
Copy Markdown
Collaborator Author

iSazonov commented Feb 4, 2017

@lzybkr Thanks!

@iSazonov iSazonov deleted the gethash branch April 17, 2020 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Breaking-Change breaking change that may affect users Committee-Reviewed PS-Committee has reviewed this and made a decision

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants