Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

[iOS][Fabric] `RCTSwitchComponentView onChange:` dereferences `_eventEmitter` without a null check (EXC_BAD_ACCESS after view recycle)

已關閉 適合新手
#59,203 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 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 內容生成。

描述

Needs: Author Feedback Needs: Repro

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

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

react/react-native 的其他 Issue

查看 react/react-native 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。