From 96b5811dc11292399ef7612f5883b4e8b179a935 Mon Sep 17 00:00:00 2001 From: Jeon Suyeol Date: Fri, 6 Mar 2026 12:16:34 +0900 Subject: [PATCH] use Map for alias lookup to prevent prototype pollution, return undefined for non-Claude bare models --- .../claude-model-mapper.test.ts | 18 ++++++++++++++---- .../claude-model-mapper.ts | 14 +++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/features/claude-code-agent-loader/claude-model-mapper.test.ts b/src/features/claude-code-agent-loader/claude-model-mapper.test.ts index b3da88759..c01075d60 100644 --- a/src/features/claude-code-agent-loader/claude-model-mapper.test.ts +++ b/src/features/claude-code-agent-loader/claude-model-mapper.test.ts @@ -79,12 +79,22 @@ describe("mapClaudeModelToOpenCode", () => { }) describe("#given non-Claude bare model", () => { - it("#when called with gpt-5.2 #then normalizes dots without adding prefix", () => { - expect(mapClaudeModelToOpenCode("gpt-5.2")).toBe("gpt-5-2") + it("#when called with gpt-5.2 #then returns undefined", () => { + expect(mapClaudeModelToOpenCode("gpt-5.2")).toBeUndefined() }) - it("#when called with gemini-3-flash #then returns unchanged", () => { - expect(mapClaudeModelToOpenCode("gemini-3-flash")).toBe("gemini-3-flash") + it("#when called with gemini-3-flash #then returns undefined", () => { + expect(mapClaudeModelToOpenCode("gemini-3-flash")).toBeUndefined() + }) + }) + + describe("#given prototype property name", () => { + it("#when called with constructor #then returns undefined", () => { + expect(mapClaudeModelToOpenCode("constructor")).toBeUndefined() + }) + + it("#when called with toString #then returns undefined", () => { + expect(mapClaudeModelToOpenCode("toString")).toBeUndefined() }) }) diff --git a/src/features/claude-code-agent-loader/claude-model-mapper.ts b/src/features/claude-code-agent-loader/claude-model-mapper.ts index 6d9b120d2..ebdbd3c86 100644 --- a/src/features/claude-code-agent-loader/claude-model-mapper.ts +++ b/src/features/claude-code-agent-loader/claude-model-mapper.ts @@ -2,11 +2,11 @@ import { normalizeModelID } from "../../shared/model-normalization" const ANTHROPIC_PREFIX = "anthropic/" -const CLAUDE_CODE_ALIAS_MAP: Record = { - sonnet: `${ANTHROPIC_PREFIX}claude-sonnet-4-6`, - opus: `${ANTHROPIC_PREFIX}claude-opus-4-6`, - haiku: `${ANTHROPIC_PREFIX}claude-haiku-4-5`, -} +const CLAUDE_CODE_ALIAS_MAP = new Map([ + ["sonnet", `${ANTHROPIC_PREFIX}claude-sonnet-4-6`], + ["opus", `${ANTHROPIC_PREFIX}claude-opus-4-6`], + ["haiku", `${ANTHROPIC_PREFIX}claude-haiku-4-5`], +]) export function mapClaudeModelToOpenCode(model: string | undefined): string | undefined { if (!model) return undefined @@ -16,7 +16,7 @@ export function mapClaudeModelToOpenCode(model: string | undefined): string | un if (trimmed === "inherit") return undefined - const aliasResult = CLAUDE_CODE_ALIAS_MAP[trimmed.toLowerCase()] + const aliasResult = CLAUDE_CODE_ALIAS_MAP.get(trimmed.toLowerCase()) if (aliasResult) return aliasResult if (trimmed.includes("/")) return trimmed @@ -27,5 +27,5 @@ export function mapClaudeModelToOpenCode(model: string | undefined): string | un return `${ANTHROPIC_PREFIX}${normalized}` } - return normalized + return undefined }