mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
lobster: parse windows cmd shim paths with rooted tokens (#20833)
This commit is contained in:
@@ -304,6 +304,38 @@ describe("lobster plugin tool", () => {
|
||||
expect(options).not.toHaveProperty("shell");
|
||||
});
|
||||
|
||||
it("runs Windows cmd shims with rooted dp0 tokens through Node", async () => {
|
||||
setProcessPlatform("win32");
|
||||
const shimScriptPath = path.join(tempDir, "shim-dist", "lobster-cli.cjs");
|
||||
const shimPath = path.join(tempDir, "shim", "lobster.cmd");
|
||||
await fs.mkdir(path.dirname(shimScriptPath), { recursive: true });
|
||||
await fs.mkdir(path.dirname(shimPath), { recursive: true });
|
||||
await fs.writeFile(shimScriptPath, "module.exports = {};\n", "utf8");
|
||||
await fs.writeFile(
|
||||
shimPath,
|
||||
`@echo off\r\n"%dp0%\\..\\shim-dist\\lobster-cli.cjs" %*\r\n`,
|
||||
"utf8",
|
||||
);
|
||||
spawnState.queue.push({
|
||||
stdout: JSON.stringify({
|
||||
ok: true,
|
||||
status: "ok",
|
||||
output: [{ hello: "rooted" }],
|
||||
requiresApproval: null,
|
||||
}),
|
||||
});
|
||||
|
||||
const tool = createLobsterTool(fakeApi({ pluginConfig: { lobsterPath: shimPath } }));
|
||||
await tool.execute("call-win-rooted-shim", {
|
||||
action: "run",
|
||||
pipeline: "noop",
|
||||
});
|
||||
|
||||
const [command, argv] = spawnState.spawn.mock.calls[0] ?? [];
|
||||
expect(command).toBe(process.execPath);
|
||||
expect(argv).toEqual([shimScriptPath, "run", "--mode", "tool", "noop"]);
|
||||
});
|
||||
|
||||
it("ignores node.exe shim entries and resolves the actual lobster script", async () => {
|
||||
setProcessPlatform("win32");
|
||||
const shimDir = path.join(tempDir, "shim-with-node");
|
||||
|
||||
@@ -121,13 +121,30 @@ function resolveLobsterScriptFromCmdShim(wrapperPath: string): string | null {
|
||||
try {
|
||||
const content = fs.readFileSync(wrapperPath, "utf8");
|
||||
const candidates: string[] = [];
|
||||
const matches = content.matchAll(/"%~?dp0%\\([^"\r\n]+)"/gi);
|
||||
for (const match of matches) {
|
||||
const extractRelativeFromToken = (token: string): string | null => {
|
||||
const match = token.match(/%~?dp0%\s*[\\/]*(.*)$/i);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
const relative = match[1];
|
||||
if (!relative) {
|
||||
return null;
|
||||
}
|
||||
return relative;
|
||||
};
|
||||
|
||||
const matches = content.matchAll(/"([^"\r\n]*)"/g);
|
||||
for (const match of matches) {
|
||||
const token = match[1] ?? "";
|
||||
const relative = extractRelativeFromToken(token);
|
||||
if (!relative) {
|
||||
continue;
|
||||
}
|
||||
const normalizedRelative = relative.replace(/[\\/]+/g, path.sep);
|
||||
|
||||
const normalizedRelative = relative
|
||||
.trim()
|
||||
.replace(/[\\/]+/g, path.sep)
|
||||
.replace(/^[\\/]+/, "");
|
||||
const candidate = path.resolve(path.dirname(wrapperPath), normalizedRelative);
|
||||
if (isFilePath(candidate)) {
|
||||
candidates.push(candidate);
|
||||
|
||||
Reference in New Issue
Block a user