diff --git a/src/input.c b/src/input.c index 537f01b..90566f0 100644 --- a/src/input.c +++ b/src/input.c @@ -632,6 +632,11 @@ static int parse_osc(struct InputState *st, struct InputEvent *ev) { if (code == -1) code = 0; code = code * 10 + (st->buf[i] - '0'); + /* 22 is the only accepted code; the accumulator only grows as digits + * arrive, so once it passes 22 no valid completion exists. Bail here so a + * long digit run can never overflow `code`. */ + if (code > 22) + return PARSE_ERR; i++; } if (i >= st->len) diff --git a/test/input.test.ts b/test/input.test.ts index 4341078..1c3f5b2 100644 --- a/test/input.test.ts +++ b/test/input.test.ts @@ -763,6 +763,15 @@ describe("input", () => { }); }); + it("rejects an unbounded digit run without overflowing", () => { + // A long run of digits must not overflow the code accumulator; anything + // that grows past 22 can never match, so it is dropped as an error. + let result = input.scan(str("\x1b]" + "9".repeat(64) + ";x\x1b\\")); + expect( + result.events.some((e) => e.type === "pointershape"), + ).toBe(false); + }); + it("parses a reply interleaved with other input", () => { let result = input.scan(str("a\x1b]22;default\x1b\\b")); expect(result.events.length).toBe(3);