From de9b96c490abd21f0bf72ae8b4b1f7c235af040e Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Mon, 20 Apr 2020 11:03:48 +0800 Subject: [PATCH] iOS:add protection for SIGSEGV --- doric-iOS/Devkit/Classes/DoricDebugDriver.m | 16 ++++++++++++++++ doric-iOS/Pod/Classes/DoricContext.h | 2 +- doric-iOS/Pod/Classes/DoricContext.m | 16 ++++++++-------- doric-iOS/Pod/Classes/DoricDriverProtocol.h | 6 ++++-- doric-iOS/Pod/Classes/DoricNativeDriver.m | 16 ++++++++++++++++ doric-iOS/Pod/Classes/Engine/DoricJSEngine.h | 2 +- doric-iOS/Pod/Classes/Engine/DoricJSEngine.m | 2 +- doric-iOS/Pod/Classes/Plugin/DoricPromise.m | 14 ++++++++++++-- 8 files changed, 59 insertions(+), 15 deletions(-) diff --git a/doric-iOS/Devkit/Classes/DoricDebugDriver.m b/doric-iOS/Devkit/Classes/DoricDebugDriver.m index 405ba184..82f4ae49 100644 --- a/doric-iOS/Devkit/Classes/DoricDebugDriver.m +++ b/doric-iOS/Devkit/Classes/DoricDebugDriver.m @@ -52,6 +52,22 @@ - (DoricRegistry *)registry { return ret; } +- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args { + DoricAsyncResult *ret = [[DoricAsyncResult alloc] init]; + __weak typeof(self) _self = self; + dispatch_async(self.jsExecutor.jsQueue, ^() { + __strong typeof(_self) self = _self; + if (!self) return; + @try { + JSValue *jsValue = [self.jsExecutor invokeDoricMethod:method argumentsArray:args]; + [ret setupResult:jsValue]; + } @catch (NSException *exception) { + [ret setupError:exception]; + } + }); + return ret; +} + - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method arguments:(va_list)args { DoricAsyncResult *ret = [[DoricAsyncResult alloc] init]; NSMutableArray *array = [[NSMutableArray alloc] init]; diff --git a/doric-iOS/Pod/Classes/DoricContext.h b/doric-iOS/Pod/Classes/DoricContext.h index c601362d..69eedd61 100644 --- a/doric-iOS/Pod/Classes/DoricContext.h +++ b/doric-iOS/Pod/Classes/DoricContext.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithScript:(NSString *)script source:(NSString *)source extra:(NSString *)extra; -- (DoricAsyncResult *)callEntity:(NSString *)method, ...; +- (DoricAsyncResult *)callEntity:(NSString *)method, ... NS_REQUIRES_NIL_TERMINATION; - (DoricAsyncResult *)callEntity:(NSString *)method withArguments:(va_list)args; diff --git a/doric-iOS/Pod/Classes/DoricContext.m b/doric-iOS/Pod/Classes/DoricContext.m index eb81f635..dec4578a 100644 --- a/doric-iOS/Pod/Classes/DoricContext.m +++ b/doric-iOS/Pod/Classes/DoricContext.m @@ -41,7 +41,7 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source extr DoricRootNode *rootNode = [[DoricRootNode alloc] initWithContext:self]; _rootNode = rootNode; [self init:extra]; - [self callEntity:DORIC_ENTITY_CREATE, nil]; + [self callEntity:DORIC_ENTITY_CREATE withArgumentsArray:@[]]; } return self; } @@ -60,7 +60,7 @@ - (DoricViewNode *)targetViewNode:(NSString *)viewId { } - (void)dealloc { - [self callEntity:DORIC_ENTITY_DESTROY, nil]; + [self callEntity:DORIC_ENTITY_DESTROY withArgumentsArray:@[]]; [[DoricContextManager instance] destroyContext:self]; } @@ -83,7 +83,7 @@ - (DoricAsyncResult *)callEntity:(NSString *)method withArgumentsArray:(NSArray - (void)init:(NSString *)initData { self.extra = initData; if (initData) { - [self callEntity:DORIC_ENTITY_INIT, initData, nil]; + [self callEntity:DORIC_ENTITY_INIT withArgumentsArray:@[initData]]; } } @@ -92,7 +92,7 @@ - (void)build:(CGSize)size { it[@"width"] = @(size.width); it[@"height"] = @(size.height); }]; - [self callEntity:DORIC_ENTITY_BUILD, self.initialParams, nil]; + [self callEntity:DORIC_ENTITY_BUILD withArgumentsArray:@[self.initialParams]]; } - (void)reload:(NSString *)script { @@ -100,17 +100,17 @@ - (void)reload:(NSString *)script { self.script = script; [self.driver createContext:self.contextId script:script source:self.source]; [self init:self.extra]; - [self callEntity:DORIC_ENTITY_CREATE, nil]; - [self callEntity:DORIC_ENTITY_BUILD, self.initialParams, nil]; + [self callEntity:DORIC_ENTITY_CREATE withArgumentsArray:@[]]; + [self callEntity:DORIC_ENTITY_BUILD withArgumentsArray:@[self.initialParams]]; [self onShow]; } - (void)onShow { - [self callEntity:DORIC_ENTITY_SHOW, nil]; + [self callEntity:DORIC_ENTITY_SHOW withArgumentsArray:@[]]; } - (void)onHidden { - [self callEntity:DORIC_ENTITY_HIDDEN, nil]; + [self callEntity:DORIC_ENTITY_HIDDEN withArgumentsArray:@[]]; } @end diff --git a/doric-iOS/Pod/Classes/DoricDriverProtocol.h b/doric-iOS/Pod/Classes/DoricDriverProtocol.h index fc502ef5..a60bb02e 100644 --- a/doric-iOS/Pod/Classes/DoricDriverProtocol.h +++ b/doric-iOS/Pod/Classes/DoricDriverProtocol.h @@ -32,9 +32,11 @@ - (DoricAsyncResult *)destroyContext:(NSString *)contextId; -- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method, ...; +- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method, ... NS_REQUIRES_NIL_TERMINATION; -- (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString *)method, ...; +- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args; + +- (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString *)method, ... NS_REQUIRES_NIL_TERMINATION; - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString *)method arguments:(va_list)args; diff --git a/doric-iOS/Pod/Classes/DoricNativeDriver.m b/doric-iOS/Pod/Classes/DoricNativeDriver.m index 8be6c0cb..1ddef1a1 100644 --- a/doric-iOS/Pod/Classes/DoricNativeDriver.m +++ b/doric-iOS/Pod/Classes/DoricNativeDriver.m @@ -53,6 +53,22 @@ + (instancetype)instance { return _instance; } +- (DoricAsyncResult *)invokeDoricMethod:(NSString *)method argumentsArray:(NSArray *)args { + DoricAsyncResult *ret = [[DoricAsyncResult alloc] init]; + __weak typeof(self) _self = self; + dispatch_async(self.jsExecutor.jsQueue, ^() { + __strong typeof(_self) self = _self; + if (!self) return; + @try { + JSValue *jsValue = [self.jsExecutor invokeDoricMethod:method argumentsArray:args]; + [ret setupResult:jsValue]; + } @catch (NSException *exception) { + [ret setupError:exception]; + } + }); + return ret; +} + - (DoricAsyncResult *)invokeDoricMethod:(NSString *)method, ... { va_list args; va_start(args, method); diff --git a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h index cdd954bf..646366ad 100644 --- a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h +++ b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h @@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)destroyContext:(NSString *)contextId; -- (JSValue *)invokeDoricMethod:(NSString *)method, ...; +- (JSValue *)invokeDoricMethod:(NSString *)method, ... NS_REQUIRES_NIL_TERMINATION; - (JSValue *)invokeDoricMethod:(NSString *)method arguments:(va_list)args; diff --git a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m index efc2f92a..97ae29b6 100644 --- a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m +++ b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m @@ -228,7 +228,7 @@ - (void)callbackTimer:(NSTimer *)timer { NSDictionary *userInfo = timer.userInfo; NSNumber *timerId = [userInfo valueForKey:@"timerId"]; NSNumber *repeat = [userInfo valueForKey:@"repeat"]; - + __strong typeof(_self) self = _self; @try { [self invokeDoricMethod:DORIC_TIMER_CALLBACK, timerId, nil]; diff --git a/doric-iOS/Pod/Classes/Plugin/DoricPromise.m b/doric-iOS/Pod/Classes/Plugin/DoricPromise.m index ff12af7a..144df3ca 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricPromise.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricPromise.m @@ -40,8 +40,13 @@ - (instancetype)initWithContext:(DoricContext *)context callbackId:(NSString *)c } - (void)resolve:(id)result { - [[self.context.driver invokeDoricMethod:DORIC_BRIDGE_RESOLVE, self.context.contextId, self.callbackId, result, nil] + __weak typeof(self) __self = self; + [[self.context.driver invokeDoricMethod:DORIC_BRIDGE_RESOLVE + argumentsArray:result + ? @[self.context.contextId, self.callbackId, result] + : @[self.context.contextId, self.callbackId]] setExceptionCallback:^(NSException *e) { + __strong typeof(__self) self = __self; [self.context.driver.registry onException:e inContext:self.context]; @@ -49,8 +54,13 @@ - (void)resolve:(id)result { } - (void)reject:(id)result { - [[self.context.driver invokeDoricMethod:DORIC_BRIDGE_REJECT, self.context.contextId, self.callbackId, result, nil] + __weak typeof(self) __self = self; + [[self.context.driver invokeDoricMethod:DORIC_BRIDGE_REJECT + argumentsArray:result + ? @[self.context.contextId, self.callbackId, result] + : @[self.context.contextId, self.callbackId]] setExceptionCallback:^(NSException *e) { + __strong typeof(__self) self = __self; [self.context.driver.registry onException:e inContext:self.context];