From 186b3b26e7a2237adac308c525ffe27c1f6aee10 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Thu, 17 Jan 2019 11:45:58 -0500
Subject: [PATCH 01/28] :sparkles: Add better handling for taking mixed-type
pipeline input
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 107 +++++++++++++++---
1 file changed, 91 insertions(+), 16 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 6bb1f37a9cd..e935dd78325 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -23,6 +23,23 @@ public sealed class FormatHex : PSCmdlet
{
private const int BUFFERSIZE = 16;
+ ///
+ /// For cases where a homogenous collection of bytes or other items are directly piped in, we collect all the
+ /// bytes in a List<byte> and then output the formatted result all at once in EndProcessing().
+ ///
+ private List _totalInputBytes;
+
+ ///
+ /// If the input is determined to be heterogenous piped input or each input object turns out to be a complete
+ /// array of items, we output each item as we receive it to avoid squashing output together in strange ways.
+ ///
+ private bool _isHeterogenousPipedInput;
+
+ ///
+ /// Keep track of prior input types to determine if we're given a heterogenous collection.
+ ///
+ private Type _lastInputType;
+
#region Parameters
///
@@ -98,6 +115,26 @@ protected override void ProcessRecord()
}
}
+ ///
+ /// Implements the EndProcessing method for the FormatHex command.
+ ///
+ protected override void EndProcessing()
+ {
+ if (_totalInputBytes != null)
+ {
+ int offset = Math.Min(_totalInputBytes.Count, Offset < (long)int.MaxValue ? (int)Offset : int.MaxValue);
+ int count = Math.Min(_totalInputBytes.Count - offset, Count < (long)int.MaxValue ? (int)Count : int.MaxValue);
+ if (offset != 0 || count != _totalInputBytes.Count)
+ {
+ WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), null, 0);
+ }
+ else
+ {
+ WriteHexadecimal(_totalInputBytes.ToArray(), null, 0);
+ }
+ }
+ }
+
#endregion
#region Paths
@@ -207,10 +244,10 @@ private void ProcessFileContent(string path)
}
}
}
- catch (IOException ioException)
+ catch (IOException fileException)
{
// IOException takes care of FileNotFoundException, DirectoryNotFoundException, and PathTooLongException
- WriteError(new ErrorRecord(ioException, "FormatHexIOError", ErrorCategory.WriteError, path));
+ WriteError(new ErrorRecord(fileException, "FormatHexIOError", ErrorCategory.WriteError, path));
}
catch (ArgumentException argException)
{
@@ -241,6 +278,7 @@ private void ProcessObjectContent(PSObject inputObject)
if (obj is System.IO.FileSystemInfo fsi)
{
+ _isHeterogenousPipedInput = true;
string[] path = { fsi.FullName };
List pathsToProcess = ResolvePaths(path, true);
ProcessPath(pathsToProcess);
@@ -249,28 +287,52 @@ private void ProcessObjectContent(PSObject inputObject)
byte[] inputBytes = ConvertToByteArray(obj);
- if (inputBytes != null)
+ if (_isHeterogenousPipedInput)
{
- int offset = Math.Min(inputBytes.Length, Offset < (long)int.MaxValue ? (int)Offset : int.MaxValue);
- int count = Math.Min(inputBytes.Length - offset, Count < (long)int.MaxValue ? (int)Count : int.MaxValue);
- if (offset != 0 || count != inputBytes.Length)
+ // Output any previously stored bytes as individual units for consistency of output
+ if (_totalInputBytes != null)
+ {
+ foreach (byte b in inputBytes)
+ {
+ WriteHexadecimal(new[] { b }, null, 0);
+ }
+
+ _totalInputBytes = null;
+ }
+
+ if (inputBytes != null)
{
- WriteHexadecimal(inputBytes.AsSpan().Slice(offset, count), null, 0);
+ int offset = Math.Min(inputBytes.Length, Offset < (long)int.MaxValue ? (int)Offset : int.MaxValue);
+ int count = Math.Min(inputBytes.Length - offset, Count < (long)int.MaxValue ? (int)Count : int.MaxValue);
+ if (offset != 0 || count != inputBytes.Length)
+ {
+ WriteHexadecimal(inputBytes.AsSpan().Slice(offset, count), null, 0);
+ }
+ else
+ {
+ WriteHexadecimal(inputBytes, null, 0);
+ }
}
else
{
- WriteHexadecimal(inputBytes, null, 0);
+ string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
+ ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(errorMessage),
+ "FormatHexTypeNotSupported",
+ ErrorCategory.InvalidArgument,
+ obj.GetType());
+ WriteError(errorRecord);
}
}
else
{
- string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
- ErrorRecord errorRecord = new ErrorRecord(
- new ArgumentException(errorMessage),
- "FormatHexTypeNotSupported",
- ErrorCategory.InvalidArgument,
- obj.GetType());
- WriteError(errorRecord);
+ if (_totalInputBytes == null)
+ {
+ _totalInputBytes = new List(inputBytes);
+ }
+ else
+ {
+ _totalInputBytes.AddRange(inputBytes);
+ }
}
}
@@ -284,10 +346,12 @@ private byte[] ConvertToByteArray(object inputObject)
{
if (inputObject is string str)
{
+ _isHeterogenousPipedInput = true;
+ _lastInputType = typeof(string);
return Encoding.GetBytes(str);
}
- var baseType = inputObject.GetType();
+ Type baseType = inputObject.GetType();
byte[] result = null;
int elements = 1;
bool isArray = false;
@@ -295,6 +359,7 @@ private byte[] ConvertToByteArray(object inputObject)
bool isEnum = false;
if (baseType.IsArray)
{
+ _isHeterogenousPipedInput = true;
baseType = baseType.GetElementType();
dynamic dynamicObject = inputObject;
elements = (int)dynamicObject.Length;
@@ -309,6 +374,16 @@ private byte[] ConvertToByteArray(object inputObject)
if (baseType.IsPrimitive && elements > 0)
{
+ if (!_isHeterogenousPipedInput)
+ {
+ if (_lastInputType != null && baseType != _lastInputType)
+ {
+ _isHeterogenousPipedInput = true;
+ }
+
+ _lastInputType = baseType;
+ }
+
if (baseType == typeof(bool))
{
isBool = true;
From caa70c607ed8d42d5cc8993e18c7a01d82129288 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Thu, 17 Jan 2019 11:55:58 -0500
Subject: [PATCH 02/28] :wrench: Use same error for both input modes
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index e935dd78325..b1a58c78293 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -325,13 +325,25 @@ private void ProcessObjectContent(PSObject inputObject)
}
else
{
- if (_totalInputBytes == null)
+ if (inputBytes != null)
{
- _totalInputBytes = new List(inputBytes);
+ if (_totalInputBytes == null)
+ {
+ _totalInputBytes = new List(inputBytes);
+ }
+ else
+ {
+ _totalInputBytes.AddRange(inputBytes);
+ }
}
else
{
- _totalInputBytes.AddRange(inputBytes);
+ string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
+ ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(errorMessage),
+ "FormatHexTypeNotSupported",
+ ErrorCategory.InvalidArgument,
+ obj.GetType());
+ WriteError(errorRecord);
}
}
}
From 6e74e267e39e010e85cf4f65ef090b12de59dc46 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Thu, 17 Jan 2019 11:56:33 -0500
Subject: [PATCH 03/28] :white_check_mark: Add tests for new behaviours
---
.../Format-Hex.Tests.ps1 | 407 +++++++++---------
1 file changed, 196 insertions(+), 211 deletions(-)
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
index baba808a436..549bcdc4aa7 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
@@ -6,10 +6,8 @@
<#
Purpose:
Verify Format-Hex displays the Hexadecimal value for the input data.
-
Action:
Run Format-Hex.
-
Expected Result:
Hexadecimal equivalent of the input data is displayed.
#>
@@ -34,8 +32,7 @@ Describe "FormatHex" -tags "CI" {
$thumbprint = $null
$certProviderAvailable = $false
- if ($certificateProvider.Count -gt 0)
- {
+ if ($certificateProvider.Count -gt 0) {
$thumbprint = $certificateProvider[0].Thumbprint
$certProviderAvailable = $true
}
@@ -44,100 +41,90 @@ Describe "FormatHex" -tags "CI" {
}
Context "InputObject Paramater" {
+ BeforeAll {
+ enum TestEnum {
+ TestOne = 1; TestTwo = 2; TestThree = 3; TestFour = 4
+ }
+ Add-Type -TypeDefinition @'
+public enum TestSByteEnum : sbyte {
+ One = -1,
+ Two = -2,
+ Three = -3,
+ Four = -4
+}
+'@
+ }
+
$testCases = @(
@{
- Name = "Can process byte type 'fhx -InputObject [byte]5'"
- InputObject = [byte]5
- Count = 1
+ Name = "Can process byte type 'fhx -InputObject [byte]5'"
+ InputObject = [byte]5
+ Count = 1
ExpectedResult = "00000000 05"
}
@{
- Name = "Can process byte[] type 'fhx -InputObject [byte[]](1,2,3,4,5)'"
- InputObject = [byte[]](1,2,3,4,5)
- Count = 1
+ Name = "Can process byte[] type 'fhx -InputObject [byte[]](1,2,3,4,5)'"
+ InputObject = [byte[]](1, 2, 3, 4, 5)
+ Count = 1
ExpectedResult = "00000000 01 02 03 04 05 ....."
}
@{
- Name = "Can process int type 'fhx -InputObject 7'"
- InputObject = 7
- Count = 1
+ Name = "Can process int type 'fhx -InputObject 7'"
+ InputObject = 7
+ Count = 1
ExpectedResult = "00000000 07 00 00 00 ...."
}
@{
- Name = "Can process int[] type 'fhx -InputObject [int[]](5,6,7,8)'"
- InputObject = [int[]](5,6,7,8)
- Count = 1
+ Name = "Can process int[] type 'fhx -InputObject [int[]](5,6,7,8)'"
+ InputObject = [int[]](5, 6, 7, 8)
+ Count = 1
ExpectedResult = "00000000 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 ................"
}
@{
- Name = "Can process int32 type 'fhx -InputObject [int32]2032'"
- InputObject = [int32]2032
- Count = 1
+ Name = "Can process int32 type 'fhx -InputObject [int32]2032'"
+ InputObject = [int32]2032
+ Count = 1
ExpectedResult = "00000000 F0 07 00 00 ð..."
}
@{
- Name = "Can process int32[] type 'fhx -InputObject [int32[]](2032, 2033, 2034)'"
- InputObject = [int32[]](2032, 2033, 2034)
- Count = 1
+ Name = "Can process int32[] type 'fhx -InputObject [int32[]](2032, 2033, 2034)'"
+ InputObject = [int32[]](2032, 2033, 2034)
+ Count = 1
ExpectedResult = "00000000000000000000 F0 07 00 00 F1 07 00 00 F2 07 00 00 ð...ñ...ò..."
}
@{
- Name = "Can process Int64 type 'fhx -InputObject [Int64]9223372036854775807'"
- InputObject = [Int64]9223372036854775807
- Count = 1
+ Name = "Can process Int64 type 'fhx -InputObject [Int64]9223372036854775807'"
+ InputObject = [Int64]9223372036854775807
+ Count = 1
ExpectedResult = "00000000000000000000 FF FF FF FF FF FF FF 7F ......."
}
@{
- Name = "Can process Int64[] type 'fhx -InputObject [Int64[]](9223372036852,9223372036853)'"
- InputObject = [Int64[]](9223372036852,9223372036853)
- Count = 1
+ Name = "Can process Int64[] type 'fhx -InputObject [Int64[]](9223372036852,9223372036853)'"
+ InputObject = [Int64[]](9223372036852, 9223372036853)
+ Count = 1
ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
}
@{
- Name = "Can process string type 'fhx -InputObject hello world'"
- InputObject = "hello world"
- Count = 1
+ Name = "Can process string type 'fhx -InputObject hello world'"
+ InputObject = "hello world"
+ Count = 1
ExpectedResult = "00000000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
}
@{
- Name = "Can process enum type 'fhx -InputObject ([DisplayHintType]::DateTime)'"
- InputObject = [Microsoft.PowerShell.Commands.DisplayHintType]::DateTime
- Count = 1
- ExpectedResult = "00000000000000000000 02 00 00 00 ...."
- }
- @{
- Name = "Can process DisplayHintType[] type 'fhx -InputObject ([DisplayHintType[]](DateTime, Time))'"
- InputObject = [Microsoft.PowerShell.Commands.DisplayHintType[]]([Microsoft.PowerShell.Commands.DisplayHintType]::DateTime)
- Count = 1
- ExpectedResult = "00000000000000000000 02 00 00 00 ...."
- }
- @{
- Name = "Can process DisplayHintType[] type 'fhx -InputObject ([DisplayHintType[]](DateTime, Time))'"
- InputObject = [Microsoft.PowerShell.Commands.DisplayHintType[]]([Microsoft.PowerShell.Commands.DisplayHintType]::DateTime, [Microsoft.PowerShell.Commands.DisplayHintType]::Time)
- Count = 1
- ExpectedResult = "00000000000000000000 02 00 00 00 01 00 00 00 ........"
+ Name = "Can process PS-native enum array '[TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour') | fhx'"
+ InputObject = [TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour')
+ Count = 1
+ ExpectedResult = "00000000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................"
}
@{
- Name = "Can process char type 'fhx -InputObject ([char]`'A`')'"
- InputObject = [char]'A'
- Count = 1
- ExpectedResult = "00000000000000000000 41 A"
- }
- @{
- Name = "Can process char[] type 'fhx -InputObject ([char[]](`'A`'))'"
- InputObject = [char[]]('A')
- Count = 1
- ExpectedResult = "00000000000000000000 41 A"
- }
- @{
- Name = "Can process char[] type 'fhx -InputObject ([char[]](`'A`', 'B'))'"
- InputObject = [char[]]('A', 'B')
- Count = 1
- ExpectedResult = "00000000000000000000 41 42 AB"
+ Name = "Can process C#-native sbyte enum array '[TestSByteEnum[]]('One', 'Two', 'Three', 'Four') | fhx'"
+ InputObject = [TestSByteEnum[]]('One', 'Two', 'Three', 'Four')
+ Count = 1
+ ExpectedResult = "00000000000000000000 FF FE FD FC .þýü"
}
)
- It "" -TestCase $testCases{
+ It "" -TestCase $testCases {
param ($Name, $InputObject, $Count, $ExpectedResult)
@@ -150,102 +137,93 @@ Describe "FormatHex" -tags "CI" {
}
Context "InputObject From Pipeline" {
+ BeforeAll {
+ enum TestEnum {
+ TestOne = 1; TestTwo = 2; TestThree = 3; TestFour = 4
+ }
+ Add-Type -TypeDefinition @'
+public enum TestSByteEnum : sbyte {
+ One = -1,
+ Two = -2,
+ Three = -3,
+ Four = -4
+}
+'@
+ }
+
$testCases = @(
@{
- Name = "Can process byte type '[byte]5 | fhx'"
- InputObject = [byte]5
- Count = 1
+ Name = "Can process byte type '[byte]5 | fhx'"
+ InputObject = [byte]5
+ Count = 1
ExpectedResult = "00000000000000000000 05"
}
@{
- Name = "Can process byte[] type '[byte[]](1,2) | fhx'"
- InputObject = [byte[]](1,2)
- Count = 2
- ExpectedResult = "00000000000000000000 01 ."
- ExpectedSecondResult = "00000000000000000000 02 ."
+ Name = "Can process byte[] type '[byte[]](1,2) | fhx'"
+ InputObject = [byte[]](1, 2)
+ Count = 1
+ ExpectedResult = "00000000000000000000 01 02 .."
}
@{
- Name = "Can process int type '7 | fhx'"
- InputObject = 7
- Count = 1
+ Name = "Can process int type '7 | fhx'"
+ InputObject = 7
+ Count = 1
ExpectedResult = "00000000000000000000 07 00 00 00 ...."
}
@{
- Name = "Can process int[] type '[int[]](5,6) | fhx'"
- InputObject = [int[]](5,6)
- Count = 2
- ExpectedResult = "00000000000000000000 05 00 00 00 ...."
- ExpectedSecondResult = "00000000000000000000 06 00 00 00 ...."
+ Name = "Can process int[] type '[int[]](5,6) | fhx'"
+ InputObject = [int[]](5, 6)
+ Count = 1
+ ExpectedResult = "00000000000000000000 05 00 00 00 06 00 00 00 ........"
}
@{
- Name = "Can process int32 type '[int32]2032 | fhx'"
- InputObject = [int32]2032
- Count = 1
+ Name = "Can process int32 type '[int32]2032 | fhx'"
+ InputObject = [int32]2032
+ Count = 1
ExpectedResult = "00000000000000000000 F0 07 00 00 ð..."
}
@{
- Name = "Can process int32[] type '[int32[]](2032, 2033) | fhx'"
- InputObject = [int32[]](2032, 2033)
- Count = 2
- ExpectedResult = "00000000000000000000 F0 07 00 00 ð..."
- ExpectedSecondResult = "00000000000000000000 F1 07 00 00 ñ..."
+ Name = "Can process int32[] type '[int32[]](2032, 2033) | fhx'"
+ InputObject = [int32[]](2032, 2033)
+ Count = 1
+ ExpectedResult = "00000000000000000000 F0 07 00 00 F1 07 00 00 ð...ñ..."
}
@{
- Name = "Can process Int64 type '[Int64]9223372036854775807 | fhx'"
- InputObject = [Int64]9223372036854775807
- Count = 1
+ Name = "Can process Int64 type '[Int64]9223372036854775807 | fhx'"
+ InputObject = [Int64]9223372036854775807
+ Count = 1
ExpectedResult = "00000000000000000000 FF FF FF FF FF FF FF 7F ......."
}
@{
- Name = "Can process Int64[] type '[Int64[]](9223372036852,9223372036853) | fhx'"
- InputObject = [Int64[]](9223372036852,9223372036853)
- Count = 2
- ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 ôZÐ{c..."
- ExpectedSecondResult = "00000000000000000000 F5 5A D0 7B 63 08 00 00 õZÐ{c..."
+ Name = "Can process Int64[] type '[Int64[]](9223372036852,9223372036853) | fhx'"
+ InputObject = [Int64[]](9223372036852, 9223372036853)
+ Count = 1
+ ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
}
@{
- Name = "Can process string type 'hello world | fhx'"
- InputObject = "hello world"
- Count = 1
+ Name = "Can process string type 'hello world | fhx'"
+ InputObject = "hello world"
+ Count = 1
ExpectedResult = "00000000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
}
@{
- Name = "Can process enum type '[DisplayHintType]::DateTime | fhx"
- InputObject = [Microsoft.PowerShell.Commands.DisplayHintType]::DateTime
- Count = 1
- ExpectedResult = "00000000000000000000 02 00 00 00 ...."
- }
- @{
- Name = "Can process DisplayHintType[] type '[DisplayHintType[]](DateTime) | fhx'"
- InputObject = [Microsoft.PowerShell.Commands.DisplayHintType[]]([Microsoft.PowerShell.Commands.DisplayHintType]::DateTime)
- Count = 1
- ExpectedResult = "00000000000000000000 02 00 00 00 ...."
- }
- @{
- Name = "Can process DisplayHintType[] type '[DisplayHintType[]](DateTime, Time) | fhx'"
- InputObject = [Microsoft.PowerShell.Commands.DisplayHintType[]]([Microsoft.PowerShell.Commands.DisplayHintType]::DateTime, [Microsoft.PowerShell.Commands.DisplayHintType]::Time)
- Count = 2
- ExpectedResult = "00000000000000000000 02 00 00 00 ...."
- ExpectedSecondResult = "00000000000000000000 01 00 00 00 ...."
+ Name = "Can process jagged array type '[sbyte[]](-15, 18, 21, -5), [byte[]](1, 2, 3, 4, 5, 6) | fhx'"
+ InputObject = [sbyte[]](-15, 18, 21, -5), [byte[]](1, 2, 3, 4, 5, 6)
+ Count = 2
+ ExpectedResult = "00000000000000000000 F1 12 15 FB ñ..û"
+ ExpectedSecondResult = "00000000000000000000 01 02 03 04 05 06 ......"
}
@{
- Name = "Can process char type '[char]`'A`' | fhx'"
- InputObject = [char]'A'
- Count = 1
- ExpectedResult = "00000000000000000000 41 A"
+ Name = "Can process PS-native enum array '[TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour') | fhx'"
+ InputObject = [TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour')
+ Count = 1
+ ExpectedResult = "00000000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................"
}
@{
- Name = "Can process char[] type '[char[]](`'A`') | fhx'"
- InputObject = [char[]]('A')
- Count = 1
- ExpectedResult = "00000000000000000000 41 A"
- }
- @{
- Name = "Can process char[] type '[char[]](`'A`', 'B') | fhx'"
- InputObject = [char[]]('A', 'B')
- Count = 2
- ExpectedResult = "00000000000000000000 41 A"
- ExpectedSecondResult = "00000000000000000000 42 B"
+ Name = "Can process C#-native sbyte enum array '[TestSByteEnum[]]('One', 'Two', 'Three', 'Four') | fhx'"
+ InputObject = [TestSByteEnum[]]('One', 'Two', 'Three', 'Four')
+ Count = 1
+ ExpectedResult = "00000000000000000000 FF FE FD FC .þýü"
}
)
@@ -255,12 +233,11 @@ Describe "FormatHex" -tags "CI" {
$result = $InputObject | Format-Hex
- $result.count | Should -Be $Count
+ $result.Count | Should -Be $Count
$result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
$result[0].ToString() | Should -MatchExactly $ExpectedResult
- if ($result.count -gt 1)
- {
+ if ($result.count -gt 1) {
$result[1].ToString() | Should -MatchExactly $ExpectedSecondResult
}
}
@@ -272,39 +249,39 @@ Describe "FormatHex" -tags "CI" {
$testCases = @(
@{
- Name = "Can process file content from given file path 'fhx -Path `$inputFile1'"
- PathCase = $true
- Path = $inputFile1
- Count = 1
+ Name = "Can process file content from given file path 'fhx -Path `$inputFile1'"
+ PathCase = $true
+ Path = $inputFile1
+ Count = 1
ExpectedResult = $inputText1
}
@{
- Name = "Can process file content from all files in array of file paths 'fhx -Path `$inputFile1, `$inputFile2'"
- PathCase = $true
- Path = @($inputFile1, $inputFile2)
- Count = 2
- ExpectedResult = $inputText1
+ Name = "Can process file content from all files in array of file paths 'fhx -Path `$inputFile1, `$inputFile2'"
+ PathCase = $true
+ Path = @($inputFile1, $inputFile2)
+ Count = 2
+ ExpectedResult = $inputText1
ExpectedSecondResult = $inputText2
}
@{
- Name = "Can process file content from all files when resolved to multiple paths 'fhx -Path '`$testDirectory\SourceFile-*''"
- PathCase = $true
- Path = "$testDirectory\SourceFile-*"
- Count = 2
- ExpectedResult = $inputText1
+ Name = "Can process file content from all files when resolved to multiple paths 'fhx -Path '`$testDirectory\SourceFile-*''"
+ PathCase = $true
+ Path = "$testDirectory\SourceFile-*"
+ Count = 2
+ ExpectedResult = $inputText1
ExpectedSecondResult = $inputText2
}
@{
- Name = "Can process file content from given file path 'fhx -LiteralPath `$inputFile3'"
- Path = $inputFile3
- Count = 1
+ Name = "Can process file content from given file path 'fhx -LiteralPath `$inputFile3'"
+ Path = $inputFile3
+ Count = 1
ExpectedResult = $inputText3
}
@{
- Name = "Can process file content from all files in array of file paths 'fhx -LiteralPath `$inputFile1, `$inputFile3'"
- Path = @($inputFile1, $inputFile3)
- Count = 2
- ExpectedResult = $inputText1
+ Name = "Can process file content from all files in array of file paths 'fhx -LiteralPath `$inputFile1, `$inputFile3'"
+ Path = @($inputFile1, $inputFile3)
+ Count = 2
+ ExpectedResult = $inputText1
ExpectedSecondResult = $inputText3
}
)
@@ -313,61 +290,73 @@ Describe "FormatHex" -tags "CI" {
param ($Name, $PathCase, $Path, $ExpectedResult, $ExpectedSecondResult)
- if ($PathCase)
- {
- $result = Format-Hex -Path $Path
- }
- else # LiteralPath
- {
+ if ($PathCase) {
+ $result = Format-Hex -Path $Path
+ } else {
+ # LiteralPath
$result = Format-Hex -LiteralPath $Path
}
$result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
$result[0].ToString() | Should -MatchExactly $ExpectedResult
- if ($result.count -gt 1)
- {
+ if ($result.count -gt 1) {
$result[1].ToString() | Should -MatchExactly $ExpectedSecondResult
}
}
+
+ It 'properly accepts -LiteralPath input from a FileInfo object' {
+ $FilePath = 'TestDrive:\FHX-LitPathTest.txt'
+ "Hello World!" | Set-Content -Path $FilePath
+ $FileObject = Get-Item -Path $FilePath
+
+ $result = $FileObject | Format-Hex
+ if ($IsWindows) {
+ $ExpectedResult = "00000000000000000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0D 0A Hello World!.."
+ } else {
+ $ExpectedResult = "00000000000000000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A Hello World!."
+ }
+
+ $result[0].ToString() | Should -MatchExactly $ExpectedResult
+ }
}
Context "Encoding Parameter" {
$testCases = @(
@{
- Name = "Can process ASCII encoding 'fhx -InputObject 'hello' -Encoding ASCII'"
- Encoding = "ASCII"
- Count = 1
+ Name = "Can process ASCII encoding 'fhx -InputObject 'hello' -Encoding ASCII'"
+ Encoding = "ASCII"
+ Count = 1
ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
}
@{
- Name = "Can process BigEndianUnicode encoding 'fhx -InputObject 'hello' -Encoding BigEndianUnicode'"
- Encoding = "BigEndianUnicode"
- Count = 1
+ Name = "Can process BigEndianUnicode encoding 'fhx -InputObject 'hello' -Encoding BigEndianUnicode'"
+ Encoding = "BigEndianUnicode"
+ Count = 1
ExpectedResult = "00000000000000000000 00 68 00 65 00 6C 00 6C 00 6F .h.e.l.l.o"
}
@{
- Name = "Can process Unicode encoding 'fhx -InputObject 'hello' -Encoding Unicode'"
- Encoding = "Unicode"
- Count = 1
+ Name = "Can process Unicode encoding 'fhx -InputObject 'hello' -Encoding Unicode'"
+ Encoding = "Unicode"
+ Count = 1
ExpectedResult = "00000000000000000000 68 00 65 00 6C 00 6C 00 6F 00 h.e.l.l.o."
}
@{
- Name = "Can process UTF7 encoding 'fhx -InputObject 'hello' -Encoding UTF7'"
- Encoding = "UTF7"
- Count = 1
+ Name = "Can process UTF7 encoding 'fhx -InputObject 'hello' -Encoding UTF7'"
+ Encoding = "UTF7"
+ Count = 1
ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
}
- @{
- Name = "Can process UTF8 encoding 'fhx -InputObject 'hello' -Encoding UTF8'"
- Encoding = "UTF8"
- Count = 1
+ @{
+ Name = "Can process UTF8 encoding 'fhx -InputObject 'hello' -Encoding UTF8'"
+ Encoding = "UTF8"
+ Count = 1
ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
}
- @{
- Name = "Can process UTF32 encoding 'fhx -InputObject 'hello' -Encoding UTF32'"
- Encoding = "UTF32"
- Count = 1
+ @{
+ Name = "Can process UTF32 encoding 'fhx -InputObject 'hello' -Encoding UTF32'"
+ Encoding = "UTF32"
+ Count = 1
ExpectedResult = "00000000000000000000 68 00 00 00 65 00 00 00 6C 00 00 00 6C 00 00 00 h...e...l...l...$($newline)00000000000000000010 6F 00 00 00 o..."
}
)
@@ -390,16 +379,16 @@ Describe "FormatHex" -tags "CI" {
$testCases = @(
@{
- Name = "Does not support non-FileSystem Provider paths 'fhx -Path 'Cert:\CurrentUser\My\`$thumbprint' -ErrorAction Stop'"
- PathParameterErrorCase = $true
- Path = "Cert:\CurrentUser\My\$thumbprint"
+ Name = "Does not support non-FileSystem Provider paths 'fhx -Path 'Cert:\CurrentUser\My\`$thumbprint' -ErrorAction Stop'"
+ PathParameterErrorCase = $true
+ Path = "Cert:\CurrentUser\My\$thumbprint"
ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
}
@{
- Name = "Type Not Supported 'fhx -InputObject @{'hash' = 'table'} -ErrorAction Stop'"
- InputObjectErrorCase = $true
- Path = $inputFile1
- InputObject = @{ "hash" = "table" }
+ Name = "Type Not Supported 'fhx -InputObject @{'hash' = 'table'} -ErrorAction Stop'"
+ InputObjectErrorCase = $true
+ Path = $inputFile1
+ InputObject = @{ "hash" = "table" }
ExpectedFullyQualifiedErrorId = "FormatHexTypeNotSupported,Microsoft.PowerShell.Commands.FormatHex"
}
)
@@ -409,12 +398,10 @@ Describe "FormatHex" -tags "CI" {
param ($Name, $PathParameterErrorCase, $Path, $InputObject, $InputObjectErrorCase, $ExpectedFullyQualifiedErrorId)
{
- if ($PathParameterErrorCase)
- {
+ if ($PathParameterErrorCase) {
$result = Format-Hex -Path $Path -ErrorAction Stop
}
- if ($InputObjectErrorCase)
- {
+ if ($InputObjectErrorCase) {
$result = Format-Hex -InputObject $InputObject -ErrorAction Stop
}
} | Should -Throw -ErrorId $ExpectedFullyQualifiedErrorId
@@ -425,20 +412,20 @@ Describe "FormatHex" -tags "CI" {
$testCases = @(
@{
- Name = "If given invalid path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- PathCase = $true
- InvalidPath = "$($inputFile1.DirectoryName)\fakefile8888845345345348709.txt"
+ Name = "If given invalid path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ PathCase = $true
+ InvalidPath = "$($inputFile1.DirectoryName)\fakefile8888845345345348709.txt"
ExpectedFullyQualifiedErrorId = "FileNotFound,Microsoft.PowerShell.Commands.FormatHex"
}
@{
- Name = "If given a non FileSystem path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- PathCase = $true
- InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
+ Name = "If given a non FileSystem path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ PathCase = $true
+ InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
}
@{
- Name = "If given a non FileSystem path in array (with LiteralPath), continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
+ Name = "If given a non FileSystem path in array (with LiteralPath), continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
}
)
@@ -450,12 +437,10 @@ Describe "FormatHex" -tags "CI" {
$output = $null
$errorThrown = $null
- if ($PathCase)
- {
+ if ($PathCase) {
$output = Format-Hex -Path $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
- }
- else # LiteralPath
- {
+ } else {
+ # LiteralPath
$output = Format-Hex -LiteralPath $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
}
@@ -470,10 +455,10 @@ Describe "FormatHex" -tags "CI" {
It "Path is default Parameter Set 'fhx `$inputFile1'" {
- $result = Format-Hex $inputFile1
+ $result = Format-Hex $inputFile1
$result | Should -Not -BeNullOrEmpty
- ,$result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
$actualResult = $result.ToString()
$actualResult | Should -MatchExactly $inputText1
}
@@ -483,7 +468,7 @@ Describe "FormatHex" -tags "CI" {
$result = Get-ChildItem $inputFile1 | Format-Hex
$result | Should -Not -BeNullOrEmpty
- ,$result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
$actualResult = $result.ToString()
$actualResult | Should -MatchExactly $inputText1
}
@@ -493,7 +478,7 @@ Describe "FormatHex" -tags "CI" {
$result = "a" * 30 | Format-Hex
$result | Should -Not -BeNullOrEmpty
- ,$result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
$result.ToString() | Should -MatchExactly "00000000000000000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa$($newline)00000000000000000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
}
From 09da3d1c7d7b5d5fb02375bb2a5345edc235353a Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Thu, 17 Jan 2019 14:32:05 -0500
Subject: [PATCH 04/28] :recycle: Tidy ErrorRecord instantiations to CodeFactor
standards
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index b1a58c78293..76d70cde4c5 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -316,10 +316,11 @@ private void ProcessObjectContent(PSObject inputObject)
else
{
string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
- ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(errorMessage),
- "FormatHexTypeNotSupported",
- ErrorCategory.InvalidArgument,
- obj.GetType());
+ ErrorRecord errorRecord = new ErrorRecord(
+ new ArgumentException(errorMessage),
+ "FormatHexTypeNotSupported",
+ ErrorCategory.InvalidArgument,
+ obj.GetType());
WriteError(errorRecord);
}
}
@@ -339,10 +340,11 @@ private void ProcessObjectContent(PSObject inputObject)
else
{
string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
- ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(errorMessage),
- "FormatHexTypeNotSupported",
- ErrorCategory.InvalidArgument,
- obj.GetType());
+ ErrorRecord errorRecord = new ErrorRecord(
+ new ArgumentException(errorMessage),
+ "FormatHexTypeNotSupported",
+ ErrorCategory.InvalidArgument,
+ obj.GetType());
WriteError(errorRecord);
}
}
From eeac89c0ed00df51e585cdf2e6379a9cf65ba608 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Sun, 23 Jun 2019 08:22:48 -0400
Subject: [PATCH 05/28] :white_check_mark: Address James' comment
---
.../Format-Hex.Tests.ps1 | 242 +++++++++---------
1 file changed, 123 insertions(+), 119 deletions(-)
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
index 549bcdc4aa7..912d2910f2c 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
@@ -23,10 +23,10 @@ Describe "FormatHex" -tags "CI" {
$inputText2 = 'More text'
$inputText3 = 'Literal path'
$inputText4 = 'Now is the winter of our discontent'
- $inputFile1 = setup -f "FormatHexDataDir/SourceFile-1.txt" -content $inputText1 -pass
- $inputFile2 = setup -f "FormatHexDataDir/SourceFile-2.txt" -content $inputText2 -pass
- $inputFile3 = setup -f "FormatHexDataDir/SourceFile literal [3].txt" -content $inputText3 -pass
- $inputFile4 = setup -f "FormatHexDataDir/SourceFile-4.txt" -content $inputText4 -pass
+ $inputFile1 = Setup -f "FormatHexDataDir/SourceFile-1.txt" -content $inputText1 -pass
+ $inputFile2 = Setup -f "FormatHexDataDir/SourceFile-2.txt" -content $inputText2 -pass
+ $inputFile3 = Setup -f "FormatHexDataDir/SourceFile literal [3].txt" -content $inputText3 -pass
+ $inputFile4 = Setup -f "FormatHexDataDir/SourceFile-4.txt" -content $inputText4 -pass
$certificateProvider = Get-ChildItem Cert:\CurrentUser\My\ -ErrorAction SilentlyContinue
$thumbprint = $null
@@ -292,7 +292,8 @@ public enum TestSByteEnum : sbyte {
if ($PathCase) {
$result = Format-Hex -Path $Path
- } else {
+ }
+ else {
# LiteralPath
$result = Format-Hex -LiteralPath $Path
}
@@ -312,12 +313,14 @@ public enum TestSByteEnum : sbyte {
$result = $FileObject | Format-Hex
if ($IsWindows) {
- $ExpectedResult = "00000000000000000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0D 0A Hello World!.."
- } else {
- $ExpectedResult = "00000000000000000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 0A Hello World!."
+ $Result.Bytes[-1] | Should -Be 0x0A
+ $Result.Bytes[-2] | Should -Be 0x0D
+ $Result.Bytes.Length | Should -Be 14
+ }
+ else {
+ $Result.Bytes[-1] | Should -Be 0x0A
+ $Result.Bytes.Length | Should -Be 13
}
-
- $result[0].ToString() | Should -MatchExactly $ExpectedResult
}
}
@@ -405,154 +408,155 @@ public enum TestSByteEnum : sbyte {
$result = Format-Hex -InputObject $InputObject -ErrorAction Stop
}
} | Should -Throw -ErrorId $ExpectedFullyQualifiedErrorId
- }
}
+}
- Context "Continues to Process Valid Paths" {
+Context "Continues to Process Valid Paths" {
- $testCases = @(
- @{
- Name = "If given invalid path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- PathCase = $true
- InvalidPath = "$($inputFile1.DirectoryName)\fakefile8888845345345348709.txt"
- ExpectedFullyQualifiedErrorId = "FileNotFound,Microsoft.PowerShell.Commands.FormatHex"
- }
- @{
- Name = "If given a non FileSystem path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- PathCase = $true
- InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
- ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
- }
- @{
- Name = "If given a non FileSystem path in array (with LiteralPath), continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
- ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
- }
- )
+ $testCases = @(
+ @{
+ Name = "If given invalid path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ PathCase = $true
+ InvalidPath = "$($inputFile1.DirectoryName)\fakefile8888845345345348709.txt"
+ ExpectedFullyQualifiedErrorId = "FileNotFound,Microsoft.PowerShell.Commands.FormatHex"
+ }
+ @{
+ Name = "If given a non FileSystem path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ PathCase = $true
+ InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
+ ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
+ }
+ @{
+ Name = "If given a non FileSystem path in array (with LiteralPath), continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
+ ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
+ }
+ )
- It "" -Skip:$skipTest -TestCase $testCases {
+ It "" -Skip:$skipTest -TestCase $testCases {
- param ($Name, $PathCase, $InvalidPath, $ExpectedFullyQualifiedErrorId)
+ param ($Name, $PathCase, $InvalidPath, $ExpectedFullyQualifiedErrorId)
- $output = $null
- $errorThrown = $null
+ $output = $null
+ $errorThrown = $null
- if ($PathCase) {
- $output = Format-Hex -Path $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
- } else {
- # LiteralPath
- $output = Format-Hex -LiteralPath $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
- }
+ if ($PathCase) {
+ $output = Format-Hex -Path $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
+ }
+ else {
+ # LiteralPath
+ $output = Format-Hex -LiteralPath $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
+ }
- $errorThrown.FullyQualifiedErrorId | Should -MatchExactly $ExpectedFullyQualifiedErrorId
+ $errorThrown.FullyQualifiedErrorId | Should -MatchExactly $ExpectedFullyQualifiedErrorId
- $output.Length | Should -Be 1
- $output[0].ToString() | Should -MatchExactly $inputText1
- }
+ $output.Length | Should -Be 1
+ $output[0].ToString() | Should -MatchExactly $inputText1
}
+}
- Context "Cmdlet Functionality" {
+Context "Cmdlet Functionality" {
- It "Path is default Parameter Set 'fhx `$inputFile1'" {
+ It "Path is default Parameter Set 'fhx `$inputFile1'" {
- $result = Format-Hex $inputFile1
+ $result = Format-Hex $inputFile1
- $result | Should -Not -BeNullOrEmpty
- , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $actualResult = $result.ToString()
- $actualResult | Should -MatchExactly $inputText1
- }
+ $result | Should -Not -BeNullOrEmpty
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ $actualResult = $result.ToString()
+ $actualResult | Should -MatchExactly $inputText1
+ }
- It "Validate file input from Pipeline 'Get-ChildItem `$inputFile1 | Format-Hex'" {
+ It "Validate file input from Pipeline 'Get-ChildItem `$inputFile1 | Format-Hex'" {
- $result = Get-ChildItem $inputFile1 | Format-Hex
+ $result = Get-ChildItem $inputFile1 | Format-Hex
- $result | Should -Not -BeNullOrEmpty
- , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $actualResult = $result.ToString()
- $actualResult | Should -MatchExactly $inputText1
- }
+ $result | Should -Not -BeNullOrEmpty
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ $actualResult = $result.ToString()
+ $actualResult | Should -MatchExactly $inputText1
+ }
- It "Validate that streamed text does not have buffer underrun problems ''a' * 30 | Format-Hex'" {
+ It "Validate that streamed text does not have buffer underrun problems ''a' * 30 | Format-Hex'" {
- $result = "a" * 30 | Format-Hex
+ $result = "a" * 30 | Format-Hex
- $result | Should -Not -BeNullOrEmpty
- , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $result.ToString() | Should -MatchExactly "00000000000000000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa$($newline)00000000000000000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
- }
+ $result | Should -Not -BeNullOrEmpty
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ $result.ToString() | Should -MatchExactly "00000000000000000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa$($newline)00000000000000000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
+ }
- It "Validate that files do not have buffer underrun problems 'Format-Hex -Path `$InputFile4'" {
+ It "Validate that files do not have buffer underrun problems 'Format-Hex -Path `$InputFile4'" {
- $result = Format-Hex -Path $InputFile4
+ $result = Format-Hex -Path $InputFile4
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
}
+}
- Context "Count and Offset parameters" {
- It "Count = length" {
+Context "Count and Offset parameters" {
+ It "Count = length" {
- $result = Format-Hex -Path $InputFile4 -Count $inputText4.Length
+ $result = Format-Hex -Path $InputFile4 -Count $inputText4.Length
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
+ }
- It "Count = 1" {
- $result = Format-Hex -Path $inputFile4 -Count 1
- $result.ToString() | Should -MatchExactly "00000000000000000000 4E N "
- }
+ It "Count = 1" {
+ $result = Format-Hex -Path $inputFile4 -Count 1
+ $result.ToString() | Should -MatchExactly "00000000000000000000 4E N "
+ }
- It "Offset = length" {
+ It "Offset = length" {
- $result = Format-Hex -Path $InputFile4 -Offset $inputText4.Length
- $result | Should -BeNullOrEmpty
+ $result = Format-Hex -Path $InputFile4 -Offset $inputText4.Length
+ $result | Should -BeNullOrEmpty
- $result = Format-Hex -InputObject $inputText4 -Offset $inputText4.Length
- $result.Bytes | Should -HaveCount 0
- }
+ $result = Format-Hex -InputObject $inputText4 -Offset $inputText4.Length
+ $result.Bytes | Should -HaveCount 0
+ }
- It "Offset = 1" {
+ It "Offset = 1" {
- $result = Format-Hex -Path $InputFile4 -Offset 1
+ $result = Format-Hex -Path $InputFile4 -Offset 1
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000001 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 72 ow is the winter"
- $result[1].ToString() | Should -MatchExactly "00000000000000000011 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 65 of our disconte"
- $result[2].ToString() | Should -MatchExactly "00000000000000000021 6E 74 nt "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000001 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 72 ow is the winter"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000011 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 65 of our disconte"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000021 6E 74 nt "
+ }
- It "Count = 1 and Offset = 1" {
- $result = Format-Hex -Path $inputFile4 -Count 1 -Offset 1
- $result.ToString() | Should -MatchExactly "00000000000000000001 6F o "
- }
+ It "Count = 1 and Offset = 1" {
+ $result = Format-Hex -Path $inputFile4 -Count 1 -Offset 1
+ $result.ToString() | Should -MatchExactly "00000000000000000001 6F o "
+ }
- It "Count should be > 0" {
- { Format-Hex -Path $inputFile4 -Count 0 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
- }
+ It "Count should be > 0" {
+ { Format-Hex -Path $inputFile4 -Count 0 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
+ }
- It "Offset should be >= 0" {
- { Format-Hex -Path $inputFile4 -Offset -1 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
- }
+ It "Offset should be >= 0" {
+ { Format-Hex -Path $inputFile4 -Offset -1 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
+ }
- It "Offset = 0" {
+ It "Offset = 0" {
- $result = Format-Hex -Path $InputFile4 -Offset 0
+ $result = Format-Hex -Path $InputFile4 -Offset 0
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
}
}
+}
From 94d5c3d3065ee6ef907489370310eee3838a6bf6 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Wed, 17 Jul 2019 12:49:45 -0400
Subject: [PATCH 06/28] :construction: WIP formatview for ByteCollection
---
.../PowerShellCore_format_ps1xml.cs | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 70eaf63bc85..2741111ea0d 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -254,6 +254,10 @@ internal static IEnumerable GetFormatData()
yield return new ExtendedTypeDefinition(
"Microsoft.PowerShell.MarkdownRender.PSMarkdownOptionInfo",
ViewsOf_Microsoft_PowerShell_MarkdownRender_MarkdownOptionInfo());
+
+ yield return new ExtendedTypeDefinition(
+ "Microsoft.PowerShell.Commands.ByteCollection",
+ ViewsOf_Microsoft_PowerShell_Commands_ByteCollection());
}
private static IEnumerable ViewsOf_System_RuntimeType()
@@ -1437,5 +1441,34 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Ma
.EndEntry()
.EndList());
}
+
+ private static IEnumerable ViewsOf_Microsoft_PowerShell_Commands_ByteCollection()
+ {
+ yield return new FormatViewDefinition("Microsoft.PowerShell.Commands.ByteCollection",
+ TableControl.Create()
+ .AddHeader(Alignment.Right, label: "Offset", width: 16)
+ .AddHeader(Alignment.Center, label: "Bytes\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F", width: 47)
+ .AddHeader(Alignment.Left, label: "Ascii", width: 16)
+ .StartRowDefinition()
+ .AddPropertyColumn("Offset64")
+ .AddScriptBlockColumn(@"
+ $sb = [System.Text.StringBuilder]::new()
+ foreach ($Byte in $_.Bytes) {
+ $sb.AppendFormat('{0:X2} ', $Byte)
+ }
+
+ $sb.ToString().Trim()
+ ")
+ .AddScriptBlockColumn(@"
+ $sb = [System.Text.StringBuilder]::new()
+ foreach ($Byte in $_.Bytes) {
+ $sb.Append([char]$Byte)
+ }
+
+ $sb.ToString()
+ ")
+ .EndRowDefinition()
+ .EndTable());
+ }
}
}
From f2a90a86349cbd9815e904d87e7e45b3e6623a40 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Mon, 29 Jul 2019 12:45:18 -0400
Subject: [PATCH 07/28] :construction: add ByteCollection helper methods To
enable easy reconstruction of the output
---
.../commands/utility/UtilityCommon.cs | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index 6e167f61825..95378239f85 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -206,6 +206,58 @@ private set
///
public string Path { get; private set; }
+ ///
+ /// Gets the hexadecimal representation of the value.
+ ///
+ public string HexOffset { get => string.Format("{0:X16}", Offset64); }
+
+ private const int BytesPerLine = 16;
+
+ ///
+ /// Gets a space-delimited string of the in this
+ /// in hexadecimal format.
+ ///
+ public string HexBytes
+ {
+ get
+ {
+ StringBuilder line = new StringBuilder(BytesPerLine * 3);
+
+ foreach (var currentByte in Bytes)
+ {
+ line.AppendFormat("{0:X2} ", currentByte);
+ }
+
+ return line.ToString().Trim();
+ }
+ }
+
+ ///
+ /// Gets the ASCII string representation of the in this .
+ ///
+ ///
+ public string AsciiBytes
+ {
+ get
+ {
+ StringBuilder ascii = new StringBuilder(BytesPerLine);
+
+ foreach (var currentByte in Bytes)
+ {
+ if ((currentByte >= 0x20) && (currentByte <= 0xFE))
+ {
+ ascii.Append((char)currentByte);
+ }
+ else
+ {
+ ascii.Append('.');
+ }
+ }
+
+ return ascii.ToString();
+ }
+ }
+
///
/// Displays the hexadecimal format of the bytes stored in the collection.
///
From 3265993d1eb88ecb0c0bb84a503fbd3d9c2085f9 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Mon, 29 Jul 2019 12:45:52 -0400
Subject: [PATCH 08/28] :art: Add format definition for ByteCollection TODO:
Investigate why it's not taking effect
---
.../PowerShellCore_format_ps1xml.cs | 20 +++----------------
1 file changed, 3 insertions(+), 17 deletions(-)
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 2741111ea0d..256753ff4ed 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -1450,23 +1450,9 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Co
.AddHeader(Alignment.Center, label: "Bytes\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F", width: 47)
.AddHeader(Alignment.Left, label: "Ascii", width: 16)
.StartRowDefinition()
- .AddPropertyColumn("Offset64")
- .AddScriptBlockColumn(@"
- $sb = [System.Text.StringBuilder]::new()
- foreach ($Byte in $_.Bytes) {
- $sb.AppendFormat('{0:X2} ', $Byte)
- }
-
- $sb.ToString().Trim()
- ")
- .AddScriptBlockColumn(@"
- $sb = [System.Text.StringBuilder]::new()
- foreach ($Byte in $_.Bytes) {
- $sb.Append([char]$Byte)
- }
-
- $sb.ToString()
- ")
+ .AddPropertyColumn("HexOffset")
+ .AddPropertyColumn("HexBytes")
+ .AddPropertyColumn("AsciiBytes")
.EndRowDefinition()
.EndTable());
}
From 045ebd6596b04adde0700d911511a539379724eb Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Tue, 30 Jul 2019 12:37:47 -0400
Subject: [PATCH 09/28] :wrench: Address Ilya's review comments Added better
control character handling in new methods. Added explicit culture parameters
for format calls.
---
.../commands/utility/UtilityCommon.cs | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index 95378239f85..3c5dcca2653 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -209,7 +209,7 @@ private set
///
/// Gets the hexadecimal representation of the value.
///
- public string HexOffset { get => string.Format("{0:X16}", Offset64); }
+ public string HexOffset { get => string.Format(CultureInfo.CurrentCulture, "{0:X16}", Offset64); }
private const int BytesPerLine = 16;
@@ -225,7 +225,7 @@ public string HexBytes
foreach (var currentByte in Bytes)
{
- line.AppendFormat("{0:X2} ", currentByte);
+ line.AppendFormat(CultureInfo.CurrentCulture, "{0:X2} ", currentByte);
}
return line.ToString().Trim();
@@ -244,13 +244,18 @@ public string AsciiBytes
foreach (var currentByte in Bytes)
{
- if ((currentByte >= 0x20) && (currentByte <= 0xFE))
+ var currentChar = (char)currentByte;
+ if (char.IsControl(currentChar))
+ {
+ ascii.Append((char)0xFFFD);
+ }
+ else if (currentChar == 0x0)
{
- ascii.Append((char)currentByte);
+ ascii.Append(' ');
}
else
{
- ascii.Append('.');
+ ascii.Append(currentChar);
}
}
From 221250802090b74bad8fc6ece4f28afe1701e29e Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Thu, 3 Oct 2019 16:27:06 -0400
Subject: [PATCH 10/28] :art: Fix formatview issues
---
.../PowerShellCore_format_ps1xml.cs | 35 ++-----------------
1 file changed, 2 insertions(+), 33 deletions(-)
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 256753ff4ed..915c0c59533 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -18,22 +18,8 @@ internal static IEnumerable GetFormatData()
.EndEntry()
.EndControl();
- var ByteCollection_GroupHeader = CustomControl.Create()
- .StartEntry()
- .StartFrame()
- .AddScriptBlockExpressionBinding(@"
- $header = "" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F""
- if($_.Path) { $header = "" "" + [Microsoft.PowerShell.Commands.UtilityResources]::FormatHexPathPrefix + $_.Path + ""`r`n`r`n"" + $header }
-
- $header
- ")
- .EndFrame()
- .EndEntry()
- .EndControl();
-
var sharedControls = new CustomControl[] {
- AvailableModules_GroupingFormat,
- ByteCollection_GroupHeader
+ AvailableModules_GroupingFormat
};
yield return new ExtendedTypeDefinition(
@@ -167,10 +153,6 @@ internal static IEnumerable GetFormatData()
"System.Management.Automation.InformationRecord",
ViewsOf_System_Management_Automation_InformationRecord());
- yield return new ExtendedTypeDefinition(
- "Microsoft.PowerShell.Commands.ByteCollection",
- ViewsOf_Microsoft_PowerShell_Commands_ByteCollection(sharedControls));
-
yield return new ExtendedTypeDefinition(
"System.Exception",
ViewsOf_System_Exception());
@@ -888,19 +870,6 @@ private static IEnumerable ViewsOf_System_Management_Autom
.EndControl());
}
- private static IEnumerable ViewsOf_Microsoft_PowerShell_Commands_ByteCollection(CustomControl[] sharedControls)
- {
- yield return new FormatViewDefinition("ByteCollection",
- CustomControl.Create()
- .GroupByScriptBlock("if($_.Path) { $_.Path } else { $_.GetHashCode() }", customControl: sharedControls[1])
- .StartEntry()
- .StartFrame()
- .AddScriptBlockExpressionBinding(@"$_.ToString()")
- .EndFrame()
- .EndEntry()
- .EndControl());
- }
-
private static IEnumerable ViewsOf_System_Exception()
{
yield return new FormatViewDefinition("Exception",
@@ -1447,7 +1416,7 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Co
yield return new FormatViewDefinition("Microsoft.PowerShell.Commands.ByteCollection",
TableControl.Create()
.AddHeader(Alignment.Right, label: "Offset", width: 16)
- .AddHeader(Alignment.Center, label: "Bytes\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F", width: 47)
+ .AddHeader(Alignment.Left, label: "Bytes\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F", width: 47)
.AddHeader(Alignment.Left, label: "Ascii", width: 16)
.StartRowDefinition()
.AddPropertyColumn("HexOffset")
From 3956925669b66f4361035e2e3a7ee9b9306de0a6 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Mon, 7 Oct 2019 13:09:09 -0400
Subject: [PATCH 11/28] :construction: Output per-line objects
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 24 +++++++++++--------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 76d70cde4c5..22874c04977 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -453,21 +453,25 @@ private byte[] ConvertToByteArray(object inputObject)
#region Output
///
- /// Outputs the hexadecimial representation of the input data.
+ /// Outputs the hexadecimal representation of the input data.
///
- /// Bytes for the hexadecimial representation.
+ /// Bytes for the hexadecimal representation.
/// File path.
/// Offset in the file.
private void WriteHexadecimal(Span inputBytes, string path, long offset)
{
- ByteCollection byteCollectionObject = new ByteCollection((ulong)offset, inputBytes.ToArray(), path);
- WriteObject(byteCollectionObject);
- }
-
- private void WriteHexadecimal(byte[] inputBytes, string path, long offset)
- {
- ByteCollection byteCollectionObject = new ByteCollection((ulong)offset, inputBytes, path);
- WriteObject(byteCollectionObject);
+ var bytesPerObject = 16;
+ for (int index = 0; index < inputBytes.Length; index += bytesPerObject)
+ {
+ var count = inputBytes.Length - index < bytesPerObject
+ ? inputBytes.Length - index
+ : bytesPerObject;
+ var bytes = inputBytes.Slice(index, count);
+ WriteObject(new ByteCollection(
+ (ulong)index + (ulong)offset,
+ bytes.ToArray(),
+ path));
+ }
}
#endregion
From af5f72ba71b85a91f8f7b6f35d166b18120353fc Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Mon, 7 Oct 2019 17:07:16 -0400
Subject: [PATCH 12/28] :construction: refactor output formats and grouping
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 56 ++++++++++---------
1 file changed, 29 insertions(+), 27 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 22874c04977..1870a9de342 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -27,7 +27,7 @@ public sealed class FormatHex : PSCmdlet
/// For cases where a homogenous collection of bytes or other items are directly piped in, we collect all the
/// bytes in a List<byte> and then output the formatted result all at once in EndProcessing().
///
- private List _totalInputBytes;
+ private List _totalInputBytes = new List();
///
/// If the input is determined to be heterogenous piped input or each input object turns out to be a complete
@@ -122,8 +122,12 @@ protected override void EndProcessing()
{
if (_totalInputBytes != null)
{
- int offset = Math.Min(_totalInputBytes.Count, Offset < (long)int.MaxValue ? (int)Offset : int.MaxValue);
- int count = Math.Min(_totalInputBytes.Count - offset, Count < (long)int.MaxValue ? (int)Count : int.MaxValue);
+ int offset = Math.Min(_totalInputBytes.Count, Offset < int.MaxValue
+ ? (int)Offset
+ : int.MaxValue);
+ int count = Math.Min(_totalInputBytes.Count - offset, Count < int.MaxValue
+ ? (int)Count
+ : int.MaxValue);
if (offset != 0 || count != _totalInputBytes.Count)
{
WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), null, 0);
@@ -278,7 +282,6 @@ private void ProcessObjectContent(PSObject inputObject)
if (obj is System.IO.FileSystemInfo fsi)
{
- _isHeterogenousPipedInput = true;
string[] path = { fsi.FullName };
List pathsToProcess = ResolvePaths(path, true);
ProcessPath(pathsToProcess);
@@ -290,28 +293,35 @@ private void ProcessObjectContent(PSObject inputObject)
if (_isHeterogenousPipedInput)
{
// Output any previously stored bytes as individual units for consistency of output
- if (_totalInputBytes != null)
+ if (_totalInputBytes.Count > 0)
{
- foreach (byte b in inputBytes)
+ int offset = Math.Min(
+ _totalInputBytes.Count,
+ Offset < int.MaxValue
+ ? (int)Offset
+ : int.MaxValue);
+ int count = Math.Min(
+ _totalInputBytes.Count - offset,
+ Count < int.MaxValue
+ ? (int)Count
+ : int.MaxValue);
+ if (offset != 0 || count != _totalInputBytes.Count)
+ {
+ WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), null, 0);
+ }
+ else
{
- WriteHexadecimal(new[] { b }, null, 0);
+ WriteHexadecimal(_totalInputBytes.ToArray(), null, 0);
}
- _totalInputBytes = null;
+ _totalInputBytes.Clear();
+ // Reset flag so we can continue grouping similar types that come in
+ _isHeterogenousPipedInput = false;
}
if (inputBytes != null)
{
- int offset = Math.Min(inputBytes.Length, Offset < (long)int.MaxValue ? (int)Offset : int.MaxValue);
- int count = Math.Min(inputBytes.Length - offset, Count < (long)int.MaxValue ? (int)Count : int.MaxValue);
- if (offset != 0 || count != inputBytes.Length)
- {
- WriteHexadecimal(inputBytes.AsSpan().Slice(offset, count), null, 0);
- }
- else
- {
- WriteHexadecimal(inputBytes, null, 0);
- }
+ _totalInputBytes.AddRange(inputBytes);
}
else
{
@@ -328,14 +338,7 @@ private void ProcessObjectContent(PSObject inputObject)
{
if (inputBytes != null)
{
- if (_totalInputBytes == null)
- {
- _totalInputBytes = new List(inputBytes);
- }
- else
- {
- _totalInputBytes.AddRange(inputBytes);
- }
+ _totalInputBytes.AddRange(inputBytes);
}
else
{
@@ -361,7 +364,6 @@ private byte[] ConvertToByteArray(object inputObject)
if (inputObject is string str)
{
_isHeterogenousPipedInput = true;
- _lastInputType = typeof(string);
return Encoding.GetBytes(str);
}
From 2ff99580834a96e36c2d1c20bcd5e3883eba132c Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 16:54:24 -0400
Subject: [PATCH 13/28] :sparkles: Add SourceType to ByteCollection This is to
allow us to group the output correctly.
---
.../commands/utility/UtilityCommon.cs | 32 +++++++++++++------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index 3c5dcca2653..9650e5889be 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -114,7 +114,7 @@ public ByteCollection(UInt32 offset, byte[] value, string path)
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
/// Indicates the path of the file whose contents are wrapped in the ByteCollection.
- public ByteCollection(UInt64 offset, byte[] value, string path)
+ public ByteCollection(ulong offset, byte[] value, string path)
{
if (value == null)
{
@@ -132,15 +132,9 @@ public ByteCollection(UInt64 offset, byte[] value, string path)
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
[Obsolete("The constructor is deprecated.", true)]
- public ByteCollection(UInt32 offset, byte[] value)
+ public ByteCollection(uint offset, byte[] value)
+ : this((ulong)offset, value)
{
- if (value == null)
- {
- throw PSTraceSource.NewArgumentNullException("value");
- }
-
- Offset64 = offset;
- Bytes = value;
}
///
@@ -148,7 +142,7 @@ public ByteCollection(UInt32 offset, byte[] value)
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
- public ByteCollection(UInt64 offset, byte[] value)
+ public ByteCollection(ulong offset, byte[] value)
{
if (value == null)
{
@@ -159,6 +153,18 @@ public ByteCollection(UInt64 offset, byte[] value)
Bytes = value;
}
+ ///
+ /// ByteCollection constructor.
+ ///
+ /// The Offset address to be used while displaying the bytes in the collection.
+ /// Underlying bytes stored in the collection.
+ /// Original object type of the converted input.
+ public ByteCollection(ulong offset, byte[] value, Type sourceType)
+ : this(offset, value)
+ {
+ SourceType = sourceType;
+ }
+
///
/// ByteCollection constructor.
///
@@ -211,6 +217,12 @@ private set
///
public string HexOffset { get => string.Format(CultureInfo.CurrentCulture, "{0:X16}", Offset64); }
+
+ ///
+ /// Gets the type of the input objects used to create the .
+ ///
+ public Type SourceType { get; private set; }
+
private const int BytesPerLine = 16;
///
From b2ff7c798a0a93b1c92215302b604b7f6ec9e3f4 Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 16:59:38 -0400
Subject: [PATCH 14/28] :art: Add GroupBy to std format
---
.../DefaultFormatters/PowerShellCore_format_ps1xml.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 6fff9ffcbdb..e6f2597ec9a 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -1611,6 +1611,7 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Co
.AddPropertyColumn("HexBytes")
.AddPropertyColumn("AsciiBytes")
.EndRowDefinition()
+ .GroupByProperty("SourceType")
.EndTable());
}
}
From 89656bd581819501873eca4974692d2a04e4985a Mon Sep 17 00:00:00 2001
From: Joel <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 17:21:11 -0400
Subject: [PATCH 15/28] :construction: :art: Finish grouping logic Pending
interactive testing.
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 42 +++++++++++++++----
.../commands/utility/UtilityCommon.cs | 1 -
.../PowerShellCore_format_ps1xml.cs | 13 +++++-
3 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 1870a9de342..1bc9336e9fb 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -130,11 +130,11 @@ protected override void EndProcessing()
: int.MaxValue);
if (offset != 0 || count != _totalInputBytes.Count)
{
- WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), null, 0);
+ WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), 0, _lastInputType);
}
else
{
- WriteHexadecimal(_totalInputBytes.ToArray(), null, 0);
+ WriteHexadecimal(_totalInputBytes.ToArray(), 0, _lastInputType);
}
}
}
@@ -280,8 +280,10 @@ private void ProcessObjectContent(PSObject inputObject)
{
object obj = inputObject.BaseObject;
- if (obj is System.IO.FileSystemInfo fsi)
+ if (obj is FileSystemInfo fsi)
{
+ // Clear last input type to prevent anything mistakenly grouping around files
+ _lastInputType = null;
string[] path = { fsi.FullName };
List pathsToProcess = ResolvePaths(path, true);
ProcessPath(pathsToProcess);
@@ -303,19 +305,19 @@ private void ProcessObjectContent(PSObject inputObject)
int count = Math.Min(
_totalInputBytes.Count - offset,
Count < int.MaxValue
- ? (int)Count
- : int.MaxValue);
+ ? (int)Count
+ : int.MaxValue);
if (offset != 0 || count != _totalInputBytes.Count)
{
- WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), null, 0);
+ WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), 0, _lastInputType);
}
else
{
- WriteHexadecimal(_totalInputBytes.ToArray(), null, 0);
+ WriteHexadecimal(_totalInputBytes.ToArray(), 0, _lastInputType);
}
_totalInputBytes.Clear();
- // Reset flag so we can continue grouping similar types that come in
+ // Reset flags so we can properly grouping later objects
_isHeterogenousPipedInput = false;
}
@@ -363,6 +365,8 @@ private byte[] ConvertToByteArray(object inputObject)
{
if (inputObject is string str)
{
+ // Clear last input type to prevent anything mistakenly grouping with strings
+ _lastInputType = null;
_isHeterogenousPipedInput = true;
return Encoding.GetBytes(str);
}
@@ -476,6 +480,28 @@ private void WriteHexadecimal(Span inputBytes, string path, long offset)
}
}
+ ///
+ /// Outputs the hexadecimal representation of the input data.
+ ///
+ /// Bytes for the hexadecimal representation.
+ /// Offset in the file.
+ /// The type of the original input objects.
+ private void WriteHexadecimal(Span inputBytes, long offset, Type sourceType)
+ {
+ var bytesPerObject = 16;
+ for (int index = 0; index < inputBytes.Length; index += bytesPerObject)
+ {
+ var count = inputBytes.Length - index < bytesPerObject
+ ? inputBytes.Length - index
+ : bytesPerObject;
+ var bytes = inputBytes.Slice(index, count);
+ WriteObject(new ByteCollection(
+ (ulong)index + (ulong)offset,
+ bytes.ToArray(),
+ sourceType));
+ }
+ }
+
#endregion
}
}
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index 9650e5889be..da396473361 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -217,7 +217,6 @@ private set
///
public string HexOffset { get => string.Format(CultureInfo.CurrentCulture, "{0:X16}", Offset64); }
-
///
/// Gets the type of the input objects used to create the .
///
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index e6f2597ec9a..64f7b47190e 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -1611,7 +1611,18 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Co
.AddPropertyColumn("HexBytes")
.AddPropertyColumn("AsciiBytes")
.EndRowDefinition()
- .GroupByProperty("SourceType")
+ .GroupByScriptBlock(@"
+ if ($_.SourceType) {
+ $_.SourceType
+ }
+ else if ($_.Path)
+ {
+ $_.Path
+ }
+ else {
+ $_.GetHashCode()
+ }
+ ")
.EndTable());
}
}
From 3c539560c9360bb8d732a85da9dbba44e4c9b6eb Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 18:50:59 -0400
Subject: [PATCH 16/28] :construction: Add backing properties No need to
rebuild the strings every single time.
---
.../commands/utility/UtilityCommon.cs | 52 ++++++++++++-------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index da396473361..6a3805b219c 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -224,6 +224,7 @@ private set
private const int BytesPerLine = 16;
+ private string _hexBytes;
///
/// Gets a space-delimited string of the in this
/// in hexadecimal format.
@@ -232,17 +233,23 @@ public string HexBytes
{
get
{
- StringBuilder line = new StringBuilder(BytesPerLine * 3);
-
- foreach (var currentByte in Bytes)
+ if (_hexBytes == null)
{
- line.AppendFormat(CultureInfo.CurrentCulture, "{0:X2} ", currentByte);
+ StringBuilder line = new StringBuilder(BytesPerLine * 3);
+
+ foreach (var currentByte in Bytes)
+ {
+ line.AppendFormat(CultureInfo.CurrentCulture, "{0:X2} ", currentByte);
+ }
+
+ _hexBytes = line.ToString().Trim();
}
- return line.ToString().Trim();
+ return _hexBytes;
}
}
+ private string _asciiBytes;
///
/// Gets the ASCII string representation of the in this .
///
@@ -251,26 +258,31 @@ public string AsciiBytes
{
get
{
- StringBuilder ascii = new StringBuilder(BytesPerLine);
-
- foreach (var currentByte in Bytes)
+ if (_asciiBytes == null)
{
- var currentChar = (char)currentByte;
- if (char.IsControl(currentChar))
- {
- ascii.Append((char)0xFFFD);
- }
- else if (currentChar == 0x0)
- {
- ascii.Append(' ');
- }
- else
+ StringBuilder ascii = new StringBuilder(BytesPerLine);
+
+ foreach (var currentByte in Bytes)
{
- ascii.Append(currentChar);
+ var currentChar = (char)currentByte;
+ if (char.IsControl(currentChar))
+ {
+ ascii.Append((char)0xFFFD);
+ }
+ else if (currentChar == 0x0)
+ {
+ ascii.Append(' ');
+ }
+ else
+ {
+ ascii.Append(currentChar);
+ }
}
+
+ _asciiBytes = ascii.ToString();
}
- return ascii.ToString();
+ return _asciiBytes;
}
}
From 77caa05f175bf2b3f0bf976e836a51fe001dd72a Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 18:52:18 -0400
Subject: [PATCH 17/28] :art: group bytecollection tables naturally - file
tables are grouped by their Path - primitives are grouped by their SourceType
- strings are "grouped" by the string contents (ungrouped)
---
.../DefaultFormatters/PowerShellCore_format_ps1xml.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 64f7b47190e..8e2bf22f301 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -1613,14 +1613,14 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Co
.EndRowDefinition()
.GroupByScriptBlock(@"
if ($_.SourceType) {
- $_.SourceType
+ 'TypeName: {0}' -f $_.SourceType.FullName
}
else if ($_.Path)
{
- $_.Path
+ 'Path: {0}' -f $_.Path
}
else {
- $_.GetHashCode()
+ 'String: {0}' -f $_.AsciiBytes
}
")
.EndTable());
From 3d8955cf94f2f5cc7edd54cc9398b8d7a0fa7fbc Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 22:54:41 -0400
Subject: [PATCH 18/28] :construction: Overhaul ByteCollection - Refactor
constructors to minimise duplicate code - Store hex and ascii strings during
first get - Add Label property to facilitate grouping byte collections
---
.../commands/utility/UtilityCommon.cs | 40 ++++++++++---------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index 6a3805b219c..de474b8ee22 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -101,11 +101,9 @@ public class ByteCollection
/// Underlying bytes stored in the collection.
/// Indicates the path of the file whose contents are wrapped in the ByteCollection.
[Obsolete("The constructor is deprecated.", true)]
- public ByteCollection(UInt32 offset, byte[] value, string path)
+ public ByteCollection(uint offset, byte[] value, string path)
+ : this((ulong)offset, value, path)
{
- Offset64 = offset;
- Bytes = value;
- Path = path;
}
///
@@ -124,6 +122,7 @@ public ByteCollection(ulong offset, byte[] value, string path)
Offset64 = offset;
Bytes = value;
Path = path;
+ Label = path;
}
///
@@ -158,11 +157,14 @@ public ByteCollection(ulong offset, byte[] value)
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
- /// Original object type of the converted input.
- public ByteCollection(ulong offset, byte[] value, Type sourceType)
+ ///
+ /// The label for the byte group. This may be a file path, a string value, or a
+ /// formatted identifying string for the group.
+ ///
+ public ByteCollection(ulong offset, string label, byte[] value)
: this(offset, value)
{
- SourceType = sourceType;
+ Label = label;
}
///
@@ -220,11 +222,11 @@ private set
///
/// Gets the type of the input objects used to create the .
///
- public Type SourceType { get; private set; }
+ public string Label { get; private set; }
private const int BytesPerLine = 16;
- private string _hexBytes;
+ private string _hexBytes = string.Empty;
///
/// Gets a space-delimited string of the in this
/// in hexadecimal format.
@@ -233,7 +235,7 @@ public string HexBytes
{
get
{
- if (_hexBytes == null)
+ if (_hexBytes == string.Empty)
{
StringBuilder line = new StringBuilder(BytesPerLine * 3);
@@ -249,29 +251,29 @@ public string HexBytes
}
}
- private string _asciiBytes;
+ private string _ascii = string.Empty;
///
/// Gets the ASCII string representation of the in this .
///
///
- public string AsciiBytes
+ public string Ascii
{
get
{
- if (_asciiBytes == null)
+ if (_ascii == string.Empty)
{
StringBuilder ascii = new StringBuilder(BytesPerLine);
foreach (var currentByte in Bytes)
{
var currentChar = (char)currentByte;
- if (char.IsControl(currentChar))
+ if (currentChar == 0x0)
{
- ascii.Append((char)0xFFFD);
+ ascii.Append(' ');
}
- else if (currentChar == 0x0)
+ else if (char.IsControl(currentChar))
{
- ascii.Append(' ');
+ ascii.Append((char)0xFFFD);
}
else
{
@@ -279,10 +281,10 @@ public string AsciiBytes
}
}
- _asciiBytes = ascii.ToString();
+ _ascii = ascii.ToString();
}
- return _asciiBytes;
+ return _ascii;
}
}
From 116f09685fb47db841cf81ab82f356534b9edd7e Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 23:00:12 -0400
Subject: [PATCH 19/28] :art: Update bytecollection formatter
---
.../PowerShellCore_format_ps1xml.cs | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 8e2bf22f301..f83d6957b3b 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -1601,7 +1601,8 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Ma
private static IEnumerable ViewsOf_Microsoft_PowerShell_Commands_ByteCollection()
{
- yield return new FormatViewDefinition("Microsoft.PowerShell.Commands.ByteCollection",
+ yield return new FormatViewDefinition(
+ "Microsoft.PowerShell.Commands.ByteCollection",
TableControl.Create()
.AddHeader(Alignment.Right, label: "Offset", width: 16)
.AddHeader(Alignment.Left, label: "Bytes\n00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F", width: 47)
@@ -1609,20 +1610,9 @@ private static IEnumerable ViewsOf_Microsoft_PowerShell_Co
.StartRowDefinition()
.AddPropertyColumn("HexOffset")
.AddPropertyColumn("HexBytes")
- .AddPropertyColumn("AsciiBytes")
+ .AddPropertyColumn("Ascii")
.EndRowDefinition()
- .GroupByScriptBlock(@"
- if ($_.SourceType) {
- 'TypeName: {0}' -f $_.SourceType.FullName
- }
- else if ($_.Path)
- {
- 'Path: {0}' -f $_.Path
- }
- else {
- 'String: {0}' -f $_.AsciiBytes
- }
- ")
+ .GroupByProperty("Label")
.EndTable());
}
}
From d3563a46ff1df22a4e547331fbed01ee510866a6 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 23:01:58 -0400
Subject: [PATCH 20/28] :recycle: Refactor Format-Hex to permit grouping - New
behaviour is to group primitives by default over the pipeline - Arrays are
handled as a single unit and confined to their own grouping - Strings and
FileInfo input is also handled on a unit basis
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 133 +++++++++++-------
1 file changed, 83 insertions(+), 50 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 1bc9336e9fb..d7d72aaa16c 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -27,7 +27,7 @@ public sealed class FormatHex : PSCmdlet
/// For cases where a homogenous collection of bytes or other items are directly piped in, we collect all the
/// bytes in a List<byte> and then output the formatted result all at once in EndProcessing().
///
- private List _totalInputBytes = new List();
+ private List _inputBuffer = new List();
///
/// If the input is determined to be heterogenous piped input or each input object turns out to be a complete
@@ -104,7 +104,7 @@ protected override void ProcessRecord()
{
if (string.Equals(this.ParameterSetName, "ByInputObject", StringComparison.OrdinalIgnoreCase))
{
- ProcessObjectContent(InputObject);
+ ProcessInputObjects(InputObject);
}
else
{
@@ -120,21 +120,21 @@ protected override void ProcessRecord()
///
protected override void EndProcessing()
{
- if (_totalInputBytes != null)
+ if (_inputBuffer.Count > 0)
{
- int offset = Math.Min(_totalInputBytes.Count, Offset < int.MaxValue
+ int offset = Math.Min(_inputBuffer.Count, Offset < int.MaxValue
? (int)Offset
: int.MaxValue);
- int count = Math.Min(_totalInputBytes.Count - offset, Count < int.MaxValue
+ int count = Math.Min(_inputBuffer.Count - offset, Count < int.MaxValue
? (int)Count
: int.MaxValue);
- if (offset != 0 || count != _totalInputBytes.Count)
+ if (offset != 0 || count != _inputBuffer.Count)
{
- WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), 0, _lastInputType);
+ WriteHexadecimal(_inputBuffer.GetRange(offset, count).ToArray(), 0, GetGroupLabel(_lastInputType));
}
else
{
- WriteHexadecimal(_totalInputBytes.ToArray(), 0, _lastInputType);
+ WriteHexadecimal(_inputBuffer.ToArray(), 0, GetGroupLabel(_lastInputType));
}
}
}
@@ -271,59 +271,96 @@ private void ProcessFileContent(string path)
#region InputObjects
+ private void ProcessString(string originalString)
+ {
+ Span bytes = Encoding.GetBytes(originalString);
+
+ int offset = Math.Min(bytes.Length, Offset < int.MaxValue ? (int)Offset : int.MaxValue);
+ int count = Math.Min(bytes.Length - offset, Count < int.MaxValue ? (int)Count : int.MaxValue);
+
+ if (offset != 0 || count != bytes.Length)
+ {
+ WriteHexadecimal(bytes.Slice(offset, count), offset: 0, GetGroupLabel(typeof(string)));
+ }
+ else
+ {
+ WriteHexadecimal(bytes, offset: 0, label: GetGroupLabel(typeof(string)));
+ }
+ }
+
+ private static readonly Random _idGenerator = new Random();
+ private string GetGroupLabel(Type inputType)
+ {
+ return string.Format("{0} ({1}) <{2:X}>", inputType.Name, inputType.FullName, _idGenerator.Next());
+ }
+
+ private void FlushInputBuffer()
+ {
+ if (_inputBuffer.Count == 0)
+ {
+ return;
+ }
+
+ int offset = Math.Min(_inputBuffer.Count, Offset < int.MaxValue ? (int)Offset : int.MaxValue);
+ int count = Math.Min(_inputBuffer.Count - offset, Count < int.MaxValue ? (int)Count : int.MaxValue);
+
+ if (offset != 0 || count != _inputBuffer.Count)
+ {
+ WriteHexadecimal(
+ _inputBuffer.GetRange(offset, count).ToArray(),
+ label: GetGroupLabel(_lastInputType),
+ offset: 0);
+ }
+ else
+ {
+ WriteHexadecimal(
+ _inputBuffer.ToArray(),
+ label: GetGroupLabel(_lastInputType),
+ offset: 0);
+ }
+
+ // Reset flags so we can go back to filling up the buffer when needed.
+ _lastInputType = null;
+ _isHeterogenousPipedInput = false;
+ _inputBuffer.Clear();
+ }
+
///
/// Creates a byte array from the object passed to the cmdlet (based on type) and passes
/// that array on to the WriteHexadecimal method to output.
///
/// The pipeline input object being processed.
- private void ProcessObjectContent(PSObject inputObject)
+ private void ProcessInputObjects(PSObject inputObject)
{
object obj = inputObject.BaseObject;
if (obj is FileSystemInfo fsi)
{
- // Clear last input type to prevent anything mistakenly grouping around files
- _lastInputType = null;
+ // Output already processed objects first, then process the file input.
+ FlushInputBuffer();
string[] path = { fsi.FullName };
List pathsToProcess = ResolvePaths(path, true);
ProcessPath(pathsToProcess);
return;
}
+ if (obj is string str)
+ {
+ // Output already processed objects first, then process the string input.
+ FlushInputBuffer();
+ ProcessString(str);
+ return;
+ }
+
byte[] inputBytes = ConvertToByteArray(obj);
if (_isHeterogenousPipedInput)
{
- // Output any previously stored bytes as individual units for consistency of output
- if (_totalInputBytes.Count > 0)
- {
- int offset = Math.Min(
- _totalInputBytes.Count,
- Offset < int.MaxValue
- ? (int)Offset
- : int.MaxValue);
- int count = Math.Min(
- _totalInputBytes.Count - offset,
- Count < int.MaxValue
- ? (int)Count
- : int.MaxValue);
- if (offset != 0 || count != _totalInputBytes.Count)
- {
- WriteHexadecimal(_totalInputBytes.GetRange(offset, count).ToArray(), 0, _lastInputType);
- }
- else
- {
- WriteHexadecimal(_totalInputBytes.ToArray(), 0, _lastInputType);
- }
-
- _totalInputBytes.Clear();
- // Reset flags so we can properly grouping later objects
- _isHeterogenousPipedInput = false;
- }
+ FlushInputBuffer();
if (inputBytes != null)
{
- _totalInputBytes.AddRange(inputBytes);
+ _inputBuffer.AddRange(inputBytes);
}
else
{
@@ -340,7 +377,7 @@ private void ProcessObjectContent(PSObject inputObject)
{
if (inputBytes != null)
{
- _totalInputBytes.AddRange(inputBytes);
+ _inputBuffer.AddRange(inputBytes);
}
else
{
@@ -363,14 +400,6 @@ private void ProcessObjectContent(PSObject inputObject)
/// Returns a byte array of the input values, or null if there is no available conversion path.
private byte[] ConvertToByteArray(object inputObject)
{
- if (inputObject is string str)
- {
- // Clear last input type to prevent anything mistakenly grouping with strings
- _lastInputType = null;
- _isHeterogenousPipedInput = true;
- return Encoding.GetBytes(str);
- }
-
Type baseType = inputObject.GetType();
byte[] result = null;
int elements = 1;
@@ -380,6 +409,7 @@ private byte[] ConvertToByteArray(object inputObject)
if (baseType.IsArray)
{
_isHeterogenousPipedInput = true;
+ _lastInputType = baseType;
baseType = baseType.GetElementType();
dynamic dynamicObject = inputObject;
elements = (int)dynamicObject.Length;
@@ -485,8 +515,11 @@ private void WriteHexadecimal(Span inputBytes, string path, long offset)
///
/// Bytes for the hexadecimal representation.
/// Offset in the file.
- /// The type of the original input objects.
- private void WriteHexadecimal(Span inputBytes, long offset, Type sourceType)
+ ///
+ /// The label for the byte group. This may be a file path, a string value, or a
+ /// formatted identifying string for the group.
+ ///
+ private void WriteHexadecimal(Span inputBytes, long offset, string label)
{
var bytesPerObject = 16;
for (int index = 0; index < inputBytes.Length; index += bytesPerObject)
@@ -498,7 +531,7 @@ private void WriteHexadecimal(Span inputBytes, long offset, Type sourceTyp
WriteObject(new ByteCollection(
(ulong)index + (ulong)offset,
bytes.ToArray(),
- sourceType));
+ label));
}
}
From 06793e79dbf98fc3e9f4e5c054d8521fc50bdd1e Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Tue, 8 Oct 2019 23:46:06 -0400
Subject: [PATCH 21/28] :bug: Fix issue with consecutive arrays over pipe
---
.../commands/utility/FormatAndOutput/format-hex/Format-Hex.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index d7d72aaa16c..c0029cd2cfe 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -408,9 +408,10 @@ private byte[] ConvertToByteArray(object inputObject)
bool isEnum = false;
if (baseType.IsArray)
{
- _isHeterogenousPipedInput = true;
+ FlushInputBuffer();
_lastInputType = baseType;
baseType = baseType.GetElementType();
+ _isHeterogenousPipedInput = true;
dynamic dynamicObject = inputObject;
elements = (int)dynamicObject.Length;
isArray = true;
From 643bdcf67bef07aae97ad231b2cdf4d38d787328 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Wed, 9 Oct 2019 07:19:30 -0400
Subject: [PATCH 22/28] :recycle: Tidy up FormatHexCommand Consolidated
duplicate code, renamed grouping flag appropriately.
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 138 ++++++++----------
1 file changed, 60 insertions(+), 78 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index c0029cd2cfe..1ba4a6bdf57 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -17,7 +17,7 @@ namespace Microsoft.PowerShell.Commands
/// Displays the hexadecimal equivalent of the input data.
///
[Cmdlet(VerbsCommon.Format, "Hex", HelpUri = "https://go.microsoft.com/fwlink/?LinkId=526919")]
- [OutputType(typeof(Microsoft.PowerShell.Commands.ByteCollection))]
+ [OutputType(typeof(ByteCollection))]
[Alias("fhx")]
public sealed class FormatHex : PSCmdlet
{
@@ -27,13 +27,14 @@ public sealed class FormatHex : PSCmdlet
/// For cases where a homogenous collection of bytes or other items are directly piped in, we collect all the
/// bytes in a List<byte> and then output the formatted result all at once in EndProcessing().
///
- private List _inputBuffer = new List();
+ private readonly List _inputBuffer = new List();
///
- /// If the input is determined to be heterogenous piped input or each input object turns out to be a complete
- /// array of items, we output each item as we receive it to avoid squashing output together in strange ways.
+ /// Expect to group s by default. When receiving input that should not be grouped,
+ /// e.g., arrays, strings, FileInfo objects, this flag will be disabled until the next groupable
+ /// is received over the pipeline.
///
- private bool _isHeterogenousPipedInput;
+ private bool _groupInput = true;
///
/// Keep track of prior input types to determine if we're given a heterogenous collection.
@@ -102,14 +103,15 @@ public sealed class FormatHex : PSCmdlet
///
protected override void ProcessRecord()
{
- if (string.Equals(this.ParameterSetName, "ByInputObject", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(ParameterSetName, "ByInputObject", StringComparison.OrdinalIgnoreCase))
{
ProcessInputObjects(InputObject);
}
else
{
- List pathsToProcess = string.Equals(this.ParameterSetName, "LiteralPath", StringComparison.OrdinalIgnoreCase) ?
- ResolvePaths(LiteralPath, true) : ResolvePaths(Path, false);
+ List pathsToProcess = string.Equals(ParameterSetName, "LiteralPath", StringComparison.OrdinalIgnoreCase)
+ ? ResolvePaths(LiteralPath, true)
+ : ResolvePaths(Path, false);
ProcessPath(pathsToProcess);
}
@@ -122,12 +124,9 @@ protected override void EndProcessing()
{
if (_inputBuffer.Count > 0)
{
- int offset = Math.Min(_inputBuffer.Count, Offset < int.MaxValue
- ? (int)Offset
- : int.MaxValue);
- int count = Math.Min(_inputBuffer.Count - offset, Count < int.MaxValue
- ? (int)Count
- : int.MaxValue);
+ int offset = Math.Min(_inputBuffer.Count, Offset < int.MaxValue ? (int)Offset : int.MaxValue);
+ int count = Math.Min(_inputBuffer.Count - offset, Count < int.MaxValue ? (int)Count : int.MaxValue);
+
if (offset != 0 || count != _inputBuffer.Count)
{
WriteHexadecimal(_inputBuffer.GetRange(offset, count).ToArray(), 0, GetGroupLabel(_lastInputType));
@@ -155,7 +154,6 @@ private List ResolvePaths(string[] path, bool literalPath)
{
List pathsToProcess = new List();
ProviderInfo provider = null;
- PSDriveInfo drive = null;
foreach (string currentPath in path)
{
@@ -163,7 +161,7 @@ private List ResolvePaths(string[] path, bool literalPath)
if (literalPath)
{
- newPaths.Add(Context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(currentPath, out provider, out drive));
+ newPaths.Add(Context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(currentPath, out provider, out _));
}
else
{
@@ -224,28 +222,26 @@ private void ProcessFileContent(string path)
try
{
- using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)))
- {
- long offset = Offset;
- int bytesRead = 0;
- long count = 0;
+ using var reader = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read));
+ long offset = Offset;
+ int bytesRead = 0;
+ long count = 0;
- reader.BaseStream.Position = Offset;
+ reader.BaseStream.Position = Offset;
- while ((bytesRead = reader.Read(buffer)) > 0)
+ while ((bytesRead = reader.Read(buffer)) > 0)
+ {
+ count += bytesRead;
+ if (count > Count)
{
- count += bytesRead;
- if (count > Count)
- {
- bytesRead -= (int)(count - Count);
- WriteHexadecimal(buffer.Slice(0, bytesRead), path, offset);
- break;
- }
-
+ bytesRead -= (int)(count - Count);
WriteHexadecimal(buffer.Slice(0, bytesRead), path, offset);
-
- offset += bytesRead;
+ break;
}
+
+ WriteHexadecimal(buffer.Slice(0, bytesRead), path, offset);
+
+ offset += bytesRead;
}
}
catch (IOException fileException)
@@ -259,11 +255,19 @@ private void ProcessFileContent(string path)
}
catch (NotSupportedException notSupportedException)
{
- WriteError(new ErrorRecord(notSupportedException, "FormatHexPathRefersToANonFileDevice", ErrorCategory.InvalidArgument, path));
+ WriteError(new ErrorRecord(
+ notSupportedException,
+ "FormatHexPathRefersToANonFileDevice",
+ ErrorCategory.InvalidArgument,
+ path));
}
catch (SecurityException securityException)
{
- WriteError(new ErrorRecord(securityException, "FormatHexUnauthorizedAccessError", ErrorCategory.PermissionDenied, path));
+ WriteError(new ErrorRecord(
+ securityException,
+ "FormatHexUnauthorizedAccessError",
+ ErrorCategory.PermissionDenied,
+ path));
}
}
@@ -321,7 +325,7 @@ private void FlushInputBuffer()
// Reset flags so we can go back to filling up the buffer when needed.
_lastInputType = null;
- _isHeterogenousPipedInput = false;
+ _groupInput = true;
_inputBuffer.Clear();
}
@@ -352,43 +356,26 @@ private void ProcessInputObjects(PSObject inputObject)
return;
}
- byte[] inputBytes = ConvertToByteArray(obj);
+ byte[] inputBytes = ConvertToBytes(obj);
- if (_isHeterogenousPipedInput)
+ if (!_groupInput)
{
FlushInputBuffer();
+ }
- if (inputBytes != null)
- {
- _inputBuffer.AddRange(inputBytes);
- }
- else
- {
- string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
- ErrorRecord errorRecord = new ErrorRecord(
- new ArgumentException(errorMessage),
- "FormatHexTypeNotSupported",
- ErrorCategory.InvalidArgument,
- obj.GetType());
- WriteError(errorRecord);
- }
+ if (inputBytes != null)
+ {
+ _inputBuffer.AddRange(inputBytes);
}
else
{
- if (inputBytes != null)
- {
- _inputBuffer.AddRange(inputBytes);
- }
- else
- {
- string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
- ErrorRecord errorRecord = new ErrorRecord(
- new ArgumentException(errorMessage),
- "FormatHexTypeNotSupported",
- ErrorCategory.InvalidArgument,
- obj.GetType());
- WriteError(errorRecord);
- }
+ string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
+ ErrorRecord errorRecord = new ErrorRecord(
+ new ArgumentException(errorMessage),
+ "FormatHexTypeNotSupported",
+ ErrorCategory.InvalidArgument,
+ obj.GetType());
+ WriteError(errorRecord);
}
}
@@ -398,7 +385,7 @@ private void ProcessInputObjects(PSObject inputObject)
///
/// The object to convert.
/// Returns a byte array of the input values, or null if there is no available conversion path.
- private byte[] ConvertToByteArray(object inputObject)
+ private byte[] ConvertToBytes(object inputObject)
{
Type baseType = inputObject.GetType();
byte[] result = null;
@@ -410,8 +397,9 @@ private byte[] ConvertToByteArray(object inputObject)
{
FlushInputBuffer();
_lastInputType = baseType;
+ _groupInput = false;
+
baseType = baseType.GetElementType();
- _isHeterogenousPipedInput = true;
dynamic dynamicObject = inputObject;
elements = (int)dynamicObject.Length;
isArray = true;
@@ -425,11 +413,11 @@ private byte[] ConvertToByteArray(object inputObject)
if (baseType.IsPrimitive && elements > 0)
{
- if (!_isHeterogenousPipedInput)
+ if (_groupInput)
{
if (_lastInputType != null && baseType != _lastInputType)
{
- _isHeterogenousPipedInput = true;
+ _groupInput = false;
}
_lastInputType = baseType;
@@ -504,10 +492,7 @@ private void WriteHexadecimal(Span inputBytes, string path, long offset)
? inputBytes.Length - index
: bytesPerObject;
var bytes = inputBytes.Slice(index, count);
- WriteObject(new ByteCollection(
- (ulong)index + (ulong)offset,
- bytes.ToArray(),
- path));
+ WriteObject(new ByteCollection((ulong)index + (ulong)offset, bytes.ToArray(), path));
}
}
@@ -529,10 +514,7 @@ private void WriteHexadecimal(Span inputBytes, long offset, string label)
? inputBytes.Length - index
: bytesPerObject;
var bytes = inputBytes.Slice(index, count);
- WriteObject(new ByteCollection(
- (ulong)index + (ulong)offset,
- bytes.ToArray(),
- label));
+ WriteObject(new ByteCollection((ulong)index + (ulong)offset, bytes.ToArray(), label));
}
}
From 65f9cbe0fb4c989f3a08f55c42f7dc4d0a2600f4 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Wed, 9 Oct 2019 07:35:08 -0400
Subject: [PATCH 23/28] :art: Update the .ToString() for ByteCollection Make it
match what we're displaying in the tabular format
---
.../commands/utility/UtilityCommon.cs | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index de474b8ee22..6f679fb20dd 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -295,7 +295,7 @@ public string Ascii
public override string ToString()
{
const int BytesPerLine = 16;
- const string LineFormat = "{0:X20} ";
+ const string LineFormat = "{0:X16} ";
// '20 + 3' comes from format "{0:X20} ".
// '20' comes from '[Uint64]::MaxValue.ToString().Length'.
@@ -322,13 +322,18 @@ public override string ToString()
// If the character is printable, add its ascii representation to
// the right-hand side. Otherwise, add a dot to the right hand side.
- if ((currentByte >= 0x20) && (currentByte <= 0xFE))
+ var currentChar = (char)currentByte;
+ if (currentChar == 0x0)
{
- asciiEnd.Append((char)currentByte);
+ asciiEnd.Append(' ');
+ }
+ else if (char.IsControl(currentChar))
+ {
+ asciiEnd.Append((char)0xFFFD);
}
else
{
- asciiEnd.Append('.');
+ asciiEnd.Append(currentChar);
}
charCounter++;
From 61722d2ea0d5160d04d71c00b38b0eef1172c68f Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Wed, 9 Oct 2019 08:31:42 -0400
Subject: [PATCH 24/28] :recycle: Cleanup ByteCollection
---
.../commands/utility/UtilityCommon.cs | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index 6f679fb20dd..ee9aa173d08 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -297,9 +297,9 @@ public override string ToString()
const int BytesPerLine = 16;
const string LineFormat = "{0:X16} ";
- // '20 + 3' comes from format "{0:X20} ".
- // '20' comes from '[Uint64]::MaxValue.ToString().Length'.
- StringBuilder nextLine = new StringBuilder(20 + 3 + (BytesPerLine * 3));
+ // '16 + 3' comes from format "{0:X16} ".
+ // '16' comes from '[Uint64]::MaxValue.ToString("X").Length'.
+ StringBuilder nextLine = new StringBuilder(16 + 3 + (BytesPerLine * 3));
StringBuilder asciiEnd = new StringBuilder(BytesPerLine);
// '+1' comes from 'result.Append(nextLine.ToString() + " " + asciiEnd.ToString());' below.
@@ -307,10 +307,8 @@ public override string ToString()
if (Bytes.Length > 0)
{
- Int64 charCounter = 0;
+ long charCounter = 0;
- // ToString() in invoked thrice by the F&O for the same content.
- // Hence making sure that Offset is not getting incremented thrice for the same bytes being displayed.
var currentOffset = Offset64;
nextLine.AppendFormat(CultureInfo.InvariantCulture, LineFormat, currentOffset);
@@ -349,7 +347,7 @@ public override string ToString()
nextLine.AppendFormat(CultureInfo.InvariantCulture, LineFormat, currentOffset);
// Adding a newline to support long inputs strings flowing through InputObject parameterset.
- if ((charCounter <= Bytes.Length) && string.IsNullOrEmpty(this.Path))
+ if ((charCounter <= Bytes.Length) && string.IsNullOrEmpty(Path))
{
result.AppendLine();
}
From f78bfa9ceec483b8fd5e349e60e085a059f7c797 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Wed, 9 Oct 2019 08:32:00 -0400
Subject: [PATCH 25/28] :white_check_mark: Finish updating tests
---
.../Format-Hex.Tests.ps1 | 353 +++++++++++-------
1 file changed, 209 insertions(+), 144 deletions(-)
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
index 912d2910f2c..875273acac0 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Format-Hex.Tests.ps1
@@ -19,14 +19,21 @@ Describe "FormatHex" -tags "CI" {
$newline = [Environment]::Newline
Setup -d FormatHexDataDir
+ $inputFile1 = New-Item -Path "$TestDrive/SourceFile-1.txt"
$inputText1 = 'Hello World'
+ Set-Content -LiteralPath $inputFile1.FullName -Value $inputText1 -NoNewline
+
+ $inputFile2 = New-Item -Path "$TestDrive/SourceFile-2.txt"
$inputText2 = 'More text'
+ Set-Content -LiteralPath $inputFile2.FullName -Value $inputText2 -NoNewline
+
+ $inputFile3 = New-Item -Path "$TestDrive/SourceFile literal [3].txt"
$inputText3 = 'Literal path'
+ Set-Content -LiteralPath $inputFile3.FullName -Value $inputText3 -NoNewline
+
+ $inputFile4 = New-Item -Path "$TestDrive/SourceFile-4.txt"
$inputText4 = 'Now is the winter of our discontent'
- $inputFile1 = Setup -f "FormatHexDataDir/SourceFile-1.txt" -content $inputText1 -pass
- $inputFile2 = Setup -f "FormatHexDataDir/SourceFile-2.txt" -content $inputText2 -pass
- $inputFile3 = Setup -f "FormatHexDataDir/SourceFile literal [3].txt" -content $inputText3 -pass
- $inputFile4 = Setup -f "FormatHexDataDir/SourceFile-4.txt" -content $inputText4 -pass
+ Set-Content -LiteralPath $inputFile4.FullName -Value $inputText4 -NoNewline
$certificateProvider = Get-ChildItem Cert:\CurrentUser\My\ -ErrorAction SilentlyContinue
$thumbprint = $null
@@ -90,37 +97,37 @@ public enum TestSByteEnum : sbyte {
Name = "Can process int32[] type 'fhx -InputObject [int32[]](2032, 2033, 2034)'"
InputObject = [int32[]](2032, 2033, 2034)
Count = 1
- ExpectedResult = "00000000000000000000 F0 07 00 00 F1 07 00 00 F2 07 00 00 ð...ñ...ò..."
+ ExpectedResult = "0000000000000000 F0 07 00 00 F1 07 00 00 F2 07 00 00 ð...ñ...ò..."
}
@{
Name = "Can process Int64 type 'fhx -InputObject [Int64]9223372036854775807'"
InputObject = [Int64]9223372036854775807
Count = 1
- ExpectedResult = "00000000000000000000 FF FF FF FF FF FF FF 7F ......."
+ ExpectedResult = "0000000000000000 FF FF FF FF FF FF FF 7F ÿÿÿÿÿÿÿ�"
}
@{
Name = "Can process Int64[] type 'fhx -InputObject [Int64[]](9223372036852,9223372036853)'"
InputObject = [Int64[]](9223372036852, 9223372036853)
Count = 1
- ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
+ ExpectedResult = "0000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
}
@{
Name = "Can process string type 'fhx -InputObject hello world'"
InputObject = "hello world"
Count = 1
- ExpectedResult = "00000000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
+ ExpectedResult = "0000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
}
@{
Name = "Can process PS-native enum array '[TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour') | fhx'"
InputObject = [TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour')
Count = 1
- ExpectedResult = "00000000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................"
+ ExpectedResult = "0000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................"
}
@{
Name = "Can process C#-native sbyte enum array '[TestSByteEnum[]]('One', 'Two', 'Three', 'Four') | fhx'"
InputObject = [TestSByteEnum[]]('One', 'Two', 'Three', 'Four')
Count = 1
- ExpectedResult = "00000000000000000000 FF FE FD FC .þýü"
+ ExpectedResult = "0000000000000000 FF FE FD FC .þýü"
}
)
@@ -156,78 +163,85 @@ public enum TestSByteEnum : sbyte {
Name = "Can process byte type '[byte]5 | fhx'"
InputObject = [byte]5
Count = 1
- ExpectedResult = "00000000000000000000 05"
+ ExpectedResult = "0000000000000000 05"
}
@{
Name = "Can process byte[] type '[byte[]](1,2) | fhx'"
InputObject = [byte[]](1, 2)
Count = 1
- ExpectedResult = "00000000000000000000 01 02 .."
+ ExpectedResult = "0000000000000000 01 02 ��"
}
@{
Name = "Can process int type '7 | fhx'"
InputObject = 7
Count = 1
- ExpectedResult = "00000000000000000000 07 00 00 00 ...."
+ ExpectedResult = "0000000000000000 07 00 00 00 � "
}
@{
Name = "Can process int[] type '[int[]](5,6) | fhx'"
InputObject = [int[]](5, 6)
Count = 1
- ExpectedResult = "00000000000000000000 05 00 00 00 06 00 00 00 ........"
+ ExpectedResult = "0000000000000000 05 00 00 00 06 00 00 00 � � "
}
@{
Name = "Can process int32 type '[int32]2032 | fhx'"
InputObject = [int32]2032
Count = 1
- ExpectedResult = "00000000000000000000 F0 07 00 00 ð..."
+ ExpectedResult = "0000000000000000 F0 07 00 00 ð� "
}
@{
Name = "Can process int32[] type '[int32[]](2032, 2033) | fhx'"
InputObject = [int32[]](2032, 2033)
Count = 1
- ExpectedResult = "00000000000000000000 F0 07 00 00 F1 07 00 00 ð...ñ..."
+ ExpectedResult = "0000000000000000 F0 07 00 00 F1 07 00 00 ð� ñ� "
}
@{
Name = "Can process Int64 type '[Int64]9223372036854775807 | fhx'"
InputObject = [Int64]9223372036854775807
Count = 1
- ExpectedResult = "00000000000000000000 FF FF FF FF FF FF FF 7F ......."
+ ExpectedResult = "0000000000000000 FF FF FF FF FF FF FF 7F ÿÿÿÿÿÿÿ�"
}
@{
Name = "Can process Int64[] type '[Int64[]](9223372036852,9223372036853) | fhx'"
InputObject = [Int64[]](9223372036852, 9223372036853)
Count = 1
- ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
+ ExpectedResult = "0000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c� õZÐ{c� "
}
@{
Name = "Can process string type 'hello world | fhx'"
InputObject = "hello world"
Count = 1
- ExpectedResult = "00000000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
+ ExpectedResult = "0000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
+ }
+ @{
+ Name = "Can process string type amidst other types { 1, 2, 3, 'hello world' | fhx }"
+ InputObject = 1, 2, 3, "hello world"
+ Count = 2
+ ExpectedResult = "0000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 � � � "
+ ExpectedSecondResult = "0000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
}
@{
Name = "Can process jagged array type '[sbyte[]](-15, 18, 21, -5), [byte[]](1, 2, 3, 4, 5, 6) | fhx'"
InputObject = [sbyte[]](-15, 18, 21, -5), [byte[]](1, 2, 3, 4, 5, 6)
Count = 2
- ExpectedResult = "00000000000000000000 F1 12 15 FB ñ..û"
- ExpectedSecondResult = "00000000000000000000 01 02 03 04 05 06 ......"
+ ExpectedResult = "0000000000000000 F1 12 15 FB ñ��û"
+ ExpectedSecondResult = "0000000000000000 01 02 03 04 05 06 ������"
}
@{
Name = "Can process PS-native enum array '[TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour') | fhx'"
InputObject = [TestEnum[]]('TestOne', 'TestTwo', 'TestThree', 'TestFour')
Count = 1
- ExpectedResult = "00000000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ................"
+ ExpectedResult = "0000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 � � � � "
}
@{
Name = "Can process C#-native sbyte enum array '[TestSByteEnum[]]('One', 'Two', 'Three', 'Four') | fhx'"
InputObject = [TestSByteEnum[]]('One', 'Two', 'Three', 'Four')
Count = 1
- ExpectedResult = "00000000000000000000 FF FE FD FC .þýü"
+ ExpectedResult = "0000000000000000 FF FE FD FC ÿþýü"
}
)
- It "" -Testcase $testCases {
+ It "" -TestCases $testCases {
param ($Name, $InputObject, $Count, $ExpectedResult, $ExpectedSecondResult)
@@ -241,6 +255,56 @@ public enum TestSByteEnum : sbyte {
$result[1].ToString() | Should -MatchExactly $ExpectedSecondResult
}
}
+
+ $heterogenousInputCases = @(
+ @{
+ InputScript = { [sbyte[]](-15, 18, 21, -5), "hello", [byte[]](1..6), 1, 2, 3, 4 }
+ Count = 4
+ ExpectedResults = @(
+ "0000000000000000 F1 12 15 FB ñ��û"
+ "0000000000000000 68 65 6C 6C 6F hello"
+ "0000000000000000 01 02 03 04 05 06 ������"
+ "0000000000000000 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 � � � � "
+ )
+ ExpectedLabels = @(
+ "System.SByte[]"
+ "System.String"
+ "System.Byte"
+ "System.Int32"
+ ).ForEach{ [regex]::Escape($_) } -join '|'
+ }
+ @{
+ InputScript = { $inputFile1, "Mountains are merely mountains", 1, 4, 5, 3, [ushort[]](1..10) }
+ Count = 6
+ ExpectedResults = @(
+ "0000000000000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 Hello World"
+ "0000000000000000 4D 6F 75 6E 74 61 69 6E 73 20 61 72 65 20 6D 65 Mountains are me"
+ "0000000000000010 72 65 6C 79 20 6D 6F 75 6E 74 61 69 6E 73 rely mountains"
+ "0000000000000000 01 00 00 00 04 00 00 00 05 00 00 00 03 00 00 00 � � � � "
+ "0000000000000000 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 � � � � � � � � "
+ "0000000000000010 09 00 0A 00 � � "
+ )
+ ExpectedLabels = @(
+ $inputFile1.FullName
+ "System.String"
+ "System.Int32"
+ "System.UInt16[]"
+ ).ForEach{ [regex]::Escape($_) } -join '|'
+ }
+ )
+
+ It 'can process jagged input: ' -TestCases $heterogenousInputCases {
+ param($InputScript, $Count, $ExpectedResults, $ExpectedLabels)
+
+ $Results = & $InputScript | Format-Hex
+ $Results | Should -HaveCount $Count
+ $ExpectedResults | Should -HaveCount $Count
+
+ for ($Number = 0; $Number -lt $Results.Count; $Number++) {
+ $Results[$Number] | Should -MatchExactly $ExpectedResults[$Number]
+ $Results[$Number].Label | Should -MatchExactly $ExpectedLabels
+ }
+ }
}
Context "Path and LiteralPath Parameters" {
@@ -330,37 +394,38 @@ public enum TestSByteEnum : sbyte {
Name = "Can process ASCII encoding 'fhx -InputObject 'hello' -Encoding ASCII'"
Encoding = "ASCII"
Count = 1
- ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
+ ExpectedResult = "0000000000000000 68 65 6C 6C 6F hello"
}
@{
Name = "Can process BigEndianUnicode encoding 'fhx -InputObject 'hello' -Encoding BigEndianUnicode'"
Encoding = "BigEndianUnicode"
Count = 1
- ExpectedResult = "00000000000000000000 00 68 00 65 00 6C 00 6C 00 6F .h.e.l.l.o"
+ ExpectedResult = "0000000000000000 00 68 00 65 00 6C 00 6C 00 6F h e l l o"
}
@{
Name = "Can process Unicode encoding 'fhx -InputObject 'hello' -Encoding Unicode'"
Encoding = "Unicode"
Count = 1
- ExpectedResult = "00000000000000000000 68 00 65 00 6C 00 6C 00 6F 00 h.e.l.l.o."
+ ExpectedResult = "0000000000000000 68 00 65 00 6C 00 6C 00 6F 00 h e l l o "
}
@{
Name = "Can process UTF7 encoding 'fhx -InputObject 'hello' -Encoding UTF7'"
Encoding = "UTF7"
Count = 1
- ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
+ ExpectedResult = "0000000000000000 68 65 6C 6C 6F hello"
}
@{
Name = "Can process UTF8 encoding 'fhx -InputObject 'hello' -Encoding UTF8'"
Encoding = "UTF8"
Count = 1
- ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
+ ExpectedResult = "0000000000000000 68 65 6C 6C 6F hello"
}
@{
- Name = "Can process UTF32 encoding 'fhx -InputObject 'hello' -Encoding UTF32'"
- Encoding = "UTF32"
- Count = 1
- ExpectedResult = "00000000000000000000 68 00 00 00 65 00 00 00 6C 00 00 00 6C 00 00 00 h...e...l...l...$($newline)00000000000000000010 6F 00 00 00 o..."
+ Name = "Can process UTF32 encoding 'fhx -InputObject 'hello' -Encoding UTF32'"
+ Encoding = "UTF32"
+ Count = 2
+ ExpectedResult = "0000000000000000 68 00 00 00 65 00 00 00 6C 00 00 00 6C 00 00 00 h e l l "
+ ExpectedSecondResult = "0000000000000010 6F 00 00 00 o "
}
)
@@ -408,155 +473,155 @@ public enum TestSByteEnum : sbyte {
$result = Format-Hex -InputObject $InputObject -ErrorAction Stop
}
} | Should -Throw -ErrorId $ExpectedFullyQualifiedErrorId
+ }
}
-}
-Context "Continues to Process Valid Paths" {
+ Context "Continues to Process Valid Paths" {
- $testCases = @(
- @{
- Name = "If given invalid path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- PathCase = $true
- InvalidPath = "$($inputFile1.DirectoryName)\fakefile8888845345345348709.txt"
- ExpectedFullyQualifiedErrorId = "FileNotFound,Microsoft.PowerShell.Commands.FormatHex"
- }
- @{
- Name = "If given a non FileSystem path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- PathCase = $true
- InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
- ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
- }
- @{
- Name = "If given a non FileSystem path in array (with LiteralPath), continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
- InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
- ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
- }
- )
+ $testCases = @(
+ @{
+ Name = "If given invalid path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ PathCase = $true
+ InvalidPath = "$($inputFile1.DirectoryName)\fakefile8888845345345348709.txt"
+ ExpectedFullyQualifiedErrorId = "FileNotFound,Microsoft.PowerShell.Commands.FormatHex"
+ }
+ @{
+ Name = "If given a non FileSystem path in array, continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ PathCase = $true
+ InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
+ ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
+ }
+ @{
+ Name = "If given a non FileSystem path in array (with LiteralPath), continues to process valid paths 'fhx -Path `$invalidPath, `$inputFile1 -ErrorVariable e -ErrorAction SilentlyContinue'"
+ InvalidPath = "Cert:\CurrentUser\My\$thumbprint"
+ ExpectedFullyQualifiedErrorId = "FormatHexOnlySupportsFileSystemPaths,Microsoft.PowerShell.Commands.FormatHex"
+ }
+ )
- It "" -Skip:$skipTest -TestCase $testCases {
+ It "" -Skip:$skipTest -TestCase $testCases {
- param ($Name, $PathCase, $InvalidPath, $ExpectedFullyQualifiedErrorId)
+ param ($Name, $PathCase, $InvalidPath, $ExpectedFullyQualifiedErrorId)
- $output = $null
- $errorThrown = $null
+ $output = $null
+ $errorThrown = $null
- if ($PathCase) {
- $output = Format-Hex -Path $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
- }
- else {
- # LiteralPath
- $output = Format-Hex -LiteralPath $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
- }
+ if ($PathCase) {
+ $output = Format-Hex -Path $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
+ }
+ else {
+ # LiteralPath
+ $output = Format-Hex -LiteralPath $InvalidPath, $inputFile1 -ErrorVariable errorThrown -ErrorAction SilentlyContinue
+ }
- $errorThrown.FullyQualifiedErrorId | Should -MatchExactly $ExpectedFullyQualifiedErrorId
+ $errorThrown.FullyQualifiedErrorId | Should -MatchExactly $ExpectedFullyQualifiedErrorId
- $output.Length | Should -Be 1
- $output[0].ToString() | Should -MatchExactly $inputText1
+ $output.Length | Should -Be 1
+ $output[0].ToString() | Should -MatchExactly $inputText1
+ }
}
-}
-Context "Cmdlet Functionality" {
+ Context "Cmdlet Functionality" {
- It "Path is default Parameter Set 'fhx `$inputFile1'" {
+ It "Path is default Parameter Set 'fhx `$inputFile1'" {
- $result = Format-Hex $inputFile1
+ $result = Format-Hex $inputFile1
- $result | Should -Not -BeNullOrEmpty
- , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $actualResult = $result.ToString()
- $actualResult | Should -MatchExactly $inputText1
- }
+ $result | Should -Not -BeNullOrEmpty
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ $actualResult = $result.ToString()
+ $actualResult | Should -MatchExactly $inputText1
+ }
- It "Validate file input from Pipeline 'Get-ChildItem `$inputFile1 | Format-Hex'" {
+ It "Validate file input from Pipeline 'Get-ChildItem `$inputFile1 | Format-Hex'" {
- $result = Get-ChildItem $inputFile1 | Format-Hex
+ $result = Get-ChildItem $inputFile1 | Format-Hex
- $result | Should -Not -BeNullOrEmpty
- , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $actualResult = $result.ToString()
- $actualResult | Should -MatchExactly $inputText1
- }
+ $result | Should -Not -BeNullOrEmpty
+ , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ $actualResult = $result.ToString()
+ $actualResult | Should -MatchExactly $inputText1
+ }
- It "Validate that streamed text does not have buffer underrun problems ''a' * 30 | Format-Hex'" {
+ It "Validate that streamed text does not have buffer underrun problems ''a' * 30 | Format-Hex'" {
- $result = "a" * 30 | Format-Hex
+ $result = "a" * 30 | Format-Hex
- $result | Should -Not -BeNullOrEmpty
- , $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $result.ToString() | Should -MatchExactly "00000000000000000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa$($newline)00000000000000000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
+ $result[0].ToString() | Should -MatchExactly "0000000000000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa"
+ $result[1].ToString() | Should -MatchExactly "0000000000000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
+ }
- It "Validate that files do not have buffer underrun problems 'Format-Hex -Path `$InputFile4'" {
+ It "Validate that files do not have buffer underrun problems 'Format-Hex -Path `$InputFile4'" {
- $result = Format-Hex -Path $InputFile4
+ $result = Format-Hex -Path $InputFile4
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "0000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "0000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "0000000000000020 65 6E 74 ent "
+ }
}
-}
-Context "Count and Offset parameters" {
- It "Count = length" {
+ Context "Count and Offset parameters" {
+ It "Count = length" {
- $result = Format-Hex -Path $InputFile4 -Count $inputText4.Length
+ $result = Format-Hex -Path $InputFile4 -Count $inputText4.Length
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
- }
-
- It "Count = 1" {
- $result = Format-Hex -Path $inputFile4 -Count 1
- $result.ToString() | Should -MatchExactly "00000000000000000000 4E N "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "0000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "0000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "0000000000000020 65 6E 74 ent "
+ }
- It "Offset = length" {
+ It "Count = 1" {
+ $result = Format-Hex -Path $inputFile4 -Count 1
+ $result.ToString() | Should -MatchExactly "0000000000000000 4E N "
+ }
- $result = Format-Hex -Path $InputFile4 -Offset $inputText4.Length
- $result | Should -BeNullOrEmpty
+ It "Offset = length" {
+ $result = Format-Hex -Path $InputFile4 -Offset $inputText4.Length
+ $result | Should -BeNullOrEmpty
- $result = Format-Hex -InputObject $inputText4 -Offset $inputText4.Length
- $result.Bytes | Should -HaveCount 0
- }
+ $result = Format-Hex -InputObject $inputText4 -Offset $inputText4.Length
+ $result | Should -BeNullOrEmpty
+ }
- It "Offset = 1" {
+ It "Offset = 1" {
- $result = Format-Hex -Path $InputFile4 -Offset 1
+ $result = Format-Hex -Path $InputFile4 -Offset 1
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000001 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 72 ow is the winter"
- $result[1].ToString() | Should -MatchExactly "00000000000000000011 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 65 of our disconte"
- $result[2].ToString() | Should -MatchExactly "00000000000000000021 6E 74 nt "
- }
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "0000000000000001 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 72 ow is the winter"
+ $result[1].ToString() | Should -MatchExactly "0000000000000011 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 65 of our disconte"
+ $result[2].ToString() | Should -MatchExactly "0000000000000021 6E 74 nt "
+ }
- It "Count = 1 and Offset = 1" {
- $result = Format-Hex -Path $inputFile4 -Count 1 -Offset 1
- $result.ToString() | Should -MatchExactly "00000000000000000001 6F o "
- }
+ It "Count = 1 and Offset = 1" {
+ $result = Format-Hex -Path $inputFile4 -Count 1 -Offset 1
+ $result.ToString() | Should -MatchExactly "0000000000000001 6F o "
+ }
- It "Count should be > 0" {
- { Format-Hex -Path $inputFile4 -Count 0 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
- }
+ It "Count should be > 0" {
+ { Format-Hex -Path $inputFile4 -Count 0 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
+ }
- It "Offset should be >= 0" {
- { Format-Hex -Path $inputFile4 -Offset -1 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
- }
+ It "Offset should be >= 0" {
+ { Format-Hex -Path $inputFile4 -Offset -1 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
+ }
- It "Offset = 0" {
+ It "Offset = 0" {
- $result = Format-Hex -Path $InputFile4 -Offset 0
+ $result = Format-Hex -Path $InputFile4 -Offset 0
- $result | Should -Not -BeNullOrEmpty
- $result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "0000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "0000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "0000000000000020 65 6E 74 ent "
+ }
}
}
-}
From e12caad8c8fe2cd2ebc365e96e49ae4ff79d9c9a Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Wed, 9 Oct 2019 21:22:58 -0400
Subject: [PATCH 26/28] :art: Set fixed width for the random ID
---
.../commands/utility/FormatAndOutput/format-hex/Format-Hex.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 1ba4a6bdf57..25c1a94b05c 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -295,7 +295,7 @@ private void ProcessString(string originalString)
private static readonly Random _idGenerator = new Random();
private string GetGroupLabel(Type inputType)
{
- return string.Format("{0} ({1}) <{2:X}>", inputType.Name, inputType.FullName, _idGenerator.Next());
+ return string.Format("{0} ({1}) <{2:X8}>", inputType.Name, inputType.FullName, _idGenerator.Next());
}
private void FlushInputBuffer()
From feb5d57666f35767edb24085c2a6dc36441501f3 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Thu, 10 Oct 2019 00:05:43 -0400
Subject: [PATCH 27/28] :art: Codacy/CodeFactor fixes
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 6 ++----
.../commands/utility/UtilityCommon.cs | 19 ++++++++++---------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 25c1a94b05c..1ec136f0923 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -293,10 +293,8 @@ private void ProcessString(string originalString)
}
private static readonly Random _idGenerator = new Random();
- private string GetGroupLabel(Type inputType)
- {
- return string.Format("{0} ({1}) <{2:X8}>", inputType.Name, inputType.FullName, _idGenerator.Next());
- }
+ private static string GetGroupLabel(Type inputType)
+ => string.Format("{0} ({1}) <{2:X8}>", inputType.Name, inputType.FullName, _idGenerator.Next());
private void FlushInputBuffer()
{
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index ee9aa173d08..f3c9d86a8e9 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -95,7 +95,7 @@ public static class UtilityResources
public class ByteCollection
{
///
- /// ByteCollection constructor.
+ /// Initializes a new instance of the class.
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
@@ -107,7 +107,7 @@ public ByteCollection(uint offset, byte[] value, string path)
}
///
- /// Initializes a new instance of ByteCollection.
+ /// Initializes a new instance of the class.
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
@@ -126,7 +126,7 @@ public ByteCollection(ulong offset, byte[] value, string path)
}
///
- /// ByteCollection constructor.
+ /// Initializes a new instance of the class.
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
@@ -137,7 +137,7 @@ public ByteCollection(uint offset, byte[] value)
}
///
- /// ByteCollection constructor.
+ /// Initializes a new instance of the class.
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
@@ -153,14 +153,13 @@ public ByteCollection(ulong offset, byte[] value)
}
///
- /// ByteCollection constructor.
+ /// Initializes a new instance of the class.
///
/// The Offset address to be used while displaying the bytes in the collection.
- /// Underlying bytes stored in the collection.
///
- /// The label for the byte group. This may be a file path, a string value, or a
- /// formatted identifying string for the group.
+ /// The label for the byte group. This may be a file path or a formatted identifying string for the group.
///
+ /// Underlying bytes stored in the collection.
public ByteCollection(ulong offset, string label, byte[] value)
: this(offset, value)
{
@@ -168,7 +167,7 @@ public ByteCollection(ulong offset, string label, byte[] value)
}
///
- /// ByteCollection constructor.
+ /// Initializes a new instance of the class.
///
/// Underlying bytes stored in the collection.
public ByteCollection(byte[] value)
@@ -227,6 +226,7 @@ private set
private const int BytesPerLine = 16;
private string _hexBytes = string.Empty;
+
///
/// Gets a space-delimited string of the in this
/// in hexadecimal format.
@@ -252,6 +252,7 @@ public string HexBytes
}
private string _ascii = string.Empty;
+
///
/// Gets the ASCII string representation of the in this .
///
From a2ae1684bd8e523fb3c2e17d273d75b16ced8059 Mon Sep 17 00:00:00 2001
From: vexx32 <32407840+vexx32@users.noreply.github.com>
Date: Sat, 12 Oct 2019 00:45:56 -0400
Subject: [PATCH 28/28] :art: Use consistent param naming
---
.../FormatAndOutput/format-hex/Format-Hex.cs | 27 +++++--------------
1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 1ec136f0923..810534a9ffd 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -122,20 +122,7 @@ protected override void ProcessRecord()
///
protected override void EndProcessing()
{
- if (_inputBuffer.Count > 0)
- {
- int offset = Math.Min(_inputBuffer.Count, Offset < int.MaxValue ? (int)Offset : int.MaxValue);
- int count = Math.Min(_inputBuffer.Count - offset, Count < int.MaxValue ? (int)Count : int.MaxValue);
-
- if (offset != 0 || count != _inputBuffer.Count)
- {
- WriteHexadecimal(_inputBuffer.GetRange(offset, count).ToArray(), 0, GetGroupLabel(_lastInputType));
- }
- else
- {
- WriteHexadecimal(_inputBuffer.ToArray(), 0, GetGroupLabel(_lastInputType));
- }
- }
+ FlushInputBuffer();
}
#endregion
@@ -284,7 +271,7 @@ private void ProcessString(string originalString)
if (offset != 0 || count != bytes.Length)
{
- WriteHexadecimal(bytes.Slice(offset, count), offset: 0, GetGroupLabel(typeof(string)));
+ WriteHexadecimal(bytes.Slice(offset, count), offset: 0, label: GetGroupLabel(typeof(string)));
}
else
{
@@ -310,15 +297,15 @@ private void FlushInputBuffer()
{
WriteHexadecimal(
_inputBuffer.GetRange(offset, count).ToArray(),
- label: GetGroupLabel(_lastInputType),
- offset: 0);
+ offset: 0,
+ label: GetGroupLabel(_lastInputType));
}
else
{
WriteHexadecimal(
_inputBuffer.ToArray(),
- label: GetGroupLabel(_lastInputType),
- offset: 0);
+ offset: 0,
+ label: GetGroupLabel(_lastInputType));
}
// Reset flags so we can go back to filling up the buffer when needed.
@@ -512,7 +499,7 @@ private void WriteHexadecimal(Span inputBytes, long offset, string label)
? inputBytes.Length - index
: bytesPerObject;
var bytes = inputBytes.Slice(index, count);
- WriteObject(new ByteCollection((ulong)index + (ulong)offset, bytes.ToArray(), label));
+ WriteObject(new ByteCollection((ulong)index + (ulong)offset, label, bytes.ToArray()));
}
}