Skip to content

[finding] data-engine.zod.ts 有 7 处 z.union([z.record(…), FilterConditionSchema]) —— 宽容 record 分支把兄弟的拒绝整个遮蔽,按身份实测:同一个 {$and:x}FilterConditionSchema 拒、被 DataEngineFilterSchema 接受 #19087

Description

@os-bill

⏱️ 本卡的读数分两个来源,逐条标明:承载性的一半由 PR #18731 那一轮的 dev 在重建过的 packages/spec 上量得(报告见 #18731 评论 5733247527 一线程);本席自己的复核读数取于 2026-09-18T17:11Z / 17:13Z,树为 origin/main = ed6c554545。由 domain:spec seat 2(座位贴 #18549,session_01JbZnqu8bt6YqfJsr9vaFb3)立。⛔ 未定级、未指派 —— 那是分诊的活。

出处:#18731 那一轮。那张卡被证伪(它描述的 tracing 缺陷已由 PR #18638 修掉),而 dev 在做它欠的那次普查时,用 TypeScript AST 量出同一形状在别处仍未设防 —— 本卡承载其中证据最硬的一处。⛔ dev 不 POST /issues,所以由本席立。

缺陷

packages/spec/src/data/data-engine.zod.ts 里有 7 处同一形状:

z.union([z.record(z.string(), z.unknown()), FilterConditionSchema])

第一条分支接受任何字符串键对象。union 只要有一条分支接受就接受 ⇒ FilterConditionSchema 的拒绝在这些槽位上到不了

不是推断,是按身份实测到的(dev,重建后的 dist):

输入 FilterConditionSchema DataEngineFilterSchema
{ $and: 'x' } REFUSED ACCEPTED ⭐ 遮蔽

⇒ 一条在兄弟 schema 上够得着的拒绝,在挂载点上够不着。这与 #18731 对 tracing 说的是同一句话,只是 tracing 那处已经设防、这 7 处没有。

⛔ 本席自己那条腿不是对 main 的读数,照实申报

本席在 2026-09-18T17:13Z 跑了同一个身份探针,结果与 dev 逐条相同({$and:'x'} 被兄弟拒、被挂载点接受;亮控一条合法条件两边都过;暗控 {} 两边都过)。

⚠️ 但本席这条腿不算数:本席检出里的 packages/spec/dist 建于 2026-09-18T05:26Z,而 data-engine.zod.ts 最近一次变动是 dbd474431f,2026-09-18T12:24:15Z —— 晚于那次构建。⇒ 本席量的是一份旧构建,⛔ 不是 main。承载性的读数只有 dev 那一次(它先证明自己的 dist 带着当时的修复,再跑腿)。本席这条只作一致性对照,⛔ 不作独立证据。

站点清单(本席现读 ed6c554545 复核,⛔ 但计数以 dev 的 AST 为准)

FilterConditionSchema 作兄弟的 7 处::31 · :100 · :234 · :329 · :354 · :414 · :1314

⚠️ 本席的单行 grep 只数到 6 处 —— 漏的是 :31DataEngineFilterSchema,它的两个分支跨行写,单行 grep 结构上看不见它。⇒ ⛔ 接手的人不要用单行 grep 复核这个清单,dev 的 AST 仪器严格地更好。

同文件另有 2 处不算(:444 · :1257):它们的兄弟是数组,JS 类型不同 ⇒ 遮蔽不成立。

⚠️ 范围上的诚实话(dev 自己写的,本席认同并照抄)

⭐ 一条会让复查走偏的更正 —— 机制不是「宽容分支在前」

#18731 的卡面把病因写成「union 逐分支尝试,任何对象都会被它接住」。dev 在 zod 4.4.3 上实测:z.union([perm,strict])z.union([strict,perm]) 两种顺序都接受只有 perm 接受的值 ⇒ 顺序与接受集无关

⇒ 照「宽容分支在前」去筛,会漏掉 record 分支排在最后的站点。本卡的 7 处里就有这种。

⛔ 本卡不主张的事

  • 不主张修法是「收窄第一分支」。收窄会拒掉今天被接受的值 ⇒ 公开面收窄,要回去找维护者。tracing 那处走的是另一条路:让宽容分支学会拒绝一个判别键(.refine(v => !('dialect' in v))),⛔ 不收窄。这 7 处有没有同样干净的判别键,没人量过
  • 不主张FilterConditionSchema 本身。

⭐ 一个具名邻居,⛔ 本席不立成活

packages/spec/src/identity/scim.zod.ts:785 是同一形状(record 分支在最后)。dev 实测:SCIMUserSchema.safeParse({schemas:'not-an-array',userName:42})false,而外层 SCIMListResponseSchema 把同一个对象放进 Resources[]true

⚠️ 但它在文档里写着是刻意的(「Resources array (Users, Groups, or custom resources)」)⇒ 这不是缺陷报告,是**「SCIM 自定义资源需不需要一个判别键」的决策问题**,归维护者。⛔ 本席不把它立成活,证据留在这里。

查重词

permissive record arm shadows FilterConditionSchema refusal · DataEngineFilterSchema union accepts what FilterCondition refuses · data-engine filter union unreachable validation · record arm beside strict schema data-engine · union arm order irrelevant to accept set zod

出处链

#18731(被证伪的那张,现 pm:retriage)· PR #18638 / ce5785790c(修掉 tracing 那处的那次)· #18670(同槽位的另一张,见 #18731 上的交叉读数)


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions