diff --git a/packages/cli/src/linter/model/color-parser.ts b/packages/cli/src/linter/model/color-parser.ts index f1a5206..f7127e1 100644 --- a/packages/cli/src/linter/model/color-parser.ts +++ b/packages/cli/src/linter/model/color-parser.ts @@ -60,6 +60,7 @@ const CSS_NAMED_COLORS: Record = { * Returns null if the color is invalid. */ export function parseCssColor(colorStr: string): ParsedColorResult | null { + if (typeof colorStr !== 'string') return null; const clean = colorStr.trim().toLowerCase(); if (!clean) return null; diff --git a/packages/cli/src/linter/model/handler.ts b/packages/cli/src/linter/model/handler.ts index caca7e4..8cfd71c 100644 --- a/packages/cli/src/linter/model/handler.ts +++ b/packages/cli/src/linter/model/handler.ts @@ -178,9 +178,10 @@ export class ModelHandler implements ModelSpec { for (const [propName, rawValue] of Object.entries(props)) { // Numeric values (e.g. fontWeight: 600, borderWidth: 1) are valid - // per spec and must be stored as-is, coercing to string first - // would cause isTokenReference / isValidColor to call .match() on - // a number and crash with "raw.match is not a function". + // per spec and must be stored as-is. We check for 'number' here, + // but isTokenReference, isValidColor, and isParseableDimension + // are also guarded against other non-string types (like booleans) + // to prevent crashes like "raw.match is not a function". if (typeof rawValue === 'number') { properties.set(propName, rawValue); } else if (isTokenReference(rawValue)) { diff --git a/packages/cli/src/linter/model/spec.ts b/packages/cli/src/linter/model/spec.ts index 0b390f6..915278f 100644 --- a/packages/cli/src/linter/model/spec.ts +++ b/packages/cli/src/linter/model/spec.ts @@ -142,6 +142,7 @@ const CSS_UNITS = new Set([ * Returns null for non-dimension strings (bare numbers, keywords like `auto`). */ export function parseDimensionParts(raw: string): { value: number; unit: string } | null { + if (typeof raw !== 'string') return null; const match = raw.match(/^(-?\d*\.?\d+)([a-zA-Z%]+)$/); if (!match) return null; const value = parseFloat(match[1]!);