Skip to content

Commit 2633743

Browse files
committed
fix(parsers): validate ffmpeg discovery candidates
fixes reported:1785304892.118879:unicode-home-ffmpeg-discovery; PR #2859 remains unmodified.
1 parent 04e0ccc commit 2633743

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

packages/parsers/src/ffBinaries.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,47 @@ describe("findFfBinary", () => {
5252
const mocked = { execFileSync: () => "C:\\tools\\ffmpeg.cmd\r\nC:\\tools\\ffmpeg.exe\r\n" };
5353
return { ...mocked, default: mocked };
5454
});
55+
vi.doMock("node:fs", () => {
56+
const mocked = {
57+
existsSync: (candidate: unknown) => candidate === "C:\\tools\\ffmpeg.exe",
58+
accessSync: () => {},
59+
constants: { X_OK: 1 },
60+
};
61+
return { ...mocked, default: mocked };
62+
});
5563
const { findFfBinary } = await importFresh();
5664

5765
expect(findFfBinary("ffmpeg")).toBe(resolve("C:\\tools\\ffmpeg.exe"));
5866
});
5967

68+
it("falls back to PATH when Windows where output decodes to a missing path", async () => {
69+
delete process.env.HYPERFRAMES_FFMPEG_PATH;
70+
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
71+
process.env.PATH = "/valid-tools";
72+
const execFileSync = vi.fn(() => "C:\\Users\\��\\ffmpeg.exe\r\n");
73+
vi.resetModules();
74+
vi.doMock("node:child_process", () => ({
75+
execFileSync,
76+
default: { execFileSync },
77+
}));
78+
vi.doMock("node:fs", () => {
79+
const mocked = {
80+
existsSync: (candidate: unknown) => candidate === "/valid-tools/ffmpeg.exe",
81+
accessSync: () => {},
82+
constants: { X_OK: 1 },
83+
};
84+
return { ...mocked, default: mocked };
85+
});
86+
const { findFfBinary } = await importFresh();
87+
88+
expect(findFfBinary("ffmpeg")).toBe("/valid-tools/ffmpeg.exe");
89+
expect(execFileSync).toHaveBeenCalledWith(
90+
"where",
91+
["ffmpeg"],
92+
expect.objectContaining({ encoding: "utf-8" }),
93+
);
94+
});
95+
6096
it("falls back to scanning PATH when which/where fails", async () => {
6197
delete process.env.HYPERFRAMES_FFMPEG_PATH;
6298
const binDir = mkdtempSync(join(tmpdir(), "hyperframes-ffbinaries-"));

packages/parsers/src/ffBinaries.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ function lookupOnSystem(name: FfBinaryName): string | undefined {
108108
stdio: ["pipe", "pipe", "pipe"],
109109
timeout: 5000,
110110
});
111-
found = chooseBestPathCandidate(name, output.split(/\r?\n/));
111+
const candidate = chooseBestPathCandidate(name, output.split(/\r?\n/));
112+
found = candidate && isExecutablePathCandidate(candidate) ? candidate : scanPath(name);
112113
} catch {
113114
found = scanPath(name);
114115
}

0 commit comments

Comments
 (0)