Properly validate JS->native method calls (#23658)

Summary:
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.

/cc fkgozali f945212447 (commitcomment-32467567)

[iOS] [Fixed] - Properly validate JS->native method calls
Pull Request resolved: https://github.com/facebook/react-native/pull/23658

Differential Revision: D14287594

Pulled By: fkgozali

fbshipit-source-id: 89dd1906a0c55f3f48ba4ff220aac0cddf2eb822
This commit is contained in:
aleclarson
2019-03-04 17:36:50 -08:00
committed by Facebook Github Bot
parent ddd5b25768
commit dc893756b8
2 changed files with 17 additions and 13 deletions

View File

@@ -330,9 +330,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
- (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;
}

View File

@@ -71,17 +71,19 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params, int
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 &&params) {