mirror of https://github.com/garrytan/gstack.git
fix(make-pdf): write browse-bound temp files under the safe-dirs allowlist
os.tmpdir() on macOS resolves to /var/folders/..., which fails browse's safe-dirs validation ([/tmp, cwd]) since the v1.6.0.0 --from-file tightening. Default PDF output (generate with no -o), the preview HTML, tmpFile() scratch files, and setup's smoke-test fixture/output all wrote there, so browse rejected the paths it was asked to read or write. Export PAYLOAD_TMP_DIR from browseClient (the existing TEMP_DIR convention: os.tmpdir() on Windows, /tmp elsewhere) and route orchestrator.ts and setup.ts temp files through it. Contributed by @lvthewah (PR #2505; the browse-binary directory guard from that PR landed separately via PR #2538). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7ca68da785
commit
de08279969
|
|
@ -195,16 +195,18 @@ function runBrowse(args: string[]): string {
|
|||
}
|
||||
|
||||
/**
|
||||
* Write a payload to a tmp file and return the path. Used for any payload
|
||||
* >4KB to avoid Windows argv limits (Codex round 2 #3).
|
||||
* Temp dir for any file handed to browse (payloads, rendered HTML, PDF output).
|
||||
*
|
||||
* Path must be under the browse safe-dirs allowlist (/tmp or cwd on
|
||||
* non-Windows; os.tmpdir on Windows). v1.6.0.0 tightened --from-file
|
||||
* validation to close a CLI/API parity gap (PR #1103), so os.tmpdir()
|
||||
* on macOS (/var/folders/...) now fails validateReadPath. Use the same
|
||||
* TEMP_DIR convention as browse/src/platform.ts.
|
||||
*
|
||||
* Exported because orchestrator.ts and setup.ts write files that browse must
|
||||
* read back; os.tmpdir() there trips the same validateReadPath rejection.
|
||||
*/
|
||||
const PAYLOAD_TMP_DIR = process.platform === "win32" ? os.tmpdir() : "/tmp";
|
||||
export const PAYLOAD_TMP_DIR = process.platform === "win32" ? os.tmpdir() : "/tmp";
|
||||
|
||||
function writePayloadFile(payload: Record<string, unknown>): string {
|
||||
const hash = crypto.createHash("sha256")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
import * as fs from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import * as crypto from "node:crypto";
|
||||
import { spawn } from "node:child_process";
|
||||
|
|
@ -86,7 +85,7 @@ export async function generate(opts: GenerateOptions): Promise<string> {
|
|||
|
||||
const to = opts.to ?? "pdf";
|
||||
const outputPath = path.resolve(
|
||||
opts.output ?? path.join(os.tmpdir(), `${deriveSlug(input)}.${to}`),
|
||||
opts.output ?? path.join(browseClient.PAYLOAD_TMP_DIR, `${deriveSlug(input)}.${to}`),
|
||||
);
|
||||
|
||||
// Stage 1: read markdown
|
||||
|
|
@ -358,7 +357,7 @@ export async function preview(opts: PreviewOptions): Promise<string> {
|
|||
progress.end("Rendering HTML", `${rendered.meta.wordCount} words`);
|
||||
|
||||
// Write to a stable path under /tmp so the user can reload in the same tab.
|
||||
const previewPath = path.join(os.tmpdir(), `make-pdf-preview-${deriveSlug(input)}.html`);
|
||||
const previewPath = path.join(browseClient.PAYLOAD_TMP_DIR, `make-pdf-preview-${deriveSlug(input)}.html`);
|
||||
fs.writeFileSync(previewPath, rendered.html, "utf8");
|
||||
|
||||
progress.begin("Opening preview");
|
||||
|
|
@ -378,7 +377,7 @@ function deriveSlug(p: string): string {
|
|||
|
||||
function tmpFile(ext: string): string {
|
||||
const hash = crypto.randomBytes(6).toString("hex");
|
||||
return path.join(os.tmpdir(), `make-pdf-${process.pid}-${hash}.${ext}`);
|
||||
return path.join(browseClient.PAYLOAD_TMP_DIR, `make-pdf-${process.pid}-${hash}.${ext}`);
|
||||
}
|
||||
|
||||
function tryOpen(pathOrUrl: string): void {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
* 6. Print a 3-command cheatsheet
|
||||
*/
|
||||
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import * as fs from "node:fs";
|
||||
|
||||
|
|
@ -77,8 +76,8 @@ export async function runSetup(): Promise<void> {
|
|||
"The second paragraph contains curly quotes (\"hello\"), an em dash -- like this, and an ellipsis... all of which should render correctly.",
|
||||
"",
|
||||
].join("\n");
|
||||
const fixturePath = path.join(os.tmpdir(), `make-pdf-smoke-${process.pid}.md`);
|
||||
const outPath = path.join(os.tmpdir(), `make-pdf-smoke-${process.pid}.pdf`);
|
||||
const fixturePath = path.join(browseClient.PAYLOAD_TMP_DIR, `make-pdf-smoke-${process.pid}.md`);
|
||||
const outPath = path.join(browseClient.PAYLOAD_TMP_DIR, `make-pdf-smoke-${process.pid}.pdf`);
|
||||
fs.writeFileSync(fixturePath, fixture, "utf8");
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue