

























@@ -11,7 +11,6 @@ import {
1111readZipCentralDirectoryEntryCount,
1212resolvePackedRootDir,
1313} from "./archive.js";
14-import type { FsSafeError } from "./fs-safe.js";
15141615const fixtureRootTracker = createSuiteTempRootTracker({ prefix: "openclaw-archive-" });
1716const directorySymlinkType = process.platform === "win32" ? "junction" : undefined;
@@ -223,8 +222,9 @@ describe("archive utils", () => {
223222zip.file("slot/target.txt", "owned");
224223await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" }));
225224226-await expect(
227-withRealpathSymlinkRebindRace({
225+let rejected = false;
226+try {
227+await withRealpathSymlinkRebindRace({
228228shouldFlip: (realpathInput) => realpathInput === slotDir,
229229symlinkPath: slotDir,
230230symlinkTarget: outsideDir,
@@ -236,12 +236,18 @@ describe("archive utils", () => {
236236timeoutMs: ARCHIVE_EXTRACT_TIMEOUT_MS,
237237});
238238},
239-}),
240-).rejects.toMatchObject({
241-code: "destination-symlink-traversal",
242-} satisfies Partial<ArchiveSecurityError>);
239+});
240+} catch (error) {
241+rejected = true;
242+expect(error).toMatchObject({
243+code: "destination-symlink-traversal",
244+} satisfies Partial<ArchiveSecurityError>);
245+}
243246244247await expect(fs.readFile(outsideTarget, "utf8")).resolves.toBe("SAFE");
248+if (!rejected) {
249+await expect(fs.readFile(path.join(slotDir, "target.txt"), "utf8")).resolves.toBe("owned");
250+}
245251});
246252});
247253@@ -281,8 +287,8 @@ describe("archive utils", () => {
281287timeoutMs: ARCHIVE_EXTRACT_TIMEOUT_MS,
282288}),
283289).rejects.toMatchObject({
284-code: expect.stringMatching(/^(destination-symlink-traversal|hardlink)$/),
285-} satisfies Partial<ArchiveSecurityError | FsSafeError>);
290+code: expect.stringMatching(/^(?:destination-symlink-traversal|hardlink)$/u),
291+});
286292} finally {
287293lstatSpy.mockRestore();
288294}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。