This is an automated email from the ASF dual-hosted git repository.
jianhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git
The following commit(s) were added to refs/heads/master by this push:
new c371398 Pass immutable arguments to JS to avoid JSC crash. (#2714)
c371398 is described below
commit c371398f9a802ee815abfe4c5c8e0751de99a488
Author: wqyfavor <[email protected]>
AuthorDate: Tue Jul 16 18:04:50 2019 +0800
Pass immutable arguments to JS to avoid JSC crash. (#2714)
---
ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m | 18 ++++++++--------
ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.h | 2 +-
ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.m | 6 +++---
ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm | 26 +++++++++++++++++++++++
ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m | 2 +-
ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m | 10 +++++++--
ios/sdk/WeexSDK/Sources/Utility/WXUtility.h | 8 +++++++
ios/sdk/WeexSDK/Sources/Utility/WXUtility.m | 24 +++++++++++++++++++++
8 files changed, 80 insertions(+), 16 deletions(-)
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
index fabc1fe..e351ef0 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
@@ -510,7 +510,10 @@ _Pragma("clang diagnostic pop") \
if (!options) {
newOptions = [NSMutableDictionary new];
}
- [newOptions addEntriesFromDictionary:@{@"env":[WXUtility
getEnvironment]}];
+ NSDictionary* immutableEnvDict = [[WXUtility getEnvironment] copy];
+ if (immutableEnvDict) {
+ [newOptions addEntriesFromDictionary:@{@"env":immutableEnvDict}];
+ }
newOptions[@"bundleType"] = bundleType;
__block NSString *raxAPIScript = nil;
__block NSString *raxAPIScriptPath = nil;
@@ -536,7 +539,8 @@ _Pragma("clang diagnostic pop") \
WX_MONITOR_INSTANCE_PERF_END(WXPTJSCreateInstance, [WXSDKManager
instanceForID:instanceIdString]);
[sdkInstance.apmInstance
onStage:KEY_PAGE_STAGES_EXECUTE_BUNDLE_END];
} else {
- sdkInstance.callCreateInstanceContext = [NSString
stringWithFormat:@"instanceId:%@\noptions:%@\ndata:%@", instanceIdString,
newOptions, data];
+ NSDictionary* immutableOptions = [newOptions copy];
+ sdkInstance.callCreateInstanceContext = [NSString
stringWithFormat:@"instanceId:%@\noptions:%@\ndata:%@", instanceIdString,
immutableOptions, data];
//add instanceId to weexContext ,if fucn createInstanceContext
failure ,then we will know which instance has problem (exceptionhandler)
self.jsBridge.javaScriptContext[@"wxExtFuncInfo"]= @{
@"func":@"createInstanceContext",
@@ -544,7 +548,7 @@ _Pragma("clang diagnostic pop") \
@"instanceId":sdkInstance.instanceId?:@"unknownId"
};
__weak typeof(self) weakSelf = self;
- [self callJSMethod:@"createInstanceContext"
args:@[instanceIdString, newOptions, data?:@[]] onContext:nil
completion:^(JSValue *instanceContextEnvironment) {
+ [self callJSMethod:@"createInstanceContext"
args:@[instanceIdString, immutableOptions, data?:@[]] onContext:nil
completion:^(JSValue *instanceContextEnvironment) {
if (sdkInstance.pageName) {
[sdkInstance.instanceJavaScriptContext.javaScriptContext
setName:sdkInstance.pageName];
}
@@ -929,10 +933,6 @@ _Pragma("clang diagnostic pop") \
bridge = self.jsBridge;
}
if (self.frameworkLoadFinished) {
- newArg = [args mutableCopy];
- if ([newArg containsObject:completion]) {
- [newArg removeObject:completion];
- }
WXLogDebug(@"Calling JS... method:%@, args:%@", method, args);
if (([bridge isKindOfClass:[WXJSCoreBridge class]]) ||
([bridge isKindOfClass:NSClassFromString(@"WXDebugger") ]) ) {
@@ -1100,9 +1100,9 @@ _Pragma("clang diagnostic pop") \
NSTimeInterval start = CACurrentMediaTime()*1000;
if (execInstance.instanceJavaScriptContext && execInstance.bundleType)
{
- [self callJSMethod:@"__WEEX_CALL_JAVASCRIPT__" args:@[execIns,
tasks] onContext:execInstance.instanceJavaScriptContext completion:nil];
+ [self callJSMethod:@"__WEEX_CALL_JAVASCRIPT__" args:@[execIns,
[tasks copy]] onContext:execInstance.instanceJavaScriptContext completion:nil];
} else {
- [self callJSMethod:@"callJS" args:@[execIns, tasks]];
+ [self callJSMethod:@"callJS" args:@[execIns, [tasks copy]]];
}
if (execInstance && !(execInstance.isJSCreateFinish)) {
NSTimeInterval diff = CACurrentMediaTime()*1000 - start;
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.h
b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.h
index 366efe1..40c9f9a 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.h
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.h
@@ -23,7 +23,7 @@
@interface WXBridgeMethod : NSObject
@property (nonatomic, strong, readonly) NSString *methodName;
-@property (nonatomic, copy, readonly) NSMutableArray *arguments;
+@property (nonatomic, copy, readonly) NSArray *arguments;
@property (nonatomic, weak, readonly) WXSDKInstance *instance;
- (instancetype)initWithMethodName:(NSString *)methodName
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.m
b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.m
index f50ad2b..0cbf9bb 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.m
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeMethod.m
@@ -32,7 +32,7 @@
{
if (self = [super init]) {
_methodName = methodName;
- _arguments = [NSMutableArray arrayWithArray:arguments];
+ _arguments = arguments ? [arguments copy] : @[];
_instance = instance;
}
@@ -124,8 +124,8 @@
id argument;
if (!strcmp(parameterType, blockType)) {
// callback
- argument = [^void(NSString *result, BOOL keepAlive) {
- [[WXSDKManager bridgeMgr] callBack:instanceId funcId:(NSString
*)obj params:result keepAlive:keepAlive];
+ argument = [^void(id result, BOOL keepAlive) {
+ [[WXSDKManager bridgeMgr] callBack:instanceId funcId:(NSString
*)obj params:[WXUtility convertContainerToImmutable:result]
keepAlive:keepAlive];
} copy];
// retain block
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
index 5283bda..9293fa5 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.mm
@@ -114,9 +114,35 @@
[_jsContext evaluateScript:frameworkScript withSourceURL:[NSURL
URLWithString:@"weex-main-jsfm.js"]];
}
+//static void __checkMutable(id container) {
+// if ([container isKindOfClass:[NSArray class]]) {
+// if ([container isKindOfClass:[NSMutableArray class]]) {
+// printf("This is mutable.");
+// }
+// else {
+// NSUInteger count = [container count];
+// for (NSUInteger index = 0; index < count; ++index) {
+// __checkMutable(container[index]);
+// }
+// }
+// }
+// else if ([container isKindOfClass:[NSDictionary class]]) {
+// if ([container isKindOfClass:[NSMutableDictionary class]]) {
+// printf("This is mutable.");
+// }
+// else {
+// NSArray* allKeys = [container allKeys];
+// for (id key in allKeys) {
+// __checkMutable(container[key]);
+// }
+// }
+// }
+//}
+
- (JSValue *)callJSMethod:(NSString *)method args:(NSArray *)args
{
WXLogDebug(@"Calling JS... method:%@, args:%@", method, args);
+// __checkMutable(args);
return [[_jsContext globalObject] invokeMethod:method withArguments:args];
}
diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
index 12c4cc4..ad181ac 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
@@ -315,7 +315,7 @@ static NSDictionary *_customEnvironment = nil;
+ (void)setCustomEnvironment:(NSDictionary *)environment
{
@synchronized (self) {
- _customEnvironment = environment;
+ _customEnvironment = [environment copy];
}
}
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
index 9b5cfae..4cab6a6 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m
@@ -36,6 +36,7 @@
#import "WXCoreBridge.h"
#import "WXDataRenderHandler.h"
#import "WXHandlerFactory.h"
+#import "WXUtility.h"
@interface WXBridgeManager ()
@@ -483,6 +484,8 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void
(^block) (void), NSString*
{
if (!modules) return;
+ modules = [WXUtility convertContainerToImmutable:modules];
+
__weak typeof(self) weakSelf = self;
WXPerformBlockOnBridgeThread(^(){
[weakSelf.bridgeCtx registerModules:modules];
@@ -496,6 +499,8 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void
(^block) (void), NSString*
{
if (!components) return;
+ components = [WXUtility convertContainerToImmutable:components];
+
__weak typeof(self) weakSelf = self;
WXPerformBlockOnBridgeThread(^(){
[weakSelf.bridgeCtx registerComponents:components];
@@ -558,7 +563,7 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void
(^block) (void), NSString*
[instance.apmInstance
updateFSDiffStats:KEY_PAGE_STATS_FS_CALL_EVENT_NUM withDiffValue:1];
}
- WXCallJSMethod *method = [[WXCallJSMethod alloc] initWithModuleName:nil
methodName:@"fireEvent" arguments:args instance:instance];
+ WXCallJSMethod *method = [[WXCallJSMethod alloc] initWithModuleName:nil
methodName:@"fireEvent" arguments:[WXUtility convertContainerToImmutable:args]
instance:instance];
[self callJsMethod:method];
}
@@ -622,7 +627,8 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void
(^block) (void), NSString*
else {
WXCallJSMethod *method = [[WXCallJSMethod alloc]
initWithModuleName:@"jsBridge" methodName:@"callback" arguments:args
instance:instance];
[self callJsMethod:method];
- }}
+ }
+}
- (void)callBack:(NSString *)instanceId funcId:(NSString *)funcId
params:(id)params
{
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
index 71c77d5..d3636ec 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
@@ -159,6 +159,14 @@ _Nonnull SEL WXSwizzledSelectorForSelector(_Nonnull SEL
selector);
*/
+ (id _Nullable)objectFromJSON:(NSString * _Nonnull)json;
+/**
+ Convert all sub-structure objects of source to immutable container.
+
+ @param source Source object.
+ @return Converted object using immutable container.
+ */
++ (id _Nullable)convertContainerToImmutable:(id _Nullable)source;
+
#define WXDecodeJson(json) [WXUtility objectFromJSON:json]
/**
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
index 28119f0..87d16f0 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
@@ -259,6 +259,30 @@ CGFloat WXFloorPixelValue(CGFloat value)
return [self JSONObject:[json dataUsingEncoding:NSUTF8StringEncoding]
error:nil];
}
++ (id _Nullable)convertContainerToImmutable:(id _Nullable)source
+{
+ if (source == nil) {
+ return nil;
+ }
+
+ if ([source isKindOfClass:[NSArray class]]) {
+ NSMutableArray* tmpArray = [[NSMutableArray alloc] init];
+ for (id obj in source) {
+ [tmpArray addObject:[self convertContainerToImmutable:obj]];
+ }
+ return [NSArray arrayWithArray:tmpArray];
+ }
+ else if ([source isKindOfClass:[NSDictionary class]]) {
+ NSMutableDictionary* tmpDictionary = [[NSMutableDictionary alloc]
init];
+ for (id key in [source keyEnumerator]) {
+ tmpDictionary[key] = [self convertContainerToImmutable:[source
objectForKey:key]];
+ }
+ return [NSDictionary dictionaryWithDictionary:tmpDictionary];
+ }
+
+ return source;
+}
+
+ (id)JSONObject:(NSData*)data error:(NSError **)error
{
if (!data) return nil;