fix(browser): harden writable output paths

This commit is contained in:
Peter Steinberger
2026-03-01 23:25:13 +00:00
parent 51bccaf988
commit 6a80e9db05
7 changed files with 219 additions and 53 deletions

View File

@@ -3,6 +3,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import type { Page } from "playwright-core";
import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js";
import { writeViaSiblingTempPath } from "./output-atomic.js";
import { DEFAULT_UPLOAD_DIR, resolveStrictExistingPathsWithinRoot } from "./paths.js";
import {
ensurePageState,
@@ -111,13 +112,25 @@ type DownloadPayload = {
async function saveDownloadPayload(download: DownloadPayload, outPath: string) {
const suggested = download.suggestedFilename?.() || "download.bin";
const resolvedOutPath = outPath?.trim() || buildTempDownloadPath(suggested);
const requestedPath = outPath?.trim();
const resolvedOutPath = path.resolve(requestedPath || buildTempDownloadPath(suggested));
await fs.mkdir(path.dirname(resolvedOutPath), { recursive: true });
await download.saveAs?.(resolvedOutPath);
if (!requestedPath) {
await download.saveAs?.(resolvedOutPath);
} else {
await writeViaSiblingTempPath({
targetPath: resolvedOutPath,
writeTemp: async (tempPath) => {
await download.saveAs?.(tempPath);
},
});
}
return {
url: download.url?.() || "",
suggestedFilename: suggested,
path: path.resolve(resolvedOutPath),
path: resolvedOutPath,
};
}