FormGroupApi.getRelatedFields and FieldApi.validate() use unguarded startsWith for group membership, matching unrelated fields with a shared name prefix
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 82/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- frontend
調査の方向性
packages/form-core/src/utils.ts の isFieldInGroup から始め、次に packages/form-core/src/FormGroupApi.ts の getRelatedFields() と packages/form-core/src/FieldApi.ts の validate() を調べます。関連する form-core テストを実行し、無関係な username フィールドと並んで user という名前のグループを対象とするカバレッジを追加します。グループ操作とバリデーションに無関係なフィールドが含まれなくなれば完了です。
索引モデルが issue の本文から書いたものです。
説明
I found another instance of the string-prefix bug that #2318 just fixed for deleteField.
FormApi.deleteField used to select sub-fields with a raw f.startsWith(fieldStr), which meant deleting field email also deleted the unrelated sibling emailVerified (#2317). That was fixed in #2318 by requiring a . or [ boundary after the prefix, and packages/form-core/src/utils.ts now has a proper isFieldInGroup(groupName, fieldName) helper that does the same boundary check for FormGroups:
export function isFieldInGroup(groupName: string, fieldName: string) {
return (
fieldName === groupName ||
fieldName.startsWith(`${groupName}.`) ||
fieldName.startsWith(`${groupName}[`)
)
}
I checked where FormGroups associate fields with themselves and found two places that don't use this helper and still do the raw unguarded startsWith:
FormGroupApi.getRelatedFields()(packages/form-core/src/FormGroupApi.ts, around line 1649):
if (field.instance.name.startsWith(this.name)) {
relatedFields.push(field.instance)
}
FieldApi.validate()(packages/form-core/src/FieldApi.ts, around line 1628), when computing which groups "encompass" a field:
const encompassingGroups = opts?.skipGroupValidation
? []
: Array.from(this.form.formGroupApis).filter((group) =>
this.name.startsWith(group.name),
)
I confirmed getRelatedFields() isn't just informational, it's used by validate(), validateAllFields(), areRelatedFieldsValid(), and handleSubmit() on FormGroupApi to decide which fields belong to the group, get touched on submit, and get counted toward the group's validity.
Repro: a form with a FormGroup named user and an unrelated top-level field named username. Submitting the user group marks username as touched and includes its validity in areRelatedFieldsValid(), even though username isn't nested under the group at all. Similarly, changing username makes FieldApi.validate() treat the user group as "encompassing" it and rerun that group's form-level validators on every change to username.
I compared this against isFieldInGroup in utils.ts, which already has the correct fix, and against getRelatedFieldMetasDerived() in the same FormGroupApi.ts file, which does use isFieldInGroup correctly (lines 1671, 2314, 2334). So the fix pattern already exists in the codebase, it's just not applied consistently at the two call sites above.
Suggested fix: swap both raw startsWith checks for isFieldInGroup(this.name, field.instance.name) in getRelatedFields() and isFieldInGroup(group.name, this.name) in FieldApi.validate().
- 主要言語
- TypeScript
- スター
- 6.7k
- フォーク
- 682
- 平均マージ
- 5日 18時間
- マージ済み PR(30日)
- 7
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
TanStack/form のほかの issue
-
難易度 2/5 1〜2日 初心者へのやさしさ 72/100
-
area: runtime scope: devtools type: bug v2
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
FormApi: onSubmit/onServer error cleared on any non-matching validation cause, not just 'change' オープンv1 v2: needs investigation
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
-
v1 v2: needs investigation
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
-
v1 v2: needs investigation
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
calcite-components needs triage refactor
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
Esri/calcite-design-system#15203 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
danielmiessler/LifeOS#2218 ·