Skip to content

[finding] sharded-artifacts 另两个读取器同样把 JSON 数组 as string[] 直接下发,条目类型无人校验(历史基线 / api-surface,#6751 的修法覆盖不到) #7076

Description

@os-project-manager

范围外发现,记录于 #6751 的实现过程中(PR #7075)。观察类:今天没有用户路径命中,门禁红绿不受影响,单纯记录同一文件里同一类的两处剩余缺口。

#6751 修的是 aggregateCategoryShards:它把分片的数组字段 as string[] 一转就喂给 categoryOfDefKey,非字符串条目于是死在 helper 里。修法是在遍历处加一次 typeof 校验(报文件名 + 条目下标 + 锚点)。

同一文件 packages/spec/scripts/lib/sharded-artifacts.ts 里还有两个读取器做了同样的转换、但走不到那次校验,所以 #6751 的落点覆盖不到它们:

1. readShardedKeysAtRev —— 历史基线读取

两条分支(sharded / legacy)都是:

const list = doc[field];
if (!Array.isArray(list)) return { error: `… has no "${field}" array` };
entries.push(...(list as string[]));

Array.isArray 只回答「是数组」,不回答「里面是什么」。非字符串条目会原样流进基线集合。它不调用 categoryOfDefKey,所以 #6751 加的那格分支永远碰不到它。

后果不是绕过:删除门禁拿基线与当前集合做差,一个数字条目会被算成「消失的 key」并索要 tombstone —— 响亮但指错人的失败,而不是静默通过。

2. aggregateApiSurfaceShards —— 第四个分片产物

if (!Array.isArray(shard.doc.exports)) {
  throw new Error(`… has no "exports" array (#5837).`);
}
surface[shard.doc.entry] = shard.doc.exports;

同样只校验容器不校验条目。api-surface/ 是第四个分片产物,#6751 明确不覆盖它 —— 因为它不经 categoryOfDefKey 路由,所以那单的实测表格里也没有它。

为什么归为观察类

建议修法(窄)

#6751 已落地的形状同族:在两处的 Array.isArray 之后各加一次逐条 typeof 校验,复用同样的消息骨架(文件名 + 字段名 + 条目下标 + #5837 锚点)。aggregateCategoryShards 里现成的 jsonTypeLabel 可直接复用。历史基线那处要注意它的返回形状是 { error } 而非 throw,消息得走同一骨架但换承载方式。

关联:#6751(同类,已修,PR #7075)、#5837(分片重做)。


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions