fix(aibox): round-5 audit batch K - max_turns clamp, task input validation, XSS hardening, atomic writes, broadcast timeout

第五轮审计(J1~J16)全量修复 + 子代理 max_turns 钳制:
- 子代理 max_turns 钳制(0/None 回退默认 10,负数钳制 1)+ 14 项回归测试
- J1 任务系统投毒:add_memo 入库校验(时间/间隔/类型)、调度器预检与触发事务
  防御、展示路径兜底、register 移入 try、add_user_task 补 repeat_end_time 透传
- J2/J13 前端 XSS:三页面 marked 输出经 DOMPurify 净化、entry1 系统消息/任务
  分隔条改 textContent、CDN 脚本补 SRI
- J3 FTS 删除换序(先 fts 后内容表,索引不再残留)
- J5 原子写推广:新增 common/atomic.py(mkstemp+fsync+os.replace),config/prompt/
  history 全部接入;损坏配置备份后回退
- J6 单例初始化加锁(PromptManager/ConfigManager 并发首例不双重加载)
- J7 broadcast 并发发送 + wait_for 超时回收僵死连接
- J4/J8/J9~J12/J14~J16:验证异常脱敏、交互输入容错、MemoDatabase WAL+busy_timeout、
  memo 批量删除、/new 竞态、skills 引号转义、voice_client 清理、死代码移除、
  skill_manager 同名键/help 截断
This commit is contained in:
qing committed 2026-08-19 07:01:13 +08:00
1 parent f4fcf175ec
commit 457bb900fb
22 files changed
+1147 -126

No files matched your search

+11 -1
View File
@@ -174,7 +174,17 @@ class TestF5LightSubagentCancel:
class TestQ5MalformedReminderTime:
def test_malformed_time_task_returned_as_due(self, tmp_path):
db = MemoDatabase(db_path=str(tmp_path / "m.db"))
mid = db.add_memo(title="格式异常", content="c", reminder_time="不是时间")
# J1(审计 2026-08-19):add_memo 已拒绝畸形时间(入库校验),
# 模拟校验落地前的存量脏数据需绕过 add_memo 直接 SQL 插入
import sqlite3
with sqlite3.connect(str(tmp_path / "m.db")) as conn:
cur = conn.cursor()
cur.execute('''INSERT INTO memos
(title, content, created_at, reminder_time, is_completed, source,
repeat_type, repeat_interval, repeat_interval_unit, is_immediate)
VALUES (?, ?, ?, ?, 0, 'test', 'none', 0, 'days', 0)''',
("格式异常", "c", "2026-08-18 00:00:00", "不是时间"))
mid = cur.lastrowid
pending = db.get_pending_memos(before_time="2026-08-18 00:00:00")
assert any(m["id"] == mid for m in pending)