fix(google-meet): reject nondecimal transcript cursors (#106384)

* fix(google-meet): reject nondecimal transcript cursors

Use parseStrictNonNegativeInteger for --since validation so hex,
exponent, and fractional spellings are rejected at the CLI boundary
instead of silently coercing to different cursor offsets.

Remove the redundant file header comment to stay within the
oversized-file LOC ratchet.

* test(google-meet): harden transcript cursor coverage

* style(google-meet): format cursor tests

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Wynne668
2026-07-14 13:28:18 +08:00
committed by GitHub
parent ee858fc9f2
commit 73cb408565
2 changed files with 47 additions and 3 deletions

View File

@@ -832,6 +832,50 @@ describe("google-meet CLI", () => {
}
});
it.each([
["0", 0],
["3", 3],
["+3", 3],
[" 3 ", 3],
[String(Number.MAX_SAFE_INTEGER), Number.MAX_SAFE_INTEGER],
] as const)("accepts base-10 safe transcript cursors: %s", async (since, expected) => {
const callGatewayFromCli = vi.fn(async () => ({
found: true,
sessionId: "meet_gateway",
startIndex: expected,
nextIndex: expected,
lines: [],
}));
await setupCli({ callGatewayFromCli }).parseAsync(
["googlemeet", "transcript", "meet_gateway", "--since", since],
{ from: "user" },
);
expect(callGatewayFromCli).toHaveBeenCalledWith(
"googlemeet.transcript",
{ json: true, timeout: "5000" },
{ sessionId: "meet_gateway", sinceIndex: expected },
{ progress: false },
);
});
it.each(["", " ", "-1", "0x10", "0o10", "0b10", "1e0", "1.5", "9007199254740992"])(
"rejects non-decimal transcript cursors before gateway delegation: %s",
async (since) => {
const callGatewayFromCli = vi.fn();
await expect(
setupCli({ callGatewayFromCli }).parseAsync(
["googlemeet", "transcript", "meet_gateway", "--since", since],
{ from: "user" },
),
).rejects.toThrow("--since must be a non-negative safe integer");
expect(callGatewayFromCli).not.toHaveBeenCalled();
},
);
it("delegates join to the gateway-owned runtime when available", async () => {
const callGatewayFromCli = vi.fn(async () => ({
session: {

View File

@@ -1,4 +1,3 @@
// Google Meet plugin module implements cli behavior.
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
import { createInterface } from "node:readline/promises";
@@ -9,6 +8,7 @@ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
import {
clampTimerTimeoutMs,
parseStrictNonNegativeInteger,
parseStrictPositiveInteger,
} from "openclaw/plugin-sdk/number-runtime";
import prettyMilliseconds from "pretty-ms";
@@ -2263,8 +2263,8 @@ export function registerGoogleMeetCli(params: {
.option("--since <index>", "Resume from the previous response's nextIndex")
.option("--json", "Print JSON output", false)
.action(async (sessionId: string, options: { since?: string; json?: boolean }) => {
const sinceIndex = options.since === undefined ? undefined : Number(options.since);
if (sinceIndex !== undefined && (!Number.isSafeInteger(sinceIndex) || sinceIndex < 0)) {
const sinceIndex = parseStrictNonNegativeInteger(options.since);
if (options.since !== undefined && sinceIndex === undefined) {
throw new Error("--since must be a non-negative safe integer");
}
const delegated = await callGoogleMeetGateway({