|
9 | 9 | import { BaseException } from '@angular-devkit/core'; |
10 | 10 | import { SpawnOptions, spawn } from 'node:child_process'; |
11 | 11 |
|
12 | | -/** |
13 | | - * Escapes a single argument for safe use with Windows cmd.exe. |
14 | | - * Prevents OS command injection (CWE-78) by wrapping in double quotes |
15 | | - * and correctly escaping embedded quotes and backslashes. |
16 | | - * |
17 | | - * Algorithm: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/ |
18 | | - */ |
19 | | -function escapeArgForWindowsShell(arg: string): string { |
20 | | - // FIX A: empty string must produce a quoted empty token. |
21 | | - // Returning bare '' causes cmd.exe to drop the arg silently, |
22 | | - // shifting all subsequent args by one (argument confusion). |
23 | | - if (!arg) return '""'; |
24 | | - // Fast path: only shell-safe chars, no quoting needed |
25 | | - if (/^[a-zA-Z0-9_\-./\\:@]+$/.test(arg)) { |
26 | | - return arg; |
27 | | - } |
28 | | - // FIX B: escape % BEFORE wrapping in double-quotes. |
29 | | - // cmd.exe expands %VAR% before evaluating quote context, so |
30 | | - // %COMSPEC% inside "..." still expands (BatBadBut / CVE-2024-3566). |
31 | | - // %% disables expansion and becomes a literal percent sign. |
32 | | - arg = arg.replace(/%/g, '%%'); |
33 | | - let result = '"'; |
34 | | - let slashes = 0; |
35 | | - for (const char of arg) { |
36 | | - if (char === '\\') { |
37 | | - slashes++; |
38 | | - } else if (char === '"') { |
39 | | - result += '\\'.repeat(slashes * 2 + 1) + '"'; |
40 | | - slashes = 0; |
41 | | - } else { |
42 | | - result += '\\'.repeat(slashes) + char; |
43 | | - slashes = 0; |
44 | | - } |
45 | | - } |
46 | | - result += '\\'.repeat(slashes * 2) + '"'; |
47 | | - return result; |
48 | | -} |
49 | 12 |
|
50 | 13 |
|
51 | 14 | import * as path from 'node:path'; |
|
0 commit comments