Skip to content

fix: 批1 缺陷修复——哨兵穿透/溢出/EOF 契约/尾点变体/2038 截断/构造期校验(#383 #388 #389 #406 #407 #408 #413) - #421

Merged
zy84338719 merged 3 commits into
mainfrom
sweep/20261112-l1
Nov 12, 2026

Conversation

@zy84338719

Copy link
Copy Markdown
Contributor

清零战役 pkg 侧批 1(缺陷修复)。7 单逐条:

#383 timex/cron WrapSchedule 破坏零值哨兵契约

WrapSchedule.Next 对内层返回的零值 time.Time 短路直返(哨兵穿透组合子)。此前 time.Time{}.Add(delay) 是公元 1 年+delay 的非零时刻——不可满足表达式(0 0 31 2 *)经包装后 IsZero 判定失效 → time.Until 极大负值 → 立即触发 → 内层从远古重扫 5 年 → 调度器热转。godoc 写明穿透契约;用例钉住「不可满足 spec + Wrap → 仍返回零值」。

#388 timex.GetCurrentTime 返回 int(32 位 2038 截断)

签名改 int64 对齐同族(GetCurrentDayStartTime/Date2Stamp/StampInt2Date 均 int64);0.x minor 允许 breaking,不留并行入口。顺带 TimestampString 的 fmt.Sprintf 分配面改 strconv.FormatInt。测试编译期锁定宽度。

#389 pack.NewWriter 不校验 formatVersion

构造期 panic(fail-fast 总则①,同 webhook/memgroup/cron 口径);AddJSONL 里的延迟校验+永久毒化分支删除。

#406 bufiox DefaultReader.ReadBinary 部分读错误契约

新增 partialReadErr 归一:n>0 且终态 io.EOF ⇒ io.ErrUnexpectedEOF(契约),n==0 保持 io.EOF。此前同一逻辑情形(读到了部分字节、随后流到头)的错误取决于剩余字节此前是否在缓冲里——acquire 路径与直读粘滞路径把底层 io.EOF 原样上抛,截断帧被下游当正常流尾。三个此前返回 io.EOF 的形态 + 两个契约基线(读满 nil、空流 EOF)全部有测试。

#407 resumable NumChunks 分子溢出

(Size-1)/ChunkSize + 1 数学等价且分子恒非负(先加后除在 Size 接近 MaxInt64 时先溢出回绕出负分片数);结果按 int 表示宽度饱和(32 位平台不回绕)。此前负分片数让 reconcile for i := range n 空过 → Complete 返回 nil 成功并交付 0 字节对象;现在同尺寸会话如实报 ErrMissingChunks,merge 不被调。端到端测试钉住。

#408 bufiox TailLines int64 乘法溢出

乘法前判上界(同 pagination 既有做法),乘积超 int64 时软上限饱和到 MaxInt64(永不生效——budget×4 已不可表示,任何行数都满足契约上界)。注释那句「int64:budget 极大时乘法不回绕」的错误安全感一并修正。budget∈{1024,1MB,2^61,2^62,MaxInt}×100 行全保留;正常预算下行数软上限仍生效的基线测试同附。

#413 urlguard 层 1 尾部分隔符变体放行

三处收口:① canonicalHost 剥全部 ASCII 尾点(TrimSuffix→TrimRight);② checkHostLiteral 拿到折叠产物后再剥一次尾点(全角尾分隔符 。.。→. 的折叠发生在剥点之后,此前折叠产物再也得不到剥点);③ looksLikeExoticIPv4 空段按候选处理(fail-closed)且先于段数上限判定。issue 实测的 22 个漏网 URL + 10 个 CheckHost 形态全组断言 BLOCKED;公网域名尾点放行与 #266 内部全角阻断两条基线保持。


验证:GOWORK=off go build/vet/test -race 全绿;gofmt 干净。

Fixes #383
Fixes #388
Fixes #389
Fixes #406
Fixes #407
Fixes #408
Fixes #413

- #383 cron WrapSchedule.Next 零值哨兵穿透:内层放弃(不可满足表达式)不再
  经包装变成公元 1 年+delay 的热循环
- #388 timex.GetCurrentTime 改 int64 对齐同族(32 位平台 2038 截断);
  TimestampString 改 strconv.FormatInt 免 Sprintf 分配
- #389 pack.NewWriter 构造期校验 formatVersion<=0 panic(fail-fast 总则①),
  删除 AddJSONL 里的延迟毒化分支
- #406 bufiox DefaultReader.ReadBinary 部分读撞 EOF 统一归一为
  io.ErrUnexpectedEOF(契约口径),无数据保持 (0, io.EOF)
- #407 resumable NumChunks 分子溢出治本:(Size-1)/ChunkSize+1 数学等价且
  恒非负,结果按 int 宽度饱和;溢出尺寸会话 Complete 如实报缺片不静默交付
- #408 bufiox TailLines 行数软上限乘法前判上界(饱和乘法,同 pagination
  口径),budget>=2^61 尾窗不再塌成 1 行
- #413 urlguard 尾部分隔符变体放行收口:canonicalHost 剥全部尾点 + 折叠
  产物重剥尾点 + exotic 判据空段按候选 fail-closed;全角尾点/双尾点回归表

每条修复配测试护栏(合计新增 5 个测试文件/6 处既有测试加固)。
golangci-lint staticcheck ST1023 拒绝 var stamp int64 = GetCurrentTime()
的显式类型声明;宽度锁定改用与 time.Now().Unix()(int64)的算术比较——
int 与 int64 无隐式转换,返回类型改回 int 时编译失败,钉子语义不变。
@zy84338719
zy84338719 merged commit 6391751 into main Nov 12, 2026
5 of 6 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in oekit PR 审查队列 Nov 12, 2026
This was referenced Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

1 participant