From ae703b1bcd5fc5527dacbb2780ceeec4a8b54af8 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Fri, 15 May 2026 02:21:18 +0200 Subject: [PATCH] fix(test-ipc-server): allow tilde in shell-arg paths for Windows 8.3 short names (#11661) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `os.tmpdir()` on GitHub's Windows runners returns the 8.3 short-name form of the user-profile directory (e.g. `C:\Users\RUNNER~1\AppData\Local\Temp`) because `runneradmin` is longer than 8 characters. The `~` then trips the `quoteShellArg` allowlist regex and every test that calls `sendLineScript` or `generateSendStdinScript` throws "Unsupported character in shell argument". The tilde is safe to allow: - cmd.exe performs no tilde expansion at all. - POSIX shells only expand `~` when it is unquoted at the start of a word; inside the double-quoted `"${arg}"` wrapper produced here it is literal. The matching CodeQL shell-injection sanitization argument is unchanged — the allowlist is still anchored and still rejects every metacharacter. The bug was masked until #11659 because the Windows test legs had been silently no-op'ing since #11608. --- Written by an agent (Claude Code, claude-opus-4-7). --- __utils__/test-ipc-server/src/TestIpcServer.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/__utils__/test-ipc-server/src/TestIpcServer.ts b/__utils__/test-ipc-server/src/TestIpcServer.ts index d23fbb919e..e5ad057b37 100644 --- a/__utils__/test-ipc-server/src/TestIpcServer.ts +++ b/__utils__/test-ipc-server/src/TestIpcServer.ts @@ -129,7 +129,7 @@ export class TestIpcServer implements AsyncDisposable { * entry. Exits after sending the message. * * Throws if `message` contains characters outside the allowlist enforced by - * `quoteShellArg` (alphanumerics plus ``_ - . / \\ : @ space + = ,``). All + * `quoteShellArg` (alphanumerics plus ``_ - . / \\ : @ space + = , ~``). All * existing call sites pass short ASCII identifiers, so the constraint is * satisfied by construction. */ @@ -163,9 +163,12 @@ export const createTestIpcServer = TestIpcServer.listen * Wrap an argument for inclusion in a shell command. The argument must contain * only a restricted set of characters known to be safe in both POSIX and * Windows command interpreters when surrounded by double quotes (alphanumerics - * plus `_ - . / \\ : @ space + = ,`). A trailing backslash is rejected because - * under both shells `\\"` consumes the closing quote, which would break the - * command line. + * plus `_ - . / \\ : @ space + = , ~`). The tilde is included because Windows + * 8.3 short-name temp paths (e.g. `C:\Users\RUNNER~1\AppData\Local\Temp`) flow + * through `os.tmpdir()` on GitHub's Windows runners; both shells treat `~` as a + * literal inside double quotes, so it is safe to allow. A trailing backslash is + * rejected because under both shells `\\"` consumes the closing quote, which + * would break the command line. * * Throws when the argument contains a character outside this allowlist. All * arguments produced internally (helper-script paths, the listen-path computed @@ -176,7 +179,7 @@ function quoteShellArg (arg: string): string { // Anchored allowlist — CodeQL recognizes this as a sanitization barrier for // shell-injection sinks. The `endsWith('\\')` check rules out the one // remaining ambiguous case the allowlist allows. - if (arg.length === 0 || !/^[\w\-./\\:@ +=,]+$/.test(arg) || arg.endsWith('\\')) { + if (arg.length === 0 || !/^[\w\-./\\:@ +=,~]+$/.test(arg) || arg.endsWith('\\')) { throw new Error(`Unsupported character in shell argument: ${JSON.stringify(arg)}`) } return `"${arg}"`