fix(temp): preserve workspace leaf filename contract
This commit is contained in:
parent
f305c8be2b
commit
5218746972
@ -9,7 +9,6 @@ import {
|
||||
type FileStoreSync,
|
||||
} from "./file-store.js";
|
||||
import { openRootFileSync } from "./root-file.js";
|
||||
import { isSafePathSegment } from "./safe-path-segment.js";
|
||||
import { registerTempPathForExit } from "./temp-cleanup.js";
|
||||
|
||||
export type TempWorkspaceOptions = {
|
||||
@ -62,7 +61,15 @@ function resolveWorkspaceLeaf(dir: string, fileName: string): string {
|
||||
|
||||
function assertWorkspaceFileName(fileName: string): string {
|
||||
const value = fileName.trim();
|
||||
if (!isSafePathSegment(value)) {
|
||||
if (
|
||||
!value ||
|
||||
value === "." ||
|
||||
value === ".." ||
|
||||
value.includes("\0") ||
|
||||
value.includes("/") ||
|
||||
value.includes("\\") ||
|
||||
path.basename(value) !== value
|
||||
) {
|
||||
throw new Error(`Invalid temp workspace file name: ${JSON.stringify(fileName)}`);
|
||||
}
|
||||
return value;
|
||||
|
||||
@ -15,7 +15,7 @@ import { runPinnedWriteHelper } from "../src/pinned-write.js";
|
||||
import { replaceFileAtomic } from "../src/replace-file.js";
|
||||
import { writeViaSiblingTempPath } from "../src/sibling-temp.js";
|
||||
import { sanitizeTempFileName, tempFile } from "../src/temp-target.js";
|
||||
import { tempWorkspaceSync } from "../src/private-temp-workspace.js";
|
||||
import { tempWorkspace, tempWorkspaceSync } from "../src/private-temp-workspace.js";
|
||||
import { __setFsSafeTestHooksForTest } from "../src/test-hooks.js";
|
||||
import { movePathToTrash } from "../src/trash.js";
|
||||
|
||||
@ -390,6 +390,19 @@ describe("security finding regressions", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("accepts safe temp workspace leaf names with spaces and dot prefixes", async () => {
|
||||
await using workspace = await tempWorkspace({
|
||||
rootDir: await tempRoot("fs-safe-workspace-leaf-"),
|
||||
prefix: "work-",
|
||||
});
|
||||
|
||||
await workspace.writeText("report 2026.txt", "ok");
|
||||
await workspace.writeText(".env", "TOKEN=ok");
|
||||
|
||||
await expect(workspace.read("report 2026.txt")).resolves.toEqual(Buffer.from("ok"));
|
||||
await expect(workspace.read(".env")).resolves.toEqual(Buffer.from("TOKEN=ok"));
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")("pins sync temp workspace reads against final symlink swaps", async () => {
|
||||
const base = await tempRoot("fs-safe-temp-workspace-sync-read-");
|
||||
const outside = await tempRoot("fs-safe-temp-workspace-sync-outside-");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user