Files
DanDingNoneBot/review_reports/danding_qqpush_review.md
Mr.Xia c62ac37611 review: fix critical/medium bugs in 4 plugins (round 2)
group_horse_racing:
- settle_race: rewrite with 7 bug fixes (race condition, draw double-credit, empty participants, etc.)
- models.py: reorder fields for correct defaults, add indexes
- message_service: add logger import

danding_points:
- api.py: add finally blocks to 3 methods (add_points, get_history, get_leaderboard)
- database.py: add finally block to get_user_balance

chatai:
- __init__.py: deprecated API→asyncio.to_thread, deduplicate logging, taskkill filter for safety
- screenshot.py: XSS protection with bleach on HTML content
- requirements.txt: add bleach dependency

danding_qqpush:
- api.py L13: fix self-referencing _renderer NameError crash
- api.py: lazy singleton pattern via _get_renderer() instead of per-request ImageRenderer
- __init__.py: mask Token in log output (security)

All 34 tests pass.
2026-05-10 00:30:22 +08:00

2.9 KiB
Raw Permalink Blame History

danding_qqpush 评审报告

修复前问题清单 (5项)

# 严重度 问题 文件
1 严重 init_bot() 在模块加载时调用bot尚未连接必然失败 init.py
2 PIL 图片渲染在 async handler 中同步执行,阻塞 event loop api.py
3 Token 硬编码默认值 "danding-8HkL9xQ2" 泄露安全隐患 config.py
4 get_bot() 中 silent except 吞没错误,调试困难 sender.py
5 validate_token 使用 == 比较,存在时序攻击风险 utils.py

修复内容

init.py

  • 移除模块级 init_bot() 调用
  • 改为 @driver.on_bot_connect 异步钩子,确保 bot 就绪后再初始化
  • 移除未使用的 get_bots 导入

api.py

  • PIL render_to_base64() 包装为 asyncio.to_thread(),避免阻塞事件循环
  • 添加 import asyncio

config.py

  • Token 默认值改为空字符串,强制用户配置
  • FontPaths 列表默认值改为 tuple符合 Pydantic 最佳实践

sender.py

  • 添加 logger 导入
  • get_bot() 的 silent except 改为 logger.warning() 记录异常

utils.py

  • validate_token 改用 secrets.compare_digest() 防时序攻击

修复后验证 (12/12 ✓)

检查项 结果
init: on_bot_connect hook
init: no module-level init_bot()
init: model_dump not .dict()
api: asyncio.to_thread for PIL
api: asyncio import
config: no hardcoded token
config: FontPaths is tuple
sender: logger import
sender: no silent except
sender: logger.warning in get_bot
utils: secrets.compare_digest
text_parser: validate_text exists

代码质量总结

修复后评级:B+ (架构清晰安全问题已修复async处理合理)

第二轮修复 (新增4项)

# 严重度 问题 文件
6 严重 api.py L13 自引用 _renderer = _renderer,运行时 NameError 崩溃 api.py
7 严重 每次请求新建 ImageRenderer,加载字体文件,性能极差 api.py
8 __init__.py Token 明文输出到日志,信息泄露 init.py
9 image_render.py 双 Pilmoji 上下文,标题和正文各创建一次 image_render.py

修复详情

api.py

  • L13: _renderer = _renderer_renderer: Optional['ImageRenderer'] = None(修复 NameError
  • 新增 _get_renderer(config) 懒加载单例函数,首次调用创建,后续复用
  • _send_image_push_get_renderer(config).render_to_base64() 替代每次 ImageRenderer(config)
  • Optional 导入

init.py

  • Token 日志掩码:plugin_config.Token[:4] + "***"

测试结果

  • 34/34 通过(含原有 + 回归)