diff --git a/.changeset/strict-vis-port-values.md b/.changeset/strict-vis-port-values.md new file mode 100644 index 0000000000..12ee4dd252 --- /dev/null +++ b/.changeset/strict-vis-port-values.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Reject malformed port values for the session visualizer command. diff --git a/apps/kimi-code/src/cli/sub/vis.ts b/apps/kimi-code/src/cli/sub/vis.ts index 7e6f2e1f25..938082c0ab 100644 --- a/apps/kimi-code/src/cli/sub/vis.ts +++ b/apps/kimi-code/src/cli/sub/vis.ts @@ -113,17 +113,28 @@ export function registerVisCommand(parent: Command, overrides?: Partial sessionId: string | undefined, options: { port?: string; host?: string; open?: boolean }, ) => { - const port = options.port === undefined ? undefined : Number.parseInt(options.port, 10); await handleVis(createDefaultVisDeps(overrides), { open: options.open !== false, - ...(port === undefined || Number.isNaN(port) ? {} : { port }), - ...(options.host === undefined ? {} : { host: options.host }), - ...(sessionId === undefined ? {} : { sessionId }), + port: parseVisPort(options.port), + host: options.host, + sessionId, }); }, ); } +export function parseVisPort(raw: string | undefined): number | undefined { + if (raw === undefined) return undefined; + if (!/^\d+$/.test(raw)) { + throw new Error(`error: invalid --port value: ${raw}`); + } + const port = Number.parseInt(raw, 10); + if (!Number.isFinite(port) || port < 0 || port > 65535) { + throw new Error(`error: invalid --port value: ${raw}`); + } + return port; +} + function createDefaultVisDeps(overrides: Partial = {}): VisDeps { return { getHomeDir: overrides.getHomeDir ?? (() => createCliTelemetryBootstrap().homeDir), diff --git a/apps/kimi-code/test/cli/vis.test.ts b/apps/kimi-code/test/cli/vis.test.ts index b611e6a372..f7dbe3c895 100644 --- a/apps/kimi-code/test/cli/vis.test.ts +++ b/apps/kimi-code/test/cli/vis.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect, vi } from 'vitest'; -import { handleVis, type VisDeps } from '#/cli/sub/vis'; +import { handleVis, parseVisPort, type VisDeps } from '#/cli/sub/vis'; function makeDeps(over: Partial = {}): { deps: VisDeps; @@ -112,3 +112,13 @@ describe('handleVis', () => { expect(deps.waitForShutdown).not.toHaveBeenCalled(); }); }); + +describe('parseVisPort', () => { + it('rejects malformed port values', () => { + expect(parseVisPort(undefined)).toBeUndefined(); + expect(parseVisPort('8080')).toBe(8080); + expect(() => parseVisPort('123abc')).toThrow(/invalid --port/); + expect(() => parseVisPort('1.5')).toThrow(/invalid --port/); + expect(() => parseVisPort('99999')).toThrow(/invalid --port/); + }); +});