[iOS][Fabric] `RCTSwitchComponentView onChange:` dereferences `_eventEmitter` without a null check (EXC_BAD_ACCESS after view recycle)
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 76/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- objective-c, react-native
- Lĩnh vực
- mobile
Hướng nghiên cứu
Đọc React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm, đặc biệt là onChange: và phần xử lý tái sử dụng ở gần đó được đề cập trong issue. So sánh các điều kiện kiểm tra event emitter trong những component view tương tự được nêu trong báo cáo, sau đó kiểm tra các bài kiểm thử Switch liên quan hoặc bổ sung kiểm thử cho một view đã được tái sử dụng nếu các bài kiểm thử hiện có cho thấy luồng này. Công việc hoàn tất khi onChange: xử lý an toàn emitter đã bị xóa và hành vi Switch hiện có vẫn được kiểm thử.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- C++
- Star
- 127k
- Fork
- 25.3k
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của react/react-native
-
Linking.getInitialURL() returns the task's first link after a link relaunches a reclaimed Android appCó thể đã có người làm @YevheniiKotyrlo đã nhận 7 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
react/react-native#59006 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Fabric TextInput: prepareForRecycle leaves stale inputAccessoryViewButtonLabel (empty Done bar)Có thể đã có người làm @jkasprzyk17 đã nhận 6 ngày trước. Đang mởNeeds: Author Feedback Needs: Repro
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
react/react-native#58952 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[iOS][Fabric] TextInput drops a keystroke right after the first character typed into an empty field (_textOf:equals: compares attributes of a focused field)Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởNeeds: Attention Needs: Repro
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
react/react-native#58904 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Needs: Author Feedback Needs: Repro
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
react/react-native#58659 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Needs: Author Feedback Needs: Repro
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
react/react-native#58621 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của react/react-native
Issue tương tự
-
[WinReg] update to v12.0.0Đang mởcategory:port-update
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 2 ngày
-
(S1 - Need confirmation)
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
CleverRaven/Cataclysm-DDA#89194 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
reproduced
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 67/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Reusing a stream after a mid-speech stop: the next session opens with a phantom line ("you")Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
moonshine-ai/moonshine#231 ·