From 92b1856b33f995d7be6eb36aef7f96a0ad7084b5 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Thu, 10 Sep 2026 14:46:23 -0700 Subject: [PATCH] Run RCTAccessibilityManager methods on the main queue Summary: RCTAccessibilityManager mirrors UIKit accessibility state into ivars from nine NSNotificationCenter handlers, which are delivered on the main thread. The module declared no methodQueue, so its exported methods ran on the JS thread instead, and none of its properties are atomic. That leaves the content size multipliers open to a data race. The `multipliers` getter lazily assigns `_multipliers` on read and is reached from the main thread via the content size category notification, while `setAccessibilityContentSizeMultipliers:` reaches `setMultipliers:` from the JS thread and releases the previous dictionary. Concurrent access can over-release that dictionary and leave a dangling pointer behind, which then faults on the next message to it. Declare methodQueue as the main queue so the exported methods and the notification handlers serialize on one thread. The module already requires main queue setup and every method reads UIKit-derived state, so this matches how it is used. Changelog: [iOS][Fixed] - Fix data race on accessibility content size multipliers in `RCTAccessibilityManager` Differential Revision: D119565016 --- .../React/CoreModules/RCTAccessibilityManager.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm b/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm index 29b03e6c1c79..7ff290fdce80 100644 --- a/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm +++ b/packages/react-native/React/CoreModules/RCTAccessibilityManager.mm @@ -40,6 +40,11 @@ + (BOOL)requiresMainQueueSetup return YES; } +- (dispatch_queue_t)methodQueue +{ + return dispatch_get_main_queue(); +} + - (instancetype)init { if (self = [super init]) {