Fix powershell generate save script

Summary

Closes #39427 (closed)

Fix ParserError: UnexpectedToken in get_sources.ps1 on Windows Kubernetes runner when CI_COMMIT_DESCRIPTION contains an em dash (U+2014).

Root cause

generateSaveScript in shells/powershell.go used:

$sw = [System.IO.StreamWriter]::new("path", $customEncoding)

PowerShell's method binder coerces the non-null Encoding argument to $True (boolean) and resolves the call to StreamWriter(String, Boolean) — append mode — rather than StreamWriter(String, Encoding). The resulting file is UTF-8 without a BOM.

On Windows, PowerShell reads BOM-less script files using the system code page (Windows-1252). The em dash U+2014 (UTF-8: E2 80 94) decodes as â€", where 0x94 in Windows-1252 is " (RIGHT DOUBLE QUOTATION MARK). That character terminates the double-quoted string mid-token, producing ParserError: UnexpectedToken in get_sources.ps1.

This affects the get_sources predefined stage, which runs in the helper container (not the build container). The helper image for runner 10.8.1 uses pwsh 7.4.6 on .NET 8 — the StreamWriter(String, Encoding) 2-arg overload exists on .NET 8, but PowerShell's binder still prefers the StreamWriter(String, Boolean) form because non-null objects coerce to $True.

Fix

Use the unambiguous 3-arg constructor:

$sw = [System.IO.StreamWriter]::new("path", $False, $customEncoding)

With explicit $False (no append) and $customEncoding there is no coercion ambiguity, the correct overload is always selected, and UTF8Encoding($True) writes a UTF-8 BOM so the encoding is detected correctly on all platforms.

Tests

  • Updated unit tests in TestPowershell_GenerateSaveScript to assert the 3-arg constructor form.
  • Added integration test TestPwsh_StreamWriterOverloadResolution that runs actual pwsh to prove the 2-arg form omits the BOM (broken) and the 3-arg form writes the BOM (fixed).

Merge request reports

Loading