diff --git a/dev-workflow/dev_workflow.py b/dev-workflow/dev_workflow.py index 16ff155..a59a42f 100644 --- a/dev-workflow/dev_workflow.py +++ b/dev-workflow/dev_workflow.py @@ -29,7 +29,15 @@ def cmd_record_event(args): for item in args.metadata: if '=' in item: key, value = item.split('=', 1) + # 白名单校验:只允许字母、数字、下划线、连字符、点、空格 + import re + if not re.match(r'^[\w\-\. \u4e00-\u9fff]+$', value): + print(f"⚠️ 警告: metadata 值 '{value}' 包含不允许的字符,将被转义", file=sys.stderr) + # 转义特殊字符,只保留安全字符 + value = re.sub(r'[^\w\-\. \u4e00-\u9fff]', '_', value) metadata[key] = value + else: + print(f"⚠️ 警告: 无效的 metadata 格式 '{item}',应为 key=value 格式,已忽略", file=sys.stderr) # 记录事件 record_event( diff --git a/dev-workflow/stats.py b/dev-workflow/stats.py index 3b5d1e8..d405533 100644 --- a/dev-workflow/stats.py +++ b/dev-workflow/stats.py @@ -6,6 +6,7 @@ Cross-Debate 统计报告模块 import json import os +import sys import fcntl from datetime import datetime, timezone from pathlib import Path @@ -49,6 +50,12 @@ class StatsManager: filtered[key] = '***REDACTED***' elif isinstance(value, dict): filtered[key] = self._filter_sensitive_data(value) + elif isinstance(value, list): + # 处理列表中的字典元素 + filtered[key] = [ + self._filter_sensitive_data(item) if isinstance(item, dict) else item + for item in value + ] else: filtered[key] = value return filtered @@ -75,7 +82,12 @@ class StatsManager: # 获取共享锁(读锁) fcntl.flock(f.fileno(), fcntl.LOCK_SH) try: - data = json.load(f) + try: + data = json.load(f) + except json.JSONDecodeError as e: + # 文件损坏时返回空数据结构 + print(f"⚠️ 警告: 统计文件损坏,将返回空数据: {e}", file=sys.stderr) + return {"events": []} finally: # 释放锁 fcntl.flock(f.fileno(), fcntl.LOCK_UN)