fix(browser): validate screenshot timeout

This commit is contained in:
Peter Steinberger
2026-05-29 03:46:46 -04:00
parent 4ad875308f
commit ac52499aca
2 changed files with 26 additions and 6 deletions

View File

@@ -169,4 +169,18 @@ describe("browser agent snapshot timeout routing", () => {
}),
);
});
it("rejects loose screenshot timeoutMs values before dispatching", async () => {
const handler = getScreenshotHandler();
const response = createBrowserRouteResponse();
await handler?.(
{ params: {}, query: {}, body: { type: "png", timeoutMs: "1e3" } },
response.res,
);
expect(response.statusCode).toBe(400);
expect(response.body).toEqual({ error: "timeoutMs must be a positive integer." });
expect(cdpMocks.captureScreenshot).not.toHaveBeenCalled();
});
});

View File

@@ -43,8 +43,9 @@ import {
shouldUsePlaywrightForScreenshot,
} from "./agent.snapshot.plan.js";
import { EXISTING_SESSION_LIMITS } from "./existing-session-limits.js";
import { readRoutePositiveInteger } from "./route-numeric.js";
import type { BrowserResponse, BrowserRouteRegistrar } from "./types.js";
import { asyncBrowserRoute, jsonError, toBoolean, toNumber, toStringOrEmpty } from "./utils.js";
import { asyncBrowserRoute, jsonError, toBoolean, toStringOrEmpty } from "./utils.js";
const CHROME_MCP_OVERLAY_ATTR = "data-openclaw-mcp-overlay";
@@ -368,11 +369,16 @@ export function registerBrowserAgentSnapshotRoutes(
const element = toStringOrEmpty(body.element) || undefined;
const labels = toBoolean(body.labels) ?? false;
const type = body.type === "jpeg" ? "jpeg" : "png";
const timeoutMsRaw = toNumber(body.timeoutMs);
const timeoutMs =
timeoutMsRaw !== undefined
? normalizeBrowserTimerDelayMs(timeoutMsRaw)
: DEFAULT_BROWSER_SCREENSHOT_TIMEOUT_MS;
let timeoutMs: number;
try {
const timeoutMsRaw = readRoutePositiveInteger(body.timeoutMs, "timeoutMs");
timeoutMs =
timeoutMsRaw !== undefined
? normalizeBrowserTimerDelayMs(timeoutMsRaw)
: DEFAULT_BROWSER_SCREENSHOT_TIMEOUT_MS;
} catch (err) {
return jsonError(res, 400, String(err instanceof Error ? err.message : err));
}
if (fullPage && (ref || element)) {
return jsonError(res, 400, "fullPage is not supported for element screenshots");