[iOS][Fabric] `RCTSwitchComponentView onChange:` dereferences `_eventEmitter` without a null check (EXC_BAD_ACCESS after view recycle)
メンテナーはふだん 2 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 76/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- objective-c, react-native
- 領域
- mobile
調査の方向性
React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mmを読み、特にonChange:と、issueで言及されている近くの再利用処理を確認してください。報告で挙げられている同種のコンポーネントビューにおけるevent emitterのガードを比較し、その後、関連するSwitchのテストを確認するか、既存のテストでこの経路が明らかになる場合は再利用されたビューのテストを追加してください。onChange:がクリア済みのemitterを安全に処理し、既存のSwitchの動作が引き続きテストでカバーされていれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Environment
- react-native 0.88.0 (first seen on 0.86.0; the file is byte-identical in both), New Architecture
- iOS 26.5.2 device (production crash), same code path on iOS 27
- Expo SDK 58 (not involved)
Description
-[RCTSwitchComponentView onChange:] (React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm:105-114) ends with
static_cast<const SwitchEventEmitter &>(*_eventEmitter) // line 113
.onChange(SwitchEventEmitter::OnChange{.value = static_cast<bool>(sender.on)});
with no check that _eventEmitter is set. RCTViewComponentView -prepareForRecycle resets it (RCTViewComponentView.mm:779, _eventEmitter.reset();), while _props stays valid, so the earlier *_props dereference does not fail.
Production crash (0.86.0, line 114 of that version), iOS 26.5.2:
EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS at 0x0000000000000030
0 React std::weak_ptr<EventDispatcher const>::lock()
1 React EventEmitter::dispatchEvent(...)
4 React SwitchEventEmitter::onChange(...)
5 React -[RCTSwitchComponentView onChange:]
6 UIKitCore -[UIApplication sendAction:to:from:forEvent:]
9 UIKitCore -[UISwitchModernVisualElement sendStateChangeActions]
11 UIKitCore -[UISwitchModernVisualElement _handleLongPressWithGestureLocationInBounds:...]
12 UIKitCore -[_UIAfterCACommitBlock run]
0x30 is a null this plus the eventDispatcher_ offset in EventEmitter.
Reproduction
Intermittent, not reproduced on demand. Conditions: iOS 26+, where the redesigned UISwitch (UISwitchModernVisualElement) delivers the state-change action from a deferred _UIAfterCACommitBlock instead of synchronously on touch-up (seen when the switch is dragged or long-pressed rather than tapped). If React re-renders and recycles the Switch view between the gesture ending and that block running, prepareForRecycle has already cleared _eventEmitter and onChange: runs on the recycled view.
Root cause
Missing null guard. Sibling components in the same directory tree already have it: RCTScrollViewComponentView, RCTImageComponentView, RCTModalHostViewComponentView, RCTVirtualViewComponentView (if (!_eventEmitter) { return; }), and RCTTextInputComponentView tests _eventEmitter before use at several sites. Switch is the outlier.
Proposed fix
--- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm
+++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm
@@ -110,6 +110,9 @@ - (void)onChange:(UISwitch *)sender
return;
}
+ if (!_eventEmitter) {
+ return;
+ }
static_cast<const SwitchEventEmitter &>(*_eventEmitter)
.onChange(SwitchEventEmitter::OnChange{.value = static_cast<bool>(sender.on)});
}
We carry this as a local patch. Dropping the event is the right behaviour: the view has been recycled and no longer represents that React node.
Disclosure: drafted with AI assistance (Claude) from a patch we carry locally; code references were checked against the published package sources. Happy to clarify or open a PR.
- 主要言語
- C++
- スター
- 127k
- フォーク
- 25.3k
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
react/react-native のほかの issue
-
Linking.getInitialURL() returns the task's first link after a link relaunches a reclaimed Android app対応中かも @YevheniiKotyrlo が 7 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
react/react-native#59006 · コメント 2 件 ·
メンテナーはふだん 2 日以内に返信
-
Fabric TextInput: prepareForRecycle leaves stale inputAccessoryViewButtonLabel (empty Done bar)対応中かも @jkasprzyk17 が 6 日前に担当しました。 オープンNeeds: Author Feedback Needs: Repro
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
react/react-native#58952 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
-
[iOS][Fabric] TextInput drops a keystroke right after the first character typed into an empty field (_textOf:equals: compares attributes of a focused field)対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンNeeds: Attention Needs: Repro
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
react/react-native#58904 · コメント 3 件 ·
メンテナーはふだん 2 日以内に返信
-
Needs: Author Feedback Needs: Repro
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
react/react-native#58659 · コメント 2 件 ·
メンテナーはふだん 2 日以内に返信
-
Needs: Author Feedback Needs: Repro
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
react/react-native#58621 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
react/react-native の issue をすべて見る
似ている issue
-
v9.6.0: CMake incorrectly enforces presence of libevdev対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
メンテナーはふだん 1 日以内に返信
-
Rowan (2017) electron heating gives NaN for beta > beta_max; clip() then sets electrons to kel_minオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
parthenon-hpc-lab/kharma#213 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
metasequoiaime/msime#9113 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
tone-3000/tone3000-plugin#257 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Locked plugin flip-flops position on every refresh after being disabled対応中かも @Illustar0 が今日担当しました。 オープンissue report
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
ModOrganizer2/modorganizer#2449 ·