mirror of
https://github.com/status-im/react-native.git
synced 2025-02-05 06:04:15 +00:00
Guard against invalid JS bundle
Reviewed By: tadeuzagallo Differential Revision: D2767961 fb-gh-sync-id: 4e9162ddbb2986a56dd129743e316d6e83bb8cb3
This commit is contained in:
parent
ba3a5f0eec
commit
5b4e873c68
@ -69,13 +69,40 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
@interface RCTAllocationTests : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation RCTAllocationTests
|
||||
@implementation RCTAllocationTests {
|
||||
NSURL *_bundleURL;
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
|
||||
NSString *bundleContents =
|
||||
@"var __fbBatchedBridge = {"
|
||||
" callFunctionReturnFlushedQueue: function() {},"
|
||||
" invokeCallbackAndReturnFlushedQueue: function() {},"
|
||||
" flushedQueue: function() {},"
|
||||
"};";
|
||||
|
||||
NSURL *tempDir = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
|
||||
[[NSFileManager defaultManager] createDirectoryAtURL:tempDir withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
|
||||
_bundleURL = [tempDir URLByAppendingPathComponent:@"rctallocationtests-bundle.js"];
|
||||
[bundleContents writeToURL:_bundleURL atomically:YES encoding:NSUTF8StringEncoding error:NULL];
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[super tearDown];
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtURL:_bundleURL error:NULL];
|
||||
}
|
||||
|
||||
- (void)testBridgeIsDeallocated
|
||||
{
|
||||
__weak RCTBridge *weakBridge;
|
||||
@autoreleasepool {
|
||||
RCTRootView *view = [[RCTRootView alloc] initWithBundleURL:nil
|
||||
RCTRootView *view = [[RCTRootView alloc] initWithBundleURL:_bundleURL
|
||||
moduleName:@""
|
||||
initialProperties:nil
|
||||
launchOptions:nil];
|
||||
@ -91,7 +118,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
{
|
||||
AllocationTestModule *module = [AllocationTestModule new];
|
||||
@autoreleasepool {
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:^{
|
||||
return @[module];
|
||||
}
|
||||
@ -109,11 +136,11 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
__weak AllocationTestModule *weakModule;
|
||||
@autoreleasepool {
|
||||
AllocationTestModule *module = [AllocationTestModule new];
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
moduleProvider:^{
|
||||
return @[module];
|
||||
}
|
||||
launchOptions:nil];
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:^{
|
||||
return @[module];
|
||||
}
|
||||
launchOptions:nil];
|
||||
weakModule = module;
|
||||
XCTAssertNotNil(weakModule, @"AllocationTestModule should have been created");
|
||||
(void)bridge;
|
||||
@ -140,7 +167,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
{
|
||||
__weak id<RCTJavaScriptExecutor> weakExecutor;
|
||||
@autoreleasepool {
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:nil
|
||||
launchOptions:nil];
|
||||
weakExecutor = [bridge.batchedBridge valueForKey:@"javaScriptExecutor"];
|
||||
@ -156,7 +183,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
{
|
||||
__weak id weakContext;
|
||||
@autoreleasepool {
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:nil
|
||||
launchOptions:nil];
|
||||
id executor = [bridge.batchedBridge valueForKey:@"javaScriptExecutor"];
|
||||
@ -171,7 +198,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
|
||||
- (void)testContentViewIsInvalidated
|
||||
{
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
|
||||
moduleProvider:nil
|
||||
launchOptions:nil];
|
||||
__weak UIView *rootContentView;
|
||||
@ -190,7 +217,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
RCTBridge *bridge;
|
||||
__weak id batchedBridge;
|
||||
@autoreleasepool {
|
||||
bridge = [[RCTBridge alloc] initWithBundleURL:nil moduleProvider:nil launchOptions:nil];
|
||||
bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:nil launchOptions:nil];
|
||||
batchedBridge = bridge.batchedBridge;
|
||||
XCTAssertTrue([batchedBridge isValid], @"RCTBatchedBridge should be valid");
|
||||
[bridge reload];
|
||||
|
@ -119,8 +119,8 @@ static NSString *RCTJSValueToJSONString(JSContextRef context, JSValueRef value,
|
||||
|
||||
static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
|
||||
{
|
||||
NSString *errorMessage = jsError ? RCTJSValueToNSString(context, jsError, NULL) : @"unknown JS error";
|
||||
NSString *details = jsError ? RCTJSValueToJSONString(context, jsError, NULL, 2) : @"no details";
|
||||
NSString *errorMessage = jsError ? RCTJSValueToNSString(context, jsError, NULL) : @"Unknown JS error";
|
||||
NSString *details = jsError ? RCTJSValueToJSONString(context, jsError, NULL, 2) : @"No details";
|
||||
return [NSError errorWithDomain:@"JS" code:1 userInfo:@{NSLocalizedDescriptionKey: errorMessage, NSLocalizedFailureReasonErrorKey: details}];
|
||||
}
|
||||
|
||||
@ -394,14 +394,12 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
||||
JSStringRelease(moduleNameJSStringRef);
|
||||
|
||||
if (moduleJSRef != NULL && errorJSRef == NULL && !JSValueIsUndefined(contextJSRef, moduleJSRef)) {
|
||||
|
||||
// get method
|
||||
JSStringRef methodNameJSStringRef = JSStringCreateWithCFString((__bridge CFStringRef)method);
|
||||
JSValueRef methodJSRef = JSObjectGetProperty(contextJSRef, (JSObjectRef)moduleJSRef, methodNameJSStringRef, &errorJSRef);
|
||||
JSStringRelease(methodNameJSStringRef);
|
||||
|
||||
if (methodJSRef != NULL && errorJSRef == NULL) {
|
||||
|
||||
if (methodJSRef != NULL && errorJSRef == NULL && !JSValueIsUndefined(contextJSRef, methodJSRef)) {
|
||||
// direct method invoke with no arguments
|
||||
if (arguments.count == 0) {
|
||||
resultJSRef = JSObjectCallAsFunction(contextJSRef, (JSObjectRef)methodJSRef, (JSObjectRef)moduleJSRef, 0, NULL, &errorJSRef);
|
||||
@ -433,11 +431,22 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
||||
JSStringRelease(argsJSStringRef);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!errorJSRef && JSValueIsUndefined(contextJSRef, methodJSRef)) {
|
||||
error = RCTErrorWithMessage([NSString stringWithFormat:@"Unable to execute JS call: method %@ is undefined", method]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!errorJSRef && JSValueIsUndefined(contextJSRef, moduleJSRef)) {
|
||||
error = RCTErrorWithMessage(@"Unable to execute JS call: __fbBatchedBridge is undefined");
|
||||
}
|
||||
}
|
||||
|
||||
if (errorJSRef) {
|
||||
onComplete(nil, RCTNSErrorFromJSError(contextJSRef, errorJSRef));
|
||||
if (errorJSRef || error) {
|
||||
if (!error) {
|
||||
error = RCTNSErrorFromJSError(contextJSRef, errorJSRef);
|
||||
}
|
||||
onComplete(nil, error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user