diff --git a/packages/cli/src/lib/init/workflow-inputs.ts b/packages/cli/src/lib/init/workflow-inputs.ts index 4af83515a..b2cff4c6f 100644 --- a/packages/cli/src/lib/init/workflow-inputs.ts +++ b/packages/cli/src/lib/init/workflow-inputs.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import path from "node:path"; +import { isLikelyBinary } from "../scan/index.js"; import { MAX_FILE_BYTES } from "./constants.js"; import { detectSentry } from "./tools/detect-sentry.js"; import { listDir } from "./tools/list-dir.js"; @@ -131,7 +132,12 @@ export async function preReadCommonFiles( if (stat.size > MAX_FILE_BYTES) { continue; } - const content = await fs.promises.readFile(absPath, "utf-8"); + const buffer = await fs.promises.readFile(absPath); + if (isLikelyBinary(buffer)) { + cache[filePath] = null; + continue; + } + const content = buffer.toString("utf-8"); if (totalBytes + content.length <= MAX_PREREAD_TOTAL_BYTES) { cache[filePath] = content; totalBytes += content.length; diff --git a/packages/cli/test/lib/init/tools/filesystem-tools.test.ts b/packages/cli/test/lib/init/tools/filesystem-tools.test.ts index ca08bfcc8..5a7d8f18b 100644 --- a/packages/cli/test/lib/init/tools/filesystem-tools.test.ts +++ b/packages/cli/test/lib/init/tools/filesystem-tools.test.ts @@ -103,6 +103,26 @@ describe("filesystem tools", () => { expect((existsResult.data as any).exists["missing.txt"]).toBe(false); }); + test("reads binary content when the workflow explicitly requests it", async () => { + const content = Buffer.from([0x7f, 0x45, 0x4c, 0x46, 0x02, 0x00, 0xff]); + fs.writeFileSync(path.join(testDir, "sentry-wizard"), content); + + const result = await executeTool( + { + type: "tool", + operation: "read-files", + cwd: testDir, + params: { paths: ["sentry-wizard"] }, + }, + makeContext(testDir) + ); + + expect(result.ok).toBe(true); + expect((result.data as any).files["sentry-wizard"]).toBe( + content.toString("utf-8") + ); + }); + test("applies patchsets and injects auth tokens into env files", async () => { const result = await executeTool( { diff --git a/packages/cli/test/lib/safe-read.test.ts b/packages/cli/test/lib/safe-read.test.ts index 94310d042..c58d7704d 100644 --- a/packages/cli/test/lib/safe-read.test.ts +++ b/packages/cli/test/lib/safe-read.test.ts @@ -272,4 +272,18 @@ describe("workflow-inputs preReadCommonFiles FIFO safety", () => { expect(cache["package.json"]).toBe('{"name":"x"}'); expect(cache["tsconfig.json"]).toBeNull(); }); + + test("does not pre-read binary content disguised as a common config", async () => { + writeFileSync( + join(dir, "package.json"), + Buffer.from([0x7f, 0x45, 0x4c, 0x46, 0x02, 0x00, 0xff]) + ); + + const listing: DirEntry[] = [ + { name: "package.json", path: "package.json", type: "file" }, + ]; + const cache = await preReadCommonFiles(dir, listing); + + expect(cache["package.json"]).toBeNull(); + }); });