Skip to content

Commit 1d213ef

Browse files
nohwndCopilot
andcommitted
Fix #2561: Escape control characters in assertion error messages
Format-String2 now escapes control characters as Unicode control pictures so they are visible in error messages. Characters like ESC (used in ANSI sequences) now display as their Unicode symbol instead of being invisible. Copilot-generated fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d5f7c87 commit 1d213ef

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

src/Format2.ps1

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,25 @@ function Format-Object2 ($Value, $Property, [switch]$Pretty) {
4646
}
4747

4848
function Format-String2 ($Value) {
49-
if ('' -eq $Value) {
49+
# Use .Length instead of '' -eq $Value because PowerShell's -eq operator
50+
# considers some control characters (NUL, BEL, BS, ESC) equal to empty string.
51+
if ($null -eq $Value -or $Value.Length -eq 0) {
5052
return '<empty>'
5153
}
5254

55+
# Escape control characters so they are visible in error messages.
56+
# Without this, chars like ESC (0x1B used in ANSI sequences) are invisible
57+
# and make error output confusing. See https://github.com/pester/Pester/issues/2561
58+
$Value = $Value `
59+
-replace "`0", '' `
60+
-replace "`a", '' `
61+
-replace "`b", '' `
62+
-replace "`t", '' `
63+
-replace "`f", '' `
64+
-replace "`r", '' `
65+
-replace "`n", '' `
66+
-replace "`e", ''
67+
5368
"'$Value'"
5469
}
5570

tst/Format2.Tests.ps1

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,5 +212,65 @@ InPesterModuleScope {
212212
It "Formats string to be sorrounded by quotes" {
213213
Format-String2 -Value "abc" | Verify-Equal "'abc'"
214214
}
215+
216+
# Regression tests for https://github.com/pester/Pester/issues/2561
217+
# Control characters must be escaped to Unicode control pictures so they are
218+
# visible in error messages instead of being invisible or breaking output.
219+
It "Escapes null character to control picture" {
220+
Format-String2 -Value "`0" | Verify-Equal "'`u{2400}'"
221+
}
222+
223+
It "Escapes bell character to control picture" {
224+
Format-String2 -Value "`a" | Verify-Equal "'`u{2407}'"
225+
}
226+
227+
It "Escapes backspace character to control picture" {
228+
Format-String2 -Value "`b" | Verify-Equal "'`u{2408}'"
229+
}
230+
231+
It "Escapes tab character to control picture" {
232+
Format-String2 -Value "`t" | Verify-Equal "'`u{2409}'"
233+
}
234+
235+
It "Escapes form feed character to control picture" {
236+
Format-String2 -Value "`f" | Verify-Equal "'`u{240C}'"
237+
}
238+
239+
It "Escapes carriage return character to control picture" {
240+
Format-String2 -Value "`r" | Verify-Equal "'`u{240D}'"
241+
}
242+
243+
It "Escapes newline character to control picture" {
244+
Format-String2 -Value "`n" | Verify-Equal "'`u{240A}'"
245+
}
246+
247+
It "Escapes ESC character to control picture" {
248+
Format-String2 -Value "$([char]27)" | Verify-Equal "'`u{241B}'"
249+
}
250+
251+
It "Leaves normal strings unchanged" {
252+
Format-String2 -Value "hello" | Verify-Equal "'hello'"
253+
}
254+
255+
It "Escapes ANSI sequence making escape char visible" {
256+
# ESC[31m is a common ANSI red color code; the ESC byte should become ␛
257+
$ansi = "$([char]27)[31m"
258+
$result = Format-String2 -Value $ansi
259+
$result | Verify-Equal "'`u{241B}[31m'"
260+
}
261+
262+
It "Escapes multiple control chars in one string" {
263+
$value = "a`t`nb"
264+
$result = Format-String2 -Value $value
265+
$result | Verify-Equal "'a`u{2409}`u{240A}b'"
266+
}
267+
268+
It "Escaped output contains no actual control characters" {
269+
# Round-trip: the escaped output should be a clean displayable string
270+
$value = "`0`a`b`t`f`r`n$([char]27)"
271+
$result = Format-String2 -Value $value
272+
# The result should not contain any of the original control characters
273+
$result | Should -Not -Match '[\x00-\x1F]'
274+
}
215275
}
216276
}

0 commit comments

Comments
 (0)