mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-09 03:22:40 +00:00
fix: validate browser geolocation numbers
This commit is contained in:
@@ -172,6 +172,31 @@ describe("browser state option collisions", () => {
|
||||
expect(getBrowserCliRuntime().exit).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("rejects invalid geolocation numbers before dispatch", async () => {
|
||||
await runBrowserCommand(["set", "geo", "48.208", "16.373", "--accuracy", "fast"]);
|
||||
|
||||
expect(mocks.callBrowserRequest).not.toHaveBeenCalled();
|
||||
expectErrorMessage("Invalid --accuracy: must be a finite number");
|
||||
expect(getBrowserCliRuntime().exit).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("passes valid decimal geolocation numbers", async () => {
|
||||
const request = await runBrowserCommandAndGetRequest([
|
||||
"set",
|
||||
"geo",
|
||||
"48.2082",
|
||||
"16.3738",
|
||||
"--accuracy",
|
||||
"12.5",
|
||||
]);
|
||||
|
||||
expect(request.body).toMatchObject({
|
||||
latitude: 48.2082,
|
||||
longitude: 16.3738,
|
||||
accuracy: 12.5,
|
||||
});
|
||||
});
|
||||
|
||||
it("errors when headers JSON is missing", async () => {
|
||||
await runBrowserCommand(["set", "headers"]);
|
||||
|
||||
|
||||
@@ -25,6 +25,22 @@ function parsePositiveInteger(value: unknown, label: string): number | undefined
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function parseFiniteNumberOption(value: string | undefined, label: string): number | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const raw = value.trim();
|
||||
const parsed = /^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:e[+-]?\d+)?$/i.test(raw)
|
||||
? Number(raw)
|
||||
: Number.NaN;
|
||||
if (!Number.isFinite(parsed)) {
|
||||
defaultRuntime.error(danger(`Invalid ${label}: must be a finite number`));
|
||||
defaultRuntime.exit(1);
|
||||
return undefined;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function runBrowserCommand(action: () => Promise<void>) {
|
||||
return runCommandWithRuntime(defaultRuntime, action, (err) => {
|
||||
defaultRuntime.error(danger(String(err)));
|
||||
@@ -189,27 +205,39 @@ export function registerBrowserStateCommands(
|
||||
.command("geo")
|
||||
.description("Set geolocation (and grant permission)")
|
||||
.option("--clear", "Clear geolocation + permissions", false)
|
||||
.argument("[latitude]", "Latitude", (v: string) => Number(v))
|
||||
.argument("[longitude]", "Longitude", (v: string) => Number(v))
|
||||
.option("--accuracy <m>", "Accuracy in meters", (v: string) => Number(v))
|
||||
.argument("[latitude]", "Latitude")
|
||||
.argument("[longitude]", "Longitude")
|
||||
.option("--accuracy <m>", "Accuracy in meters")
|
||||
.option("--origin <origin>", "Origin to grant permissions for")
|
||||
.option("--target-id <id>", "CDP target id (or unique prefix)")
|
||||
.action(async (latitude: number | undefined, longitude: number | undefined, opts, cmd) => {
|
||||
const parent = parentOpts(cmd);
|
||||
await runBrowserSetRequest({
|
||||
parent,
|
||||
path: "/set/geolocation",
|
||||
body: {
|
||||
latitude: Number.isFinite(latitude) ? latitude : undefined,
|
||||
longitude: Number.isFinite(longitude) ? longitude : undefined,
|
||||
accuracy: Number.isFinite(opts.accuracy) ? opts.accuracy : undefined,
|
||||
origin: normalizeOptionalString(opts.origin),
|
||||
clear: Boolean(opts.clear),
|
||||
targetId: normalizeOptionalString(opts.targetId),
|
||||
},
|
||||
successMessage: opts.clear ? "geolocation cleared" : "geolocation set",
|
||||
});
|
||||
});
|
||||
.action(
|
||||
async (latitudeRaw: string | undefined, longitudeRaw: string | undefined, opts, cmd) => {
|
||||
const parent = parentOpts(cmd);
|
||||
const latitude = parseFiniteNumberOption(latitudeRaw, "latitude");
|
||||
const longitude = parseFiniteNumberOption(longitudeRaw, "longitude");
|
||||
const accuracy = parseFiniteNumberOption(opts.accuracy, "--accuracy");
|
||||
if (
|
||||
(latitudeRaw !== undefined && latitude === undefined) ||
|
||||
(longitudeRaw !== undefined && longitude === undefined) ||
|
||||
(opts.accuracy !== undefined && accuracy === undefined)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
await runBrowserSetRequest({
|
||||
parent,
|
||||
path: "/set/geolocation",
|
||||
body: {
|
||||
latitude,
|
||||
longitude,
|
||||
accuracy,
|
||||
origin: normalizeOptionalString(opts.origin),
|
||||
clear: Boolean(opts.clear),
|
||||
targetId: normalizeOptionalString(opts.targetId),
|
||||
},
|
||||
successMessage: opts.clear ? "geolocation cleared" : "geolocation set",
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
set
|
||||
.command("media")
|
||||
|
||||
Reference in New Issue
Block a user