From 5d61afb362d32d9c7b592e300b186782f5b130f3 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 19:31:03 +0000 Subject: [PATCH] test(commands): dedupe signal install extract fixture and cover zip extract --- src/commands/signal-install.test.ts | 38 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/commands/signal-install.test.ts b/src/commands/signal-install.test.ts index c078c6fd754..a377428de4d 100644 --- a/src/commands/signal-install.test.ts +++ b/src/commands/signal-install.test.ts @@ -133,9 +133,17 @@ describe("pickAsset", () => { }); describe("extractSignalCliArchive", () => { - it("rejects zip slip path traversal", async () => { + async function withArchiveWorkspace(run: (workDir: string) => Promise) { const workDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-signal-install-")); try { + await run(workDir); + } finally { + await fs.rm(workDir, { recursive: true, force: true }).catch(() => undefined); + } + } + + it("rejects zip slip path traversal", async () => { + await withArchiveWorkspace(async (workDir) => { const archivePath = path.join(workDir, "bad.zip"); const extractDir = path.join(workDir, "extract"); await fs.mkdir(extractDir, { recursive: true }); @@ -147,14 +155,28 @@ describe("extractSignalCliArchive", () => { await expect(extractSignalCliArchive(archivePath, extractDir, 5_000)).rejects.toThrow( /(escapes destination|absolute)/i, ); - } finally { - await fs.rm(workDir, { recursive: true, force: true }).catch(() => undefined); - } + }); + }); + + it("extracts zip archives", async () => { + await withArchiveWorkspace(async (workDir) => { + const archivePath = path.join(workDir, "ok.zip"); + const extractDir = path.join(workDir, "extract"); + await fs.mkdir(extractDir, { recursive: true }); + + const zip = new JSZip(); + zip.file("root/signal-cli", "bin"); + await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" })); + + await extractSignalCliArchive(archivePath, extractDir, 5_000); + + const extracted = await fs.readFile(path.join(extractDir, "root", "signal-cli"), "utf-8"); + expect(extracted).toBe("bin"); + }); }); it("extracts tar.gz archives", async () => { - const workDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-signal-install-")); - try { + await withArchiveWorkspace(async (workDir) => { const archivePath = path.join(workDir, "ok.tgz"); const extractDir = path.join(workDir, "extract"); const rootDir = path.join(workDir, "root"); @@ -167,8 +189,6 @@ describe("extractSignalCliArchive", () => { const extracted = await fs.readFile(path.join(extractDir, "root", "signal-cli"), "utf-8"); expect(extracted).toBe("bin"); - } finally { - await fs.rm(workDir, { recursive: true, force: true }).catch(() => undefined); - } + }); }); });