1520
*/
1521
private async _findFallbackCLI(client: SSHClient): Promise<string | undefined> {
1522
>
const { stdout } = await sshExec(client, buildFindFallbackCLICommand(this._serverDataFolderName, this._quality), { ignoreExitCode: true });
sshRemoteAgentHostService.ts
1523
>
const rawCandidates = stdout.split('\n').map(s => s.trim()).filter(s => s.length > 0);
1524
>
// Defensive validation: the finder shell snippet emits paths we
1525
>
// trust by construction, but the output is still data coming back
1526
>
// over SSH that we then interpolate into a follow-up command
1527
>
// (`<candidate> --version`). Filter to the exact shapes we expect
1528
>
// — `<root>/<archive>-<40 hex>` or `<legacyDir>/<archive>` — so a
1529
>
// malicious or junk file in the install root can never become a
1530
>
// shell argument.
1531
>
const candidates: string[] = [];
1532
>
for (const candidate of rawCandidates) {
1533
if (isValidFallbackCLIPath(candidate, this._serverDataFolderName, this._quality)) {
1534
candidates.push(candidate);