Skip to content

Commit a072d19

Browse files
committed
feat: add -Encoding parameter to MemoryStream string functions (Issue #21)
- Add -Encoding parameter to ConvertFrom-MemoryStreamToString - Add -Encoding parameter to ConvertFrom-MemoryStreamToSecureString - Pass -Encoding through in ConvertFrom-MemoryStream for consistency - Update tests to use correct encoding when creating streams - Update documentation and CHANGELOG
1 parent 4d85c3f commit a072d19

9 files changed

Lines changed: 243 additions & 11 deletions

docs/CHANGELOG.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Changelog
22

3-
## Version v2.0.0-alpha
3+
## Version v2.0.4-alpha
44

55
### Breaking Changes
66

@@ -11,6 +11,23 @@
1111
* **Removed Aliases**:
1212
* `Get-Hash` - Use `ConvertTo-Hash` directly instead
1313

14+
### New Features
15+
16+
* **Added `-Encoding` parameter** to `ConvertFrom-MemoryStreamToString` (Issue #21)
17+
* **Added `-Encoding` parameter** to `ConvertFrom-MemoryStreamToSecureString` (Issue #21)
18+
* **Added pipeline support** to `ConvertFrom-Base64ToByteArray` (Issue #16)
19+
* **Added pipeline support** to `ConvertFrom-ByteArrayToMemoryStream` (Issue #16)
20+
21+
### Changed
22+
23+
* **Consolidated `-MemoryStream` parameter** into `-Stream` for `ConvertFrom-MemoryStreamToString` and `ConvertTo-String` (Issue #17)
24+
* `-MemoryStream` is now an alias for `-Stream` for backward compatibility
25+
26+
### Fixed
27+
28+
* `ConvertFrom-MemoryStream` now correctly passes `-Encoding` parameter to `ConvertFrom-MemoryStreamToString` for consistent behavior
29+
* `ConvertFrom-Base64ToString` and `ConvertTo-String` now handle binary data correctly (Issue #14)
30+
1431
## Version v1.5.0 (2023-03-17)
1532

1633
* **New Functions**:

docs/functions/ConvertFrom-MemoryStreamToSecureString.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ Converts a Memory Stream to a Secure String
1414

1515
### MemoryStream (Default)
1616
```
17-
ConvertFrom-MemoryStreamToSecureString -MemoryStream <MemoryStream[]> [-ProgressAction <ActionPreference>]
17+
ConvertFrom-MemoryStreamToSecureString -MemoryStream <MemoryStream[]> [-Encoding <String>] [-ProgressAction <ActionPreference>]
1818
[<CommonParameters>]
1919
```
2020

2121
### Stream
2222
```
23-
ConvertFrom-MemoryStreamToSecureString -Stream <Stream[]> [-ProgressAction <ActionPreference>]
23+
ConvertFrom-MemoryStreamToSecureString -Stream <Stream[]> [-Encoding <String>] [-ProgressAction <ActionPreference>]
2424
[<CommonParameters>]
2525
```
2626

@@ -72,6 +72,23 @@ Accept pipeline input: True (ByPropertyName)
7272
Accept wildcard characters: False
7373
```
7474
75+
### -Encoding
76+
The encoding to use for conversion.
77+
Defaults to UTF8.
78+
Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, and UTF8.
79+
80+
```yaml
81+
Type: String
82+
Parameter Sets: (All)
83+
Aliases:
84+
85+
Required: False
86+
Position: Named
87+
Default value: UTF8
88+
Accept pipeline input: False
89+
Accept wildcard characters: False
90+
```
91+
7592
### -ProgressAction
7693
{{ Fill ProgressAction Description }}
7794

docs/functions/ConvertFrom-MemoryStreamToString.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ Converts MemoryStream to a string.
1414

1515
### MemoryStream
1616
```
17-
ConvertFrom-MemoryStreamToString -MemoryStream <MemoryStream[]> [-ProgressAction <ActionPreference>]
17+
ConvertFrom-MemoryStreamToString -MemoryStream <MemoryStream[]> [-Encoding <String>] [-ProgressAction <ActionPreference>]
1818
[<CommonParameters>]
1919
```
2020

2121
### Stream
2222
```
23-
ConvertFrom-MemoryStreamToString -Stream <Stream[]> [-ProgressAction <ActionPreference>] [<CommonParameters>]
23+
ConvertFrom-MemoryStreamToString -Stream <Stream[]> [-Encoding <String>] [-ProgressAction <ActionPreference>]
24+
[<CommonParameters>]
2425
```
2526

2627
## DESCRIPTION
@@ -126,6 +127,23 @@ Accept pipeline input: True (ByPropertyName)
126127
Accept wildcard characters: False
127128
```
128129
130+
### -Encoding
131+
The encoding to use for conversion.
132+
Defaults to UTF8.
133+
Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, and UTF8.
134+
135+
```yaml
136+
Type: String
137+
Parameter Sets: (All)
138+
Aliases:
139+
140+
Required: False
141+
Position: Named
142+
Default value: UTF8
143+
Accept pipeline input: False
144+
Accept wildcard characters: False
145+
```
146+
129147
### -ProgressAction
130148
{{ Fill ProgressAction Description }}
131149

src/Convert/Public/ConvertFrom-MemoryStream.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ function ConvertFrom-MemoryStream {
176176
process {
177177
foreach ($m in $MemoryStream) {
178178
try {
179-
$string = ConvertFrom-MemoryStreamToString -MemoryStream $m -ErrorAction Stop
179+
$string = ConvertFrom-MemoryStreamToString -MemoryStream $m -Encoding $Encoding -ErrorAction Stop
180180

181181
if ($ToString) {
182182
$string

src/Convert/Public/ConvertFrom-MemoryStreamToSecureString.ps1

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
.PARAMETER Stream
1212
A System.IO.Stream object for conversion.
1313
14+
.PARAMETER Encoding
15+
The encoding to use for conversion.
16+
Defaults to UTF8.
17+
Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, and UTF8.
18+
1419
.EXAMPLE
1520
$string = 'My Super Secret Value'
1621
$bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
@@ -47,7 +52,11 @@ function ConvertFrom-MemoryStreamToSecureString {
4752
ParameterSetName = 'Stream')]
4853
[ValidateNotNullOrEmpty()]
4954
[System.IO.Stream[]]
50-
$Stream
55+
$Stream,
56+
57+
[ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF8')]
58+
[String]
59+
$Encoding = 'UTF8'
5160
)
5261

5362
begin {
@@ -67,7 +76,8 @@ function ConvertFrom-MemoryStreamToSecureString {
6776
foreach ($object in $inputObject) {
6877
try {
6978
$secureString = [System.Security.SecureString]::new()
70-
$reader = [System.IO.StreamReader]::new($object)
79+
$enc = [System.Text.Encoding]::$Encoding
80+
$reader = [System.IO.StreamReader]::new($object, $enc)
7181

7282
while ($reader.Peek() -ge 0) {
7383
$secureString.AppendChar($reader.Read())

src/Convert/Public/ConvertFrom-MemoryStreamToString.ps1

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
.PARAMETER Stream
99
A System.IO.Stream object for conversion. Accepts any stream type including MemoryStream, FileStream, etc.
1010
11+
.PARAMETER Encoding
12+
The encoding to use for conversion.
13+
Defaults to UTF8.
14+
Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, and UTF8.
15+
1116
.EXAMPLE
1217
$string = 'A string'
1318
$stream = [System.IO.MemoryStream]::new()
@@ -85,7 +90,11 @@ function ConvertFrom-MemoryStreamToString {
8590
[ValidateNotNullOrEmpty()]
8691
[Alias('MemoryStream')]
8792
[System.IO.Stream[]]
88-
$Stream
93+
$Stream,
94+
95+
[ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF8')]
96+
[String]
97+
$Encoding = 'UTF8'
8998
)
9099

91100
begin {
@@ -98,7 +107,8 @@ function ConvertFrom-MemoryStreamToString {
98107
if ($object.CanSeek) {
99108
$object.Position = 0
100109
}
101-
$reader = [System.IO.StreamReader]::new($object)
110+
$enc = [System.Text.Encoding]::$Encoding
111+
$reader = [System.IO.StreamReader]::new($object, $enc)
102112
$reader.ReadToEnd()
103113
} catch {
104114
Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference

src/Tests/Unit/ConvertFrom-MemoryStream.Tests.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ Describe -Name $function -Fixture {
3939
$string = 'ThisIsMyString'
4040

4141
$stream = [System.IO.MemoryStream]::new()
42-
$writer = [System.IO.StreamWriter]::new($stream)
42+
$enc = [System.Text.Encoding]::$Encoding
43+
$writer = [System.IO.StreamWriter]::new($stream, $enc)
4344
$writer.Write($string)
4445
$writer.Flush()
4546

src/Tests/Unit/ConvertFrom-MemoryStreamToSecureString.Tests.ps1

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,63 @@ Describe $function {
2424
It 'Does not throw an exception when input is an empty System.IO.MemoryStream' {
2525
{ ConvertFrom-MemoryStreamToSecureString -MemoryStream (New-Object System.IO.MemoryStream) } | Should -Not -Throw
2626
}
27+
28+
Context 'Encoding' {
29+
It 'Uses UTF8 encoding by default' {
30+
$string = 'MySecretPassword'
31+
$bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
32+
$stream = [System.IO.MemoryStream]::new($bytes)
33+
34+
$secure = ConvertFrom-MemoryStreamToSecureString -MemoryStream $stream
35+
$credential = [PSCredential]::new('Dummy', $secure)
36+
$credential.GetNetworkCredential().Password | Should -BeExactly $string
37+
}
38+
39+
It 'Converts ASCII encoded stream to SecureString' {
40+
$string = 'MySecretPassword'
41+
$bytes = [System.Text.Encoding]::ASCII.GetBytes($string)
42+
$stream = [System.IO.MemoryStream]::new($bytes)
43+
44+
$secure = ConvertFrom-MemoryStreamToSecureString -MemoryStream $stream -Encoding ASCII
45+
$credential = [PSCredential]::new('Dummy', $secure)
46+
$credential.GetNetworkCredential().Password | Should -BeExactly $string
47+
}
48+
49+
It 'Converts Unicode encoded stream to SecureString' {
50+
$string = 'MySecretPassword'
51+
$bytes = [System.Text.Encoding]::Unicode.GetBytes($string)
52+
$stream = [System.IO.MemoryStream]::new($bytes)
53+
54+
$secure = ConvertFrom-MemoryStreamToSecureString -MemoryStream $stream -Encoding Unicode
55+
$credential = [PSCredential]::new('Dummy', $secure)
56+
$credential.GetNetworkCredential().Password | Should -BeExactly $string
57+
}
58+
59+
It 'Converts BigEndianUnicode encoded stream to SecureString' {
60+
$string = 'MySecretPassword'
61+
$bytes = [System.Text.Encoding]::BigEndianUnicode.GetBytes($string)
62+
$stream = [System.IO.MemoryStream]::new($bytes)
63+
64+
$secure = ConvertFrom-MemoryStreamToSecureString -MemoryStream $stream -Encoding BigEndianUnicode
65+
$credential = [PSCredential]::new('Dummy', $secure)
66+
$credential.GetNetworkCredential().Password | Should -BeExactly $string
67+
}
68+
69+
It 'Converts UTF32 encoded stream to SecureString' {
70+
$string = 'MySecretPassword'
71+
$bytes = [System.Text.Encoding]::UTF32.GetBytes($string)
72+
$stream = [System.IO.MemoryStream]::new($bytes)
73+
74+
$secure = ConvertFrom-MemoryStreamToSecureString -MemoryStream $stream -Encoding UTF32
75+
$credential = [PSCredential]::new('Dummy', $secure)
76+
$credential.GetNetworkCredential().Password | Should -BeExactly $string
77+
}
78+
79+
It 'Rejects invalid encoding name' {
80+
$bytes = [System.Text.Encoding]::UTF8.GetBytes('test')
81+
$stream = [System.IO.MemoryStream]::new($bytes)
82+
83+
{ ConvertFrom-MemoryStreamToSecureString -MemoryStream $stream -Encoding InvalidEncoding } | Should -Throw
84+
}
85+
}
2786
}

src/Tests/Unit/ConvertFrom-MemoryStreamToString.Tests.ps1

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,104 @@ Describe -Name $function -Fixture {
199199
$assertion.Exception.InnerException.Message | Should -BeIn @('Cannot access a closed Stream.', 'Stream was not readable.')
200200
}
201201
}
202+
203+
Context -Name 'Encoding' -Fixture {
204+
It -Name 'Uses UTF8 encoding by default' -Test {
205+
$string = 'Hello World'
206+
$bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
207+
$stream = [System.IO.MemoryStream]::new($bytes)
208+
209+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream
210+
211+
$assertion | Should -BeExactly $string
212+
$stream.Dispose()
213+
}
214+
215+
It -Name 'Converts ASCII encoded stream' -Test {
216+
$string = 'Hello World'
217+
$bytes = [System.Text.Encoding]::ASCII.GetBytes($string)
218+
$stream = [System.IO.MemoryStream]::new($bytes)
219+
220+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream -Encoding ASCII
221+
222+
$assertion | Should -BeExactly $string
223+
$stream.Dispose()
224+
}
225+
226+
It -Name 'Converts Unicode (UTF-16 LE) encoded stream' -Test {
227+
$string = 'Hello World'
228+
$bytes = [System.Text.Encoding]::Unicode.GetBytes($string)
229+
$stream = [System.IO.MemoryStream]::new($bytes)
230+
231+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream -Encoding Unicode
232+
233+
$assertion | Should -BeExactly $string
234+
$stream.Dispose()
235+
}
236+
237+
It -Name 'Converts BigEndianUnicode (UTF-16 BE) encoded stream' -Test {
238+
$string = 'Hello World'
239+
$bytes = [System.Text.Encoding]::BigEndianUnicode.GetBytes($string)
240+
$stream = [System.IO.MemoryStream]::new($bytes)
241+
242+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream -Encoding BigEndianUnicode
243+
244+
$assertion | Should -BeExactly $string
245+
$stream.Dispose()
246+
}
247+
248+
It -Name 'Converts UTF32 encoded stream' -Test {
249+
$string = 'Hello World'
250+
$bytes = [System.Text.Encoding]::UTF32.GetBytes($string)
251+
$stream = [System.IO.MemoryStream]::new($bytes)
252+
253+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream -Encoding UTF32
254+
255+
$assertion | Should -BeExactly $string
256+
$stream.Dispose()
257+
}
258+
259+
It -Name 'Converts UTF8 encoded stream explicitly' -Test {
260+
$string = 'Hello World'
261+
$bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
262+
$stream = [System.IO.MemoryStream]::new($bytes)
263+
264+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream -Encoding UTF8
265+
266+
$assertion | Should -BeExactly $string
267+
$stream.Dispose()
268+
}
269+
270+
It -Name 'Supports -Encoding with pipeline input' -Test {
271+
$string = 'Hello World'
272+
$bytes = [System.Text.Encoding]::Unicode.GetBytes($string)
273+
$stream = [System.IO.MemoryStream]::new($bytes)
274+
275+
$assertion = $stream | ConvertFrom-MemoryStreamToString -Encoding Unicode
276+
277+
$assertion | Should -BeExactly $string
278+
$stream.Dispose()
279+
}
280+
281+
It -Name 'Handles special characters with Unicode encoding' -Test {
282+
$string = 'Hello 世界 🌍'
283+
$bytes = [System.Text.Encoding]::Unicode.GetBytes($string)
284+
$stream = [System.IO.MemoryStream]::new($bytes)
285+
286+
$assertion = ConvertFrom-MemoryStreamToString -Stream $stream -Encoding Unicode
287+
288+
$assertion | Should -BeExactly $string
289+
$stream.Dispose()
290+
}
291+
292+
It -Name 'Rejects invalid encoding name' -Test {
293+
$string = 'Hello World'
294+
$bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
295+
$stream = [System.IO.MemoryStream]::new($bytes)
296+
297+
{ ConvertFrom-MemoryStreamToString -Stream $stream -Encoding InvalidEncoding } | Should -Throw
298+
299+
$stream.Dispose()
300+
}
301+
}
202302
}

0 commit comments

Comments
 (0)