* Find an executable using where.exe on Windows * @param executable - The name of the executable to find * @returns The path to the executable or null if not found
(executable: string)
| 24 | * @returns The path to the executable or null if not found |
| 25 | */ |
| 26 | function findExecutable(executable: string): string | null { |
| 27 | // For git, check common installation locations first |
| 28 | if (executable === 'git') { |
| 29 | const defaultLocations = [ |
| 30 | // check 64 bit before 32 bit |
| 31 | 'C:\\Program Files\\Git\\cmd\\git.exe', |
| 32 | 'C:\\Program Files (x86)\\Git\\cmd\\git.exe', |
| 33 | // intentionally don't look for C:\Program Files\Git\mingw64\bin\git.exe |
| 34 | // because that directory is the "raw" tools with no environment setup |
| 35 | ] |
| 36 | |
| 37 | for (const location of defaultLocations) { |
| 38 | if (checkPathExists(location)) { |
| 39 | return location |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | // Fall back to where.exe |
| 45 | try { |
| 46 | const result = execSync_DEPRECATED(`where.exe ${executable}`, { |
| 47 | stdio: 'pipe', |
| 48 | encoding: 'utf8', |
| 49 | }).trim() |
| 50 | |
| 51 | // SECURITY: Filter out any results from the current directory |
| 52 | // to prevent executing malicious git.bat/cmd/exe files |
| 53 | const paths = result.split('\r\n').filter(Boolean) |
| 54 | const cwd = getCwd().toLowerCase() |
| 55 | |
| 56 | for (const candidatePath of paths) { |
| 57 | // Normalize and compare paths to ensure we're not in current directory |
| 58 | const normalizedPath = path.resolve(candidatePath).toLowerCase() |
| 59 | const pathDir = path.dirname(normalizedPath).toLowerCase() |
| 60 | |
| 61 | // Skip if the executable is in the current working directory |
| 62 | if (pathDir === cwd || normalizedPath.startsWith(cwd + path.sep)) { |
| 63 | logForDebugging( |
| 64 | `Skipping potentially malicious executable in current directory: ${candidatePath}`, |
| 65 | ) |
| 66 | continue |
| 67 | } |
| 68 | |
| 69 | // Return the first valid path that's not in the current directory |
| 70 | return candidatePath |
| 71 | } |
| 72 | |
| 73 | return null |
| 74 | } catch { |
| 75 | return null |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * If Windows, set the SHELL environment variable to git-bash path. |
no test coverage detected