fix: 代码审查问题修复
- C1 (Critical): 添加 PyYAML 解析 frontmatter,支持多行值和列表 - M1 (Major): 添加 FTS5 查询验证,防止注入攻击 - M2/M3 (Major): 工具类使用显式 wiki_vault_path 参数 - M4 (Major): 集成 aiofiles 实现真正的异步文件 I/O - M5 (Major): 改用 logger.exception() 记录完整堆栈 Co-Authored-By: Claude Dev <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,14 @@ from typing import List, Dict, Optional, Tuple
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import yaml
|
||||
YAML_AVAILABLE = True
|
||||
except ImportError:
|
||||
YAML_AVAILABLE = False
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.warning("PyYAML not available, using simple parser")
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -30,7 +38,7 @@ class ParserService:
|
||||
|
||||
def parse_frontmatter(self, content: str) -> Dict:
|
||||
"""
|
||||
解析 frontmatter
|
||||
解析 frontmatter(使用 PyYAML)
|
||||
|
||||
返回格式:
|
||||
{
|
||||
@@ -45,14 +53,28 @@ class ParserService:
|
||||
|
||||
if match:
|
||||
yaml_content = match.group(1)
|
||||
# 简单解析(对于复杂情况,应该使用 PyYAML)
|
||||
for line in yaml_content.split('\n'):
|
||||
if ':' in line:
|
||||
key, value = line.split(':', 1)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
frontmatter[key] = value
|
||||
|
||||
# 使用 PyYAML 进行完整解析
|
||||
if YAML_AVAILABLE:
|
||||
try:
|
||||
frontmatter = yaml.safe_load(yaml_content) or {}
|
||||
except yaml.YAMLError as e:
|
||||
logger.warning(f"Failed to parse YAML: {e}")
|
||||
frontmatter = self._simple_parse(yaml_content)
|
||||
else:
|
||||
frontmatter = self._simple_parse(yaml_content)
|
||||
|
||||
return frontmatter
|
||||
|
||||
def _simple_parse(self, yaml_content: str) -> Dict:
|
||||
"""简单 YAML 解析(fallback)"""
|
||||
frontmatter = {}
|
||||
for line in yaml_content.split('\n'):
|
||||
if ':' in line:
|
||||
key, value = line.split(':', 1)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
frontmatter[key] = value
|
||||
return frontmatter
|
||||
|
||||
def extract_links(self, content: str) -> List[str]:
|
||||
@@ -71,20 +93,25 @@ class ParserService:
|
||||
支持:
|
||||
- tags: ["tag1", "tag2"]
|
||||
- tags: [tag1, tag2]
|
||||
- YAML 列表格式
|
||||
"""
|
||||
tags = []
|
||||
match = self.TAG_PATTERN.search(content)
|
||||
frontmatter = self.parse_frontmatter(content)
|
||||
|
||||
if match:
|
||||
tag_content = match.group(1)
|
||||
# 尝试 JSON 解析
|
||||
try:
|
||||
tags = json.loads(f"[{tag_content}]")
|
||||
except:
|
||||
# 简单逗号分隔
|
||||
tags = [t.strip().strip('"\'') for t in tag_content.split(',')]
|
||||
if "tags" in frontmatter:
|
||||
tags_value = frontmatter["tags"]
|
||||
|
||||
return tags
|
||||
if isinstance(tags_value, list):
|
||||
tags = tags_value
|
||||
elif isinstance(tags_value, str):
|
||||
# 尝试解析字符串格式的标签
|
||||
try:
|
||||
tags = json.loads(tags_value) if tags_value.startswith('[') else tags_value.split(',')
|
||||
except:
|
||||
tags = [tags_value]
|
||||
|
||||
# 确保 tags 是字符串列表
|
||||
return [str(tag).strip() for tag in tags if tag]
|
||||
|
||||
def extract_title(self, content: str) -> str:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user