mirror of
https://github.com/morluto/rea.git
synced 2026-11-07 05:56:19 -10:00
fix(cli): reject non-decimal web capture deadlines (#9167)
This commit is contained in:
3 files changed
+31
-4
No files matched your search
@@ -38,6 +38,7 @@ import { inspectWebNetworkCaptureInputSchema } from "../domain/webNetworkCapture
|
|||||||
import { withCommandCancellation } from "./commandCancellation.js";
|
import { withCommandCancellation } from "./commandCancellation.js";
|
||||||
import { finishAnalysisCommand } from "./finishAnalysisCommand.js";
|
import { finishAnalysisCommand } from "./finishAnalysisCommand.js";
|
||||||
import type { CliInstance } from "./types.js";
|
import type { CliInstance } from "./types.js";
|
||||||
|
import { cliDecimalField } from "./options.js";
|
||||||
|
|
||||||
/** Same envelope label as the other JSON-input commands and `parseCliJsonInput`. */
|
/** Same envelope label as the other JSON-input commands and `parseCliJsonInput`. */
|
||||||
const cliError = (error: AnalysisError): JsonValue => ({
|
const cliError = (error: AnalysisError): JsonValue => ({
|
||||||
@@ -512,8 +513,10 @@ const registerBuildCommand = (
|
|||||||
.boolean()
|
.boolean()
|
||||||
.default(false)
|
.default(false)
|
||||||
.describe("Run every stage and report, but write nothing"),
|
.describe("Run every stage and report, but write nothing"),
|
||||||
captureTimeoutMs:
|
// Decimal tokens only: numeric coercion would read "0x1" as 1 ms.
|
||||||
|
captureTimeoutMs: cliDecimalField(
|
||||||
inspectWebNetworkCaptureInputSchema.shape.capture_timeout_ms,
|
inspectWebNetworkCaptureInputSchema.shape.capture_timeout_ms,
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
withCommandCancellation((signal) =>
|
withCommandCancellation((signal) =>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { CLI_COMMANDS } from "../cliCommandNames.js";
|
|||||||
import { logCliCommand } from "../cliLogging.js";
|
import { logCliCommand } from "../cliLogging.js";
|
||||||
import type { Logger } from "pino";
|
import type { Logger } from "pino";
|
||||||
import type { CliInstance } from "./types.js";
|
import type { CliInstance } from "./types.js";
|
||||||
import { cliIntegerArgument } from "./options.js";
|
import { cliDecimalField, cliIntegerArgument } from "./options.js";
|
||||||
import { withCommandCancellation } from "./commandCancellation.js";
|
import { withCommandCancellation } from "./commandCancellation.js";
|
||||||
import {
|
import {
|
||||||
analysisEvidenceDeliveryOptions,
|
analysisEvidenceDeliveryOptions,
|
||||||
@@ -55,8 +55,10 @@ export const registerWebNetworkCaptureCommands = (
|
|||||||
.optional()
|
.optional()
|
||||||
.describe("Zero-based producer ordinals; repeat to select several"),
|
.describe("Zero-based producer ordinals; repeat to select several"),
|
||||||
...explicitSensitiveValueOptions,
|
...explicitSensitiveValueOptions,
|
||||||
captureTimeoutMs:
|
// Decimal tokens only: numeric coercion would read "0x1" as 1 ms.
|
||||||
|
captureTimeoutMs: cliDecimalField(
|
||||||
inspectWebNetworkCaptureInputSchema.shape.capture_timeout_ms,
|
inspectWebNetworkCaptureInputSchema.shape.capture_timeout_ms,
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
run: ({ args, options }) =>
|
run: ({ args, options }) =>
|
||||||
withCommandCancellation((signal) =>
|
withCommandCancellation((signal) =>
|
||||||
|
|||||||
@@ -152,7 +152,13 @@ cliTest(
|
|||||||
const har = join(root, "grafana.har");
|
const har = join(root, "grafana.har");
|
||||||
await writeFile(har, JSON.stringify(environmentManifestHar()));
|
await writeFile(har, JSON.stringify(environmentManifestHar()));
|
||||||
const planned = await cli.run({
|
const planned = await cli.run({
|
||||||
arguments: ["environment-build", har, "--dry-run", "--json"],
|
arguments: [
|
||||||
|
"environment-build",
|
||||||
|
har,
|
||||||
|
"--dry-run",
|
||||||
|
"--capture-timeout-ms=030000",
|
||||||
|
"--json",
|
||||||
|
],
|
||||||
timeoutMs: 60_000,
|
timeoutMs: 60_000,
|
||||||
});
|
});
|
||||||
expect(planned.exitCode, planned.stderr).toBe(0);
|
expect(planned.exitCode, planned.stderr).toBe(0);
|
||||||
@@ -188,6 +194,22 @@ cliTest(
|
|||||||
expect(conflicting.exitCode).toBe(1);
|
expect(conflicting.exitCode).toBe(1);
|
||||||
expect(conflicting.json).toMatchObject({ code: "invalid_request" });
|
expect(conflicting.json).toMatchObject({ code: "invalid_request" });
|
||||||
|
|
||||||
|
// Both capture readers share the field. Numeric coercion would read
|
||||||
|
// "0x1" as a 1 ms capture deadline.
|
||||||
|
for (const command of [
|
||||||
|
["environment-build", har, "--dry-run"],
|
||||||
|
["inspect-web-network-capture", har, "har"],
|
||||||
|
]) {
|
||||||
|
const hexDeadline = await cli.run({
|
||||||
|
arguments: [...command, "--capture-timeout-ms=0x1", "--json"],
|
||||||
|
});
|
||||||
|
expect(hexDeadline.exitCode).toBe(1);
|
||||||
|
expect(hexDeadline.json).toMatchObject({
|
||||||
|
code: "VALIDATION_ERROR",
|
||||||
|
fieldErrors: [expect.objectContaining({ path: "captureTimeoutMs" })],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const noDirectory = await cli.run({
|
const noDirectory = await cli.run({
|
||||||
arguments: ["environment-build", har, "--json"],
|
arguments: ["environment-build", har, "--json"],
|
||||||
timeoutMs: 60_000,
|
timeoutMs: 60_000,
|
||||||
|
|||||||
Reference in new issue
Block a user