[iOS][Fabric] `RCTSwitchComponentView onChange:` dereferences `_eventEmitter` without a null check (EXC_BAD_ACCESS after view recycle)
維護者通常 2 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 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 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 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)可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉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
-
category:port-update
難度 2/5 1-3 小時 新手友好度 68/100
維護者通常 2 天內回覆
-
(S1 - Need confirmation)
難度 2/5 1-3 小時 新手友好度 65/100
CleverRaven/Cataclysm-DDA#89194 ·
維護者通常 1 天內回覆
-
reproduced
難度 1/5 1 小時以內 新手友好度 67/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 78/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 78/100
moonshine-ai/moonshine#231 ·