diff --git a/cliamp/cliamp-ws.ts b/cliamp/cliamp-ws.ts index d3bb564..9c3bd29 100644 --- a/cliamp/cliamp-ws.ts +++ b/cliamp/cliamp-ws.ts @@ -107,12 +107,19 @@ function pump( function openPlayer(ws: ServerWebSocket, files: string): void { if (!files) return sendOutput(ws, '\r\n[Error] No files specified.\r\n'); - const cliampPath = findCliamp(); - if (!cliampPath) return sendOutput(ws, '\r\n[Error] cliamp not found on host.\r\n'); - + // Validate the REQUEST before inspecting the HOST, and in that order deliberately. + // + // It was the other way round until 2026-08-18, which had two costs. A path escaping the owner's home + // was answered "cliamp not found on host" on a machine without the binary — telling the caller + // something about the host in response to input that should simply have been refused. And the + // behaviour this pair is supposed to guarantee became dependent on whether an unrelated binary happens + // to be installed, which is what made `cliamp-ws.test.ts` fail on every machine that does not have it. const target = resolveInHome(files); if (!target) return sendOutput(ws, '\r\n[Error] Invalid file path.\r\n'); + const cliampPath = findCliamp(); + if (!cliampPath) return sendOutput(ws, '\r\n[Error] cliamp not found on host.\r\n'); + // `script` fakes a PTY for cliamp, which avoids a node-pty native dependency here. const cliampCmd = `${shellEscape(cliampPath)} ${shellEscape(target)}`; console.log(`[music] cliamp spawning: ${cliampCmd}`);