fix(windows): drop no-op -ExecutionPolicy Bypass from -Command spawns (#17873)

* fix(windows): drop no-op -ExecutionPolicy Bypass from -Command spawns

Execution policy gates script *files* only; it has no effect on -Command.
Measured on Windows 11:

  powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Restricted \
    -Command "Write-Output 'COMMAND-RAN'"   -> COMMAND-RAN, exit 0

So the switch bought nothing on these two call sites while contributing the
highest-weighted token on the command lines Defender for Endpoint flags.

Font enumeration returns a byte-identical family list with and without the
switch (182 families, matching SHA-256), and the ACL script's argv behaves
identically either way.

Tests now assert the argv carries no -ExecutionPolicy/Bypass, and the
secure-file assertions derive the script position from -Command instead of a
fixed index so they cannot rot the next time the switch list moves.

* refactor(windows): tighten -Command argv assertions and comments

Review follow-ups on the -ExecutionPolicy Bypass removal:

- powershellScriptArgs asserts the -Command anchor before slicing, so a
  -Command -> -File swap names the switch shape that moved instead of
  surfacing as a path mismatch several asserts later.
- Collapse both no-op rationale comments to one line per AGENTS.md.

---------

Co-authored-by: Orca Worker <orca-worker@localhost>
This commit is contained in:
OrcaWin
2026-09-05 21:54:37 -07:00
committed by GitHub
co-authored by Orca Worker
parent bdad20b4c1
commit 8b88b3b60a
2 changed files with 18 additions and 1 deletions
+16
View File
@@ -70,6 +70,22 @@ describe('listSystemFontFamilies', () => {
})
})
it('spawns the Windows font script without an -ExecutionPolicy switch', async () => {
// Why: execution policy gates script *files*, never -Command, so the switch
// was a no-op -- and it is the highest-weighted token on the command lines
// Defender flags (#17858).
await withPlatform('win32', async () => {
runProcessMock.mockResolvedValue(ok('Consolas\n'))
const { listSystemFontFamilies } = await import('./system-fonts')
await listSystemFontFamilies()
const args = runProcessMock.mock.calls[0]?.[0].args ?? []
expect(args).toContain('-Command')
expect(args).not.toContain('-ExecutionPolicy')
expect(args).not.toContain('Bypass')
})
})
it('runs PowerShell by absolute path on Windows', async () => {
// Why: a bare `powershell.exe` resolves against the child's PATH, which is
// not the user's under Electron. Where policy has pruned the System32 entry
+2 -1
View File
@@ -89,7 +89,8 @@ $fonts.Families | ForEach-Object { $_.Name }
return execFileText(
windowsPowerShellPath(),
['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', script],
// Why: policy gates script *files*, not -Command, so the switch was a Defender-weighted no-op.
['-NoProfile', '-NonInteractive', '-Command', script],
8 * 1024 * 1024
).then((output) =>
uniqueSorted(