From 67cf61e4bed8a7f2719aa605c045f3ef01e10dc5 Mon Sep 17 00:00:00 2001 From: Joseph Yaksich Date: Wed, 5 Aug 2026 05:19:58 +0000 Subject: [PATCH] fix(phase4): execute Windows WSL scripts without BOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PowerShell 5 adds a UTF-8 BOM when piping text to wsl.exe, so bash received `test` as the first command. A non-login `bash -s` also omitted the installed node path. Write each command to a unique runner-temp script as UTF-8 without BOM, mount that file through /mnt, and execute it from a login shell. The exact transport passed under the real limited helm-ph4 account on VM 115 with an isolated WSL distribution, including nested substitutions and cleanup. Keep structural coverage for no-BOM file transport and login-shell execution. Co-Authored-By: Claude --- ops/platform-acceptance/windows.ps1 | 21 +++++++++++++++------ test/phase4-platform-acceptance.mjs | 5 ++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ops/platform-acceptance/windows.ps1 b/ops/platform-acceptance/windows.ps1 index 17ef2d8..becae29 100644 --- a/ops/platform-acceptance/windows.ps1 +++ b/ops/platform-acceptance/windows.ps1 @@ -29,12 +29,21 @@ function Get-Distros { return @($raw -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ }) } function Invoke-Distro([string] $Command) { - # PowerShell 5 re-quotes native command arguments before invoking wsl.exe. - # That mangles bash substitutions and nested quotes even when the - # PowerShell string itself is literal. Send the script over stdin instead; - # this preserves the exact bytes and was proven under the real runner user. - $Command | & $Wsl -d $Distro -u root --exec /bin/bash -s | Out-Host - if ($LASTEXITCODE -ne 0) { Refuse "in-distribution command failed: $Command" } + # PowerShell 5 either re-quotes native arguments or adds a BOM when piping + # text to wsl.exe. Write exact UTF-8 without a BOM to the runner temp mount, + # then execute it from a login shell so the installed node path is present. + $tempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP } + $script = Join-Path $tempRoot ("1helm-distro-{0}.sh" -f [guid]::NewGuid().ToString('N')) + $encoding = New-Object System.Text.UTF8Encoding($false) + [IO.File]::WriteAllText($script, $Command + "`n", $encoding) + $drive = $script.Substring(0, 1).ToLowerInvariant() + $scriptInDistro = "/mnt/$drive/" + ($script.Substring(3) -replace '\\', '/') + try { + & $Wsl -d $Distro -u root --exec /bin/bash -lc "bash '$scriptInDistro'" | Out-Host + if ($LASTEXITCODE -ne 0) { Refuse "in-distribution command failed: $Command" } + } finally { + Remove-Item $script -Force -ErrorAction SilentlyContinue + } } function Assert-DistroVersion([string] $ExpectedVersion) { if ($ExpectedVersion -notmatch '^\d+\.\d+\.\d+$') { Refuse 'expected distribution version is invalid' } diff --git a/test/phase4-platform-acceptance.mjs b/test/phase4-platform-acceptance.mjs index 90e16af..e063a2f 100644 --- a/test/phase4-platform-acceptance.mjs +++ b/test/phase4-platform-acceptance.mjs @@ -212,7 +212,10 @@ test("Windows code publishes no artifact/signing claim and requires honest reboo assert.match(windows, /apply-linux-release\.sh/); assert.match(windows, /function Assert-DistroVersion/); assert.equal((windows.match(/Assert-DistroVersion \$(?:Version|PreviousVersion)/g) || []).length, 4); - assert.match(windows, /\$Command \| & \$Wsl -d \$Distro -u root --exec \/bin\/bash -s/); + assert.match(windows, /UTF8Encoding\(\$false\)/); + assert.match(windows, /\[IO\.File\]::WriteAllText/); + assert.match(windows, /\/bin\/bash -lc "bash '\$scriptInDistro'"/); + assert.doesNotMatch(windows, /\$Command \| & \$Wsl/); assert.doesNotMatch(windows, /\/bin\/bash -lc \$Command/); assert.doesNotMatch(windows, /Invoke-Distro "test .*systemctl/); assert.match(windows, /LocalRootfs/);