diff --git a/src/media/video-dimensions.test.ts b/src/media/video-dimensions.test.ts index b82f5bed2ba8..c8480c181745 100644 --- a/src/media/video-dimensions.test.ts +++ b/src/media/video-dimensions.test.ts @@ -26,6 +26,12 @@ describe("parseFfprobeVideoDimensions", () => { parseFfprobeVideoDimensions(JSON.stringify({ streams: [{ width: 720.5, height: 1280 }] })), ).toBeUndefined(); }); + + it("returns undefined for malformed JSON instead of throwing", () => { + for (const stdout of ["{", "", "not json", "null", "42", '"text"', '{"streams":{}}']) { + expect(parseFfprobeVideoDimensions(stdout)).toBeUndefined(); + } + }); }); describe("probeVideoDimensions", () => { diff --git a/src/media/video-dimensions.ts b/src/media/video-dimensions.ts index 1e0830dd0052..8c65370117be 100644 --- a/src/media/video-dimensions.ts +++ b/src/media/video-dimensions.ts @@ -16,10 +16,23 @@ function parsePositiveDimension(value: unknown): number | undefined { /** Parses ffprobe JSON output, accepting only positive integer first-stream dimensions. */ export function parseFfprobeVideoDimensions(stdout: string): VideoDimensions | undefined { - const parsed = JSON.parse(stdout) as { streams?: Array<{ width?: unknown; height?: unknown }> }; - const stream = parsed.streams?.[0]; - const width = parsePositiveDimension(stream?.width); - const height = parsePositiveDimension(stream?.height); + let parsed: unknown; + try { + parsed = JSON.parse(stdout); + } catch { + return undefined; + } + if (!parsed || typeof parsed !== "object") { + return undefined; + } + const streams = (parsed as { streams?: unknown }).streams; + const stream = Array.isArray(streams) ? streams[0] : undefined; + if (!stream || typeof stream !== "object") { + return undefined; + } + const record = stream as Record; + const width = parsePositiveDimension(record.width); + const height = parsePositiveDimension(record.height); return width && height ? { width, height } : undefined; }