本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:暂存20260913/audit_comments_review.md。
审计代号注释审查清单
审查范围:app/ 下所有 PHP 文件
审查目标:找出所有包含审计代号(如 M5、P2、L1 等字母+数字组合)的注释
后续动作:将代号注释替换为通俗中文"防御意图"说明,仅改注释,不碰代码逻辑
涉及审计代号种类
M5, M-1, M-2, M-3, P0, P1, P2, P3, P4, P7, P41, L1, L2, L3, L4, S2, S3, S5, D1, D3, D4, D5, D6, H1, H-3, H-4, E2, E4, F1, F2, G1, G3, G4, G5
文件清单(19 个 PHP 文件,约 48 处)
1. app/Core/Model.php — 7 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 16 | M5/P2 | /** 可更新列白名单(M5/P2):子类必须声明;update() 对白名单外键忽略并记日志(fail-closed) */ | 防批量赋值 |
| 89 | M5/P2 | * 更新记录(M5/P2:$fillable 列白名单,fail-closed 防批量赋值面) | 防批量赋值 |
| 94 | L1 | * 空 $data / 全部键被白名单过滤时返回 0(L1:不拼出 'SET WHERE' 非法 SQL)。 | 防非法 SQL |
| 110 | L1 | return 0; // L1:无任何可更新列,不拼非法 SQL | 防非法 SQL |
| 122 | L1 | return 0; // L1:全部键被过滤 → 无 SET 子句 | 防非法 SQL |
| 137 | L3 | * 统计(L3:非字符串条件显式走 buildWhere,其余类型抛错,杜绝 'WHERE Array') | 防类型混淆 |
| 204 | L2 | // L2:空数组/全非法键 → fail-closed,与字符串分支一致,绝不回退 WHERE 1 全表匹配 | 防全表匹配 |
2. app/Core/Database.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 90 | G5 | // G5:ERRMODE_EXCEPTION 下 prepare() 失败必抛异常,不再需要 if (!$stmt) 死代码检查 | 防静默失败 |
3. app/Helpers/Plugin.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 89 | H-3/P2 | // - 全局开关 permission_enforce(后台设置,默认 1=强制模式,H-3/P2):未声明权限的操作被拒绝; | 权限强制 |
4. app/Helpers/Search.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 124 | P0 | // 因 $i=0 < $offset 立即退出循环,导致第 2 页起永远无数据(P0) | 分页逻辑缺陷修复 |
5. app/Helpers/Settings.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 742 | P7 | * 替代详情页原先 getThreadAttachments + getPostAttachments 两次独立查询(P7)。 | 查询优化 |
6. app/Models/Blog.php — 2 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 16 | M5/P2 | /** 可更新列白名单(M5/P2):前台博客编辑走基类 update() */ | 防批量赋值 |
| 137 | M-2/P2 | * 删除单条博客评论(M-2/P2):mod_system 等插件侧评论删除统一走 Model 封装, | 收敛写入口 |
7. app/Models/BlogCategory.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 16 | M5/P2 | /** 可更新列白名单(M5/P2):后台博客分类编辑走基类 update() */ | 防批量赋值 |
8. app/Models/Category.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 16 | M5/P2 | /** 可更新列白名单(M5/P2):后台版块编辑 + smoke 用例共用 */ | 防批量赋值 |
9. app/Models/Post.php — 6 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 22 | P3/P4 | /** 兼容保留:business.sqlite 的 posts 表(P3 过渡遗留,P4 起不再写入) */ | 废弃表标注 |
| 50 | E2/E4 | // 归档/删除守卫(E2/E4):父帖已归档…或已软删 → 拒绝插入回复。 | 防写入已归档帖 |
| 163 | D4 | // 100%:拒绝写入(最终防线,D4 已确认) | 桶满载拒绝写入 |
| 164 | D6 | // D6:文案修正——原「请联系管理员扩容」误导… | 文案准确性 |
| 239 | G1 | // G1:只统计未删除回复(status=0),楼层数不含软删 | 数据一致性 |
| 356 | D3 | /** 缓存上限(D3):常驻 worker(CLI/AI)下无上限会持续内存膨胀;超限按 FIFO 淘汰最旧 */ | 防内存膨胀 |
10. app/Models/Thread.php — 7 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 24 | P3/P4 | /** 兼容保留:business.sqlite 的 threads 表(P3 过渡遗留,P4 起不再写入) */ | 废弃表标注 |
| 414 | D4 | // 空 SET 守卫(D4):调用方字段均不在白名单且无正文变更时 $setSql 为空, | 防非法 SQL |
| 676 | G3 | // G3:文件名非法(非白名单字符)时不再静默跳过——记日志… | 防路径穿越 |
| 732 | D5 | // 硬删时再按全量递减会造成重复扣减(D5) | 防计数重复扣减 |
| 1007 | G4 | // G4:空 catch 补日志,避免「摘要莫名为空但无迹可查」 | 防静默失败 |
| 1018 | D3 | $memoMax = 500; // 缓存上限(D3):常驻 worker 下无上限持续内存膨胀;超限按 FIFO 淘汰最旧 | 防内存膨胀 |
| 1092 | D3 | array_shift($memo); // FIFO 淘汰最旧条目(D3) | 防内存膨胀 |
11. app/Models/User.php — 6 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 16 | M5/P2 | /** 可更新列白名单(M5/P2):仅 updateLoginTime 走基类 update() */ | 防批量赋值 |
| 323 | M-1/P2 | * 批量取用户名(M-1/P2):插件侧名称补全统一走 Model,不直查核心库 users 表。 | 收敛读入口 |
| 339 | M-1/P2 | * 批量取用户展示信息(用户名+头像+等级,M-1/P2):请求级缓存… | 收敛读入口 |
| 381 | M-1/P2 | * 批量按用户名查用户 ID(M-1/P2 补齐):插件 @提及 等反向批量查询统一走 Model… | 收敛读入口 |
| 477 | H-4/P2 | * 仅更新用户组(H-4/P2):封禁/解封等插件侧组迁移统一走 Model,不绕模型直写 users 表。 | 收敛写入口 |
| 579 | M3/P2 | // M3/P2:与 Thread::hardDelete 同款文件名白名单(防 path 穿越), | 防路径穿越 |
12. app/Controllers/Admin/DashboardController.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 31 | P4 | // business.threads 表已退役(P4 起不再写入),直查该表对分片后新帖恒为空。 | 废弃表标注 |
13. app/Controllers/AttachmentController.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 47 | P4 | // business.sqlite 的 threads 表已退役(P4 起不再写入),LEFT JOIN 旧表对新帖恒为 NULL, | 废弃表标注/防越权 |
14. app/Controllers/ThreadController.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 199 | P7 | // 一次查询取回主楼 + 回帖附件(替代原先两次独立查询,P7) | 查询优化 |
15. app/SplitDB/BucketAutoScaler.php — 4 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 40 | P3 | // P3:config.php 存在但正则匹配失败 → 发声… | 防静默失败 |
| 70 | L3 | // L3:mkdir 失败必须发声,否则 fopen 会静默失败导致「以为拿到锁、实际没锁」并发写坏 | 防锁失效 |
| 83 | L3 | // L3:mkdir 失败必须发声,否则备份 @copy 静默失败且后续无备份可用 | 防备份丢失 |
| 171 | P3 | // P3:$value 只允许纯数字(常量值拼进 config.php 前必须白名单校验… | 防配置注入 |
16. app/SplitDB/IDGenerator.php — 6 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 51 | L4/P2 | // L4/P2:global_id 连接单独下调写锁等待… | 写锁超时控制 |
| 55 | F1 | // F1:放弃 spl_object_id 缓存「已设置」标记——连接池淘汰重建后对象 id 可能被复用… | 防缓存误命中 |
| 70 | F2 | // F2:区分错误类型——仅「写锁竞争/busy」才重试; | 精确错误分类 |
| 84 | L4/P2 | // L4/P2:取号超时埋点告警(写锁竞争持续阻塞) | 写锁超时告警 |
| 101 | F2 | // F2:仅写锁竞争(database is locked)→ 回滚重试;其它 PDO 错误直接抛出 | 精确错误分类 |
| 114 | L4/P2 | // L4/P2:取号超时埋点告警(写锁竞争持续阻塞) | 写锁超时告警 |
17. app/SplitDB/Schema.php — 6 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 119 | S3 | // S3:防护文件写入失败必须发声(安全控制 fail-silent = 数据目录裸奔无感知) | 防静默裸奔 |
| 145 | S3 | // S3:防护文件写入失败必须发声(IIS 下 data 目录可能可直访) | 防静默裸奔 |
| 607 | D1 | // D1(每请求固定税修复):补列探测 + audit_logs 回填只需在「首次/升级」执行一次—— | 消除每请求开销 |
| 624 | S5 | // S5:升级瞬间多请求并发进入…并发 ALTER,后者抛 "duplicate column name"——捕获并跳过 | 防并发 ALTER 冲突 |
| 823 | S2 | // S2:^...$ 锚定(防御深度),防止畸形前缀/后缀混入路径仍被当作桶路径打开 | 防路径绕过 |
| 841 | H1 | // H1:mkdir 失败必须发声(目录不可写等),否则后续 DBFactory 打开会抛隐晦错误 | 防静默失败 |
18. app/SplitDB/ShardRouter.php — 4 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 74 | D3/P41 | * [P41] 新帖写入路由(智能扩容路由策略,D3 已确认) | 路由策略标注 |
| 164 | S2 | // S2:^...$ 锚定(防御深度),防止畸形前缀/后缀混入路径仍被解析出桶号 | 防路径绕过 |
| 178 | H1 | // H1:mkdir 失败必须发声,否则后续打开库会抛更隐晦的错误(目录不存在) | 防静默失败 |
| 192 | H1 | // H1:mkdir 失败必须发声,否则正文写入会在更深层抛隐晦错误 | 防静默失败 |
19. app/SplitDB/SearchIndexStore.php — 1 处
| 行 | 审计代号 | 当前注释 | 防御意图 |
|---|
| 322 | P1 | // P1 高频词 OOM 修复:原实现逐行 fetchColumn 把全部 target_id 拉进 PHP 数组去重… | 防 OOM |
已排除项(不修改)
| 文件 | 排除原因 |
|---|
app/SplitDB/SplitDB_Code_Audit_Report.html | 审计报告文档本身,不是代码注释 |
app/Views/home/FlintHub 燧石门户首页原型.html | HTML 原型文件中的 M14、M12 等是 SVG 路径命令,不是审计代号 |
修改原则
- 只改注释文字,绝对不修改任何 PHP 代码逻辑
- 将审计代号(如
M5/P2、L1、D4)替换为通俗易懂的中文"防御意图"说明 - 修改完成后对每个文件跑
php -l 确认语法无报错
状态