test: tolerate archive race outcomes

This commit is contained in:
Peter Steinberger
2026-05-06 03:22:52 +01:00
parent 736f627fb5
commit 74532265f4

View File

@@ -11,7 +11,6 @@ import {
readZipCentralDirectoryEntryCount, readZipCentralDirectoryEntryCount,
resolvePackedRootDir, resolvePackedRootDir,
} from "./archive.js"; } from "./archive.js";
import type { FsSafeError } from "./fs-safe.js";
const fixtureRootTracker = createSuiteTempRootTracker({ prefix: "openclaw-archive-" }); const fixtureRootTracker = createSuiteTempRootTracker({ prefix: "openclaw-archive-" });
const directorySymlinkType = process.platform === "win32" ? "junction" : undefined; const directorySymlinkType = process.platform === "win32" ? "junction" : undefined;
@@ -223,8 +222,9 @@ describe("archive utils", () => {
zip.file("slot/target.txt", "owned"); zip.file("slot/target.txt", "owned");
await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" })); await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" }));
await expect( let rejected = false;
withRealpathSymlinkRebindRace({ try {
await withRealpathSymlinkRebindRace({
shouldFlip: (realpathInput) => realpathInput === slotDir, shouldFlip: (realpathInput) => realpathInput === slotDir,
symlinkPath: slotDir, symlinkPath: slotDir,
symlinkTarget: outsideDir, symlinkTarget: outsideDir,
@@ -236,12 +236,18 @@ describe("archive utils", () => {
timeoutMs: ARCHIVE_EXTRACT_TIMEOUT_MS, timeoutMs: ARCHIVE_EXTRACT_TIMEOUT_MS,
}); });
}, },
}), });
).rejects.toMatchObject({ } catch (error) {
code: "destination-symlink-traversal", rejected = true;
} satisfies Partial<ArchiveSecurityError>); expect(error).toMatchObject({
code: "destination-symlink-traversal",
} satisfies Partial<ArchiveSecurityError>);
}
await expect(fs.readFile(outsideTarget, "utf8")).resolves.toBe("SAFE"); await expect(fs.readFile(outsideTarget, "utf8")).resolves.toBe("SAFE");
if (!rejected) {
await expect(fs.readFile(path.join(slotDir, "target.txt"), "utf8")).resolves.toBe("owned");
}
}); });
}); });
@@ -281,8 +287,8 @@ describe("archive utils", () => {
timeoutMs: ARCHIVE_EXTRACT_TIMEOUT_MS, timeoutMs: ARCHIVE_EXTRACT_TIMEOUT_MS,
}), }),
).rejects.toMatchObject({ ).rejects.toMatchObject({
code: expect.stringMatching(/^(destination-symlink-traversal|hardlink)$/), code: expect.stringMatching(/^(?:destination-symlink-traversal|hardlink)$/u),
} satisfies Partial<ArchiveSecurityError | FsSafeError>); });
} finally { } finally {
lstatSpy.mockRestore(); lstatSpy.mockRestore();
} }