编号:C-07 严重级:low 工作线:消息核心(internal/app/message、serve 的 messageLoops) 来源:审查 M-16、M-18、I-16、M-19 依赖:第 4 点依赖 C-03 (#34)、C-04 (#35) 被依赖:无
keep
ttl_seconds<=0
bad_request
*DelayMs > MaxScheduleSeconds*1000
Send.Validate
enabled
unauthorized
AND gm.joined_at <= ?
completed_at
internal/app/message/submit.go、dispatch.go、recover.go;internal/protocol/validate.go;迁移文件。
internal/app/message/submit.go
dispatch.go
recover.go
internal/protocol/validate.go
submit.go 与 C-05、U-03 改不同位置;第 4 点依赖 C-03、C-04。
以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。解决方案以本 issue 上方的"结论与统一方案"为准;原文里的方案与之不一致时,按上方执行。
keep:true
expire_at
delay_ms
nowMs+delay
max_schedule_seconds
submit.go:52-54
submit.go:301
protocol/validate.go:57-65
ttl<=0
Submit
submit.go:65-71
submit.go:203-211
snd.Enabled
joined_at <= send_at
message/dispatch.go:90-94
cmd/nixmsg/serve.go:322-333
message/dispatch.go
created_at < now-7天
recover.go:81-89
internal/app/message/dispatch.go
复审基线:main 4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。
4059a15
已合入 origin/main 0c9b459。落地提交 659373e fix: 补提交校验、停用检查、入群过滤与按完成时刻清理 (#38)。
0c9b459
659373e
No dependencies set.
The note is not visible to the blocked user.
编号:C-07 严重级:low 工作线:消息核心(internal/app/message、serve 的 messageLoops) 来源:审查 M-16、M-18、I-16、M-19
依赖:第 4 点依赖 C-03 (#34)、C-04 (#35) 被依赖:无
结论与统一方案
keep时ttl_seconds<=0返回bad_request;先判断*DelayMs > MaxScheduleSeconds*1000再做加法;Send.Validate同步补上。(审查 M-16)enabled,已停用就拒绝,错误码建议unauthorized并记入 DEVIATIONS。(审查 M-18)AND gm.joined_at <= ?(参数为 send_at),PRD F06"发送时刻之后才入群的端收不到"。(审查 I-16)completed_at列,所有完成路径(配合 C-04 的统一函数)写入,清理按completed_at判断,并在 DEVELOPMENT 7.6 写明口径。迁移号排在 C-03 的 0003 之后,或与 C-03 合并。(审查 M-19)改动文件
internal/app/message/submit.go、dispatch.go、recover.go;internal/protocol/validate.go;迁移文件。与其他问题的交互 / 冲突说明
submit.go 与 C-05、U-03 改不同位置;第 4 点依赖 C-03、C-04。
验收与测试
问题明细(各区审查原文,证据含文件与行号)
[M-16] 发送参数边界校验缺失:ttl_seconds 可以为 0 或负数,delay_ms 溢出后变成立即发送
keep:true配ttl_seconds<=0会被接受,expire_at落在过去,结果取决于推送和清理谁先执行。delay_ms使nowMs+delay溢出成负数,绕过max_schedule_seconds检查,变成立即发送。submit.go:52-54(只查上限)、submit.go:301;protocol/validate.go:57-65。ttl<=0返回bad_request;先判断*DelayMs > MaxScheduleSeconds*1000再做加法;协议包的Send.Validate同步补上。internal/app/message/submit.go(以及协议包,属共享文件)。[M-18] 提交时不检查发送方是否已停用
Submit在事务内外都没有检查发送方的enabled。停用写库完成到连接真正断开之间(发 fatal 后约 20 毫秒),上行队列里已经排着的 send 仍会被接受并投递;如果停用时恰好碰上重连(踢线没找到连接),窗口会更长。submit.go:65-71、submit.go:203-211。snd.Enabled,已停用就拒绝。错误码建议用unauthorized,并记入 DEVIATIONS。internal/app/message/submit.go。[I-16] 群消息分发不按入群时间过滤(跨模块)
joined_at <= send_at条件。分发由每秒一次的循环执行,每轮最多 100 条。在发送时刻和实际分发之间入群的人(通常不到 1 秒,积压时可达分钟级)会收到入群前发出的消息。message/dispatch.go:90-94;cmd/nixmsg/serve.go:322-333。AND gm.joined_at <= ?,参数为 send_at。message/dispatch.go(消息线)。[M-19] 记录保留期按创建时间算:长定时、长保留的消息一完成就被清掉
created_at < now-7天。一条 30 天保留、第 29 天才被收下的消息,或者一条 365 天后的定时消息,完成后下一次清理就被删掉,后台看不到它的最终结果。recover.go:81-89。completed_at列(迁移),所有完成路径(配合 M-06 的统一函数)都写入它,清理按completed_at判断;同时在 DEVELOPMENT 7.6 写明口径。internal/app/message/dispatch.go、recover.go;迁移文件(共享)。复审基线:main
4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。已合入 origin/main
0c9b459。落地提交659373efix: 补提交校验、停用检查、入群过滤与按完成时刻清理 (#38)。