From ebd25fe5179ace951d48a5995a22207b6a5973ef Mon Sep 17 00:00:00 2001 From: aleclarson Date: Tue, 26 Feb 2019 10:26:47 -0500 Subject: [PATCH] Properly validate JS->native method calls Between invalidating a bridge and suspending its JS thread, native modules may have their methods called. Only warn when a native module has been invalidated, which happens right before its JS thread is suspended. Avoid initializing a native module's instance if its bridge is invalidated. --- React/Base/RCTModuleData.mm | 8 +++++--- React/CxxModule/RCTNativeModule.mm | 22 ++++++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/React/Base/RCTModuleData.mm b/React/Base/RCTModuleData.mm index ba2dbd5196f9..c02c8810f6e1 100644 --- a/React/Base/RCTModuleData.mm +++ b/React/Base/RCTModuleData.mm @@ -330,9 +330,11 @@ - (void)gatherConstants - (dispatch_queue_t)methodQueue { - (void)[self instance]; - RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@, bridge.valid: %d)", - self, _instance, _bridge.valid); + if (_bridge.valid) { + id instance = self.instance; + RCTAssert(_methodQueue != nullptr, @"Module %@ has no methodQueue (instance: %@)", + self, instance); + } return _methodQueue; } diff --git a/React/CxxModule/RCTNativeModule.mm b/React/CxxModule/RCTNativeModule.mm index ec88558b873d..b59a68312a80 100644 --- a/React/CxxModule/RCTNativeModule.mm +++ b/React/CxxModule/RCTNativeModule.mm @@ -71,17 +71,19 @@ invokeInner(weakBridge, weakModuleData, methodId, std::move(params)); }; - if (m_bridge.valid) { - dispatch_queue_t queue = m_moduleData.methodQueue; - if (queue == RCTJSThread) { - block(); - } else if (queue) { - dispatch_async(queue, block); - } - } else { - RCTLog(@"Attempted to invoke `%u` (method ID) on `%@` (NativeModule name) with an invalid bridge.", - methodId, m_moduleData.name); + dispatch_queue_t queue = m_moduleData.methodQueue; + if (queue == RCTJSThread) { + block(); + } else if (queue) { + dispatch_async(queue, block); + } + + #ifdef RCT_DEV + if (!queue) { + RCTLog(@"Attempted to invoke `%u` (method ID) on `%@` (NativeModule name) without a method queue.", + methodId, m_moduleData.name); } + #endif } MethodCallResult RCTNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic &¶ms) {