{"record":{"id":"529277afd2b4f7b4","repo":"BigPizzaV3/CodexPlusPlus","slug":"theme-css-skin-api-data-ds-part","errorCode":null,"errorMessage":"theme.css 只能选择 Skin API 注册的 data-ds-part","messagePattern":"theme\\.css 只能选择 Skin API 注册的 data-ds-part","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin_package.rs","lineNumber":329,"sourceCode":"        let open = rest.find('{').context(\"theme.css 规则缺少开始括号\")?;\n        let selector = rest[..open].trim();\n        if selector.is_empty()\n            || selector.contains([',', '@', ';', '}'])\n            || rest[open + 1..].find('{').is_some_and(|nested| {\n                rest[open + 1..]\n                    .find('}')\n                    .is_none_or(|close| nested < close)\n            })\n        {\n            bail!(\"theme.css 选择器或规则语法无效\");\n        }\n        let close = open\n            + 1\n            + rest[open + 1..]\n                .find('}')\n                .context(\"theme.css 规则缺少结束括号\")?;\n        let Some(after_prefix) = selector.strip_prefix(\"[data-ds-part=\\\"\") else {\n            bail!(\"theme.css 只能选择 Skin API 注册的 data-ds-part\");\n        };\n        let (part, suffix) = after_prefix\n            .split_once(\"\\\"]\")\n            .context(\"theme.css data-ds-part 语法无效\")?;\n        if !allowed_parts.contains(&part)\n            || (!suffix.is_empty() && suffix != \":hover\" && suffix != \":focus-visible\")\n        {\n            bail!(\"theme.css 使用了未注册的 Skin API part 或状态\");\n        }\n\n        let mut rule_declarations = Vec::new();\n        let mut seen = HashSet::new();\n        for declaration in rest[open + 1..close]\n            .split(';')\n            .map(str::trim)\n            .filter(|value| !value.is_empty())\n        {\n            let (property, value) = declaration","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin_package.rs#L311-L347","documentation":"Selector whitelist guard in parse_safe_css: the selector does not begin with the literal prefix [data-ds-part=\". The Safe CSS engine only styles elements registered through the Skin API via data-ds-part attributes; arbitrary selectors (tag, class, id) are refused.","triggerScenarios":"Thrown at crates/codex-plus-core/src/dream_skin_package.rs:329 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rewrite selectors as [data-ds-part=\"<registered part>\"]","Style only Skin API registered parts"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}