From 09dc880f892a3b69d5353e252a633b79bd27ee74 Mon Sep 17 00:00:00 2001 From: pick-cat Date: Sat, 4 Jul 2026 05:11:14 +0800 Subject: [PATCH] fix(media): guard ffprobe JSON parse against malformed output (#98613) * fix(media): guard ffprobe JSON parse against malformed output Co-Authored-By: Claude Opus 4.7 * chore: trigger CI re-run Co-Authored-By: Claude Opus 4.7 * chore: trigger CI re-run Co-Authored-By: Claude Opus 4.7 * fix(media): validate ffprobe JSON shape --------- Co-authored-by: Claude Opus 4.7 Co-authored-by: Peter Steinberger --- src/media/video-dimensions.test.ts | 6 ++++++ src/media/video-dimensions.ts | 21 +++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) 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; }