Skip to content

Commit 756276d

Browse files
committed
Address CodeRabbit review feedback
- Guard the raw config text length (1 MB) before JSON.parse, so a pathological file is rejected without being fully allocated first (completes the MAX_KEYFRAMES DoS hardening, which only ran post-parse).
1 parent 9df89ed commit 756276d

2 files changed

Lines changed: 15 additions & 0 deletions

File tree

apps/geolibre-desktop/src/lib/tour-recorder.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ const MAX_PITCH = 85;
5353
* array and the dialog mint an id per entry in a loop.
5454
*/
5555
const MAX_KEYFRAMES = 500;
56+
/**
57+
* Upper bound on the raw config text before parsing. A real tour (even the
58+
* 500-keyframe maximum) is well under 100 KB, so 1 MB is generous while still
59+
* rejecting a pathological file before `JSON.parse` allocates it.
60+
*/
61+
const MAX_CONFIG_TEXT_LENGTH = 1_000_000;
5662

5763
/** A short still hold at the start of the tour so the opening frame is steady. */
5864
export const START_HOLD_MS = 400;
@@ -210,6 +216,11 @@ function parseKeyframe(raw: unknown): TourKeyframeData {
210216
* message on any structural problem; callers show a translated fallback.
211217
*/
212218
export function parseTourConfig(text: string): ParsedTourConfig {
219+
// Reject an oversized file before JSON.parse so a pathological input can't be
220+
// fully allocated just to be rejected by the later keyframe-count check.
221+
if (text.length > MAX_CONFIG_TEXT_LENGTH) {
222+
throw new Error("Tour configuration file is too large.");
223+
}
213224
let raw: unknown;
214225
try {
215226
raw = JSON.parse(text);

tests/tour-recorder.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ describe("serializeTourConfig / parseTourConfig", () => {
198198
assert.throws(() => parseTourConfig("not json"));
199199
});
200200

201+
it("rejects an oversized config file before parsing", () => {
202+
assert.throws(() => parseTourConfig(" ".repeat(1_000_001)));
203+
});
204+
201205
it("rejects a file without the tour marker", () => {
202206
assert.throws(() =>
203207
parseTourConfig(JSON.stringify({ keyframes: [], fps: 30 })),

0 commit comments

Comments
 (0)