{"record":{"id":"7b2c5d5c225ec0bb","repo":"BigPizzaV3/CodexPlusPlus","slug":"name-7b2c5d","errorCode":null,"errorMessage":"主题包路径不安全：{name}","messagePattern":"主题包路径不安全：(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin_package.rs","lineNumber":819,"sourceCode":"            }\n            \"saturate\" => numeric(argument, \"\", 0.5, 2.0),\n            \"brightness\" | \"contrast\" => numeric(argument, \"\", 0.8, 1.5),\n            _ => false,\n        };\n        if !valid {\n            return false;\n        }\n    }\n    seen.contains(\"blur\")\n}\n\nfn parse_json<T: serde::de::DeserializeOwned>(bytes: &[u8], label: &str) -> anyhow::Result<T> {\n    serde_json::from_slice(bytes).with_context(|| format!(\"{label} 不是有效 JSON\"))\n}\n\nfn validate_archive_entry_name(name: &str) -> anyhow::Result<()> {\n    if name.is_empty() || name.starts_with('/') || name.contains('\\\\') {\n        bail!(\"主题包路径不安全：{name}\");\n    }\n    if name != name.trim()\n        || name.contains(['\\0', ':'])\n        || name.split('/').any(|part| part == \".\" || part == \"..\")\n        || (!name.starts_with(\"__MACOSX/\")\n            && name.split('/').filter(|part| !part.is_empty()).count() > 2)\n    {\n        bail!(\"主题包文件名不安全：{name}\");\n    }\n    Ok(())\n}\n\nfn normalize_package_entries(\n    entries: Vec<(String, Option<Vec<u8>>)>,\n) -> anyhow::Result<std::collections::BTreeMap<String, Vec<u8>>> {\n    let content_entries = entries\n        .into_iter()\n        .filter_map(|(name, content)| content.map(|content| (name, content)))","sourceCodeStart":801,"sourceCodeEnd":837,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin_package.rs#L801-L837","documentation":"Path-traversal guard in validate_archive_entry_name: the ZIP entry name is empty, starts with '/', or contains a backslash. Such names escape or subvert the package-root normalization, so they are rejected before any file is extracted.","triggerScenarios":"Thrown at crates/codex-plus-core/src/dream_skin_package.rs:819 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rebuild the ZIP with plain relative POSIX-style entry names","Remove entries with absolute or backslash paths"],"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-14T05:17:10.506Z"}