fix(core): avoid grade stats regex backtracking (#3706)

This commit is contained in:
James Russo
2026-09-05 12:28:59 -04:00
committed by GitHub
parent e5d1d9bf0e
commit eec04340b3
4 changed files with 29 additions and 3 deletions
+2 -1
View File
@@ -157,7 +157,8 @@ export function parseMediaTreatmentSignalStats(raw: string): GradeSignalFrame[]
const frames: GradeSignalFrame[] = [];
let current: GradeSignalFrame | null = null;
for (const line of raw.split(/\r?\n/)) {
const frame = line.match(/^frame:\d+.*pts_time:([+-]?(?:\d+(?:\.\d+)?|\.\d+))/);
// One digit is enough: .* consumes the rest without overlapping repetitions.
const frame = line.match(/^frame:\d.*pts_time:([+-]?(?:\d+(?:\.\d+)?|\.\d+))/);
if (frame?.[1]) {
if (current) frames.push(current);
current = { ptsTime: Number(frame[1]) };
@@ -98,3 +98,27 @@ describe("vendored media grade analyzer parity", () => {
expect(await vendoredResult(signalStats)).toEqual(product);
});
});
describe("signal-stats frame headers", () => {
it.each([
["frame:123 pts:42 pts_time:-12.5", -12.5],
["frame:000pts_time:+.25", 0.25],
["frame:1 pts_time:1 pts_time:2.5", 2.5],
["frame:1 pts_time:1 pts_time:invalid", 1],
["frame:1 pts_time:12.", 12],
["frame:1 pts_time:2e3", 2],
["frame: pts_time:1", undefined],
["frame:-1 pts_time:1", undefined],
["prefix frame:1 pts_time:1", undefined],
["frame:1\u2028pts_time:1", undefined],
["frame:" + "0".repeat(100_000) + "!", undefined],
["frame:" + "0".repeat(100_000) + " pts_time:-.5", -0.5],
])("preserves header parsing (case %#)", async (header, ptsTime) => {
const raw = SIGNALSTATS.replace("frame:0 pts:0 pts_time:0", String(header));
const product = productResult(raw);
expect(product.frames).toHaveLength(2);
expect(product.frames[0]?.ptsTime).toBe(ptsTime);
expect(product.frames[1]?.ptsTime).toBe(1);
expect(await vendoredResult(raw)).toEqual(product);
});
});
+1 -1
View File
@@ -50,7 +50,7 @@
"files": 12
},
"media-use": {
"hash": "00a2d26e22fc1ab1",
"hash": "5b35f62a2c59f220",
"files": 153
},
"motion-graphics": {
@@ -76,7 +76,8 @@ export function parseMediaTreatmentSignalStats(raw) {
const frames = [];
let current = null;
for (const line of String(raw).split(/\r?\n/)) {
const frame = line.match(/^frame:\d+.*pts_time:([+-]?(?:\d+(?:\.\d+)?|\.\d+))/);
// One digit is enough: .* consumes the rest without overlapping repetitions.
const frame = line.match(/^frame:\d.*pts_time:([+-]?(?:\d+(?:\.\d+)?|\.\d+))/);
if (frame) {
if (current) frames.push(current);
current = { ptsTime: Number(frame[1]) };