You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by mo...@apache.org on 2019/09/23 13:27:13 UTC
[incubator-weex] branch master updated: [iOS] Protect for invalid
JSON object on iOS13 which will crash.
This is an automated email from the ASF dual-hosted git repository.
moshen 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 1461699 [iOS] Protect for invalid JSON object on iOS13 which will crash.
new 315f88f Merge pull request #2931 from wqyfavor/fix_json_crash_ios13
1461699 is described below
commit 146169900bdc8093cec47817d3dccfc9d763be23
Author: qianyuan.wqy <qi...@taobao.com>
AuthorDate: Mon Sep 23 21:08:16 2019 +0800
[iOS] Protect for invalid JSON object on iOS13 which will crash.
---
ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm | 8 ++++
ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h | 1 +
ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m | 2 +
ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m | 6 +++
ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h | 8 ++++
.../WeexSDK/Sources/Utility/WXConvertUtility.mm | 53 ++++++++++++++++++++++
6 files changed, 78 insertions(+)
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
index e241609..d739d63 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
@@ -1302,6 +1302,7 @@ break; \
_customPages[sId] = page;
}
+ SetConvertCurrentPage(pageId);
[WXCustomPageBridge parseRenderObject:data parentRef:"" index:0 genObject:^(const std::string &ref, const std::string &type, const std::string &parentRef, std::map<std::string, std::string> *styles, std::map<std::string, std::string> *attrs, std::set<std::string> *events, int index) {
if (parentRef.empty()) {
// is root body
@@ -1343,6 +1344,7 @@ break; \
{
RenderPageCustom* page = [self getPage:pageId];
if (page && page->IsValid()) {
+ SetConvertCurrentPage(pageId);
page->UpdateAttr([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
}
}
@@ -1351,6 +1353,7 @@ break; \
{
RenderPageCustom* page = [self getPage:pageId];
if (page && page->IsValid()) {
+ SetConvertCurrentPage(pageId);
page->UpdateStyle([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
}
}
@@ -1406,6 +1409,7 @@ break; \
if (target && target->shouldHandleModuleMethod([moduleName UTF8String] ?: "", [methodName UTF8String] ?: "")) {
__block const char* seralizedArguments = nullptr;
__block const char* seralizedOptions = nullptr;
+ SetConvertCurrentPage(pageId);
ConvertToCString(arguments, ^(const char * value) {
if (value != nullptr) {
seralizedArguments = strdup(value);
@@ -1495,6 +1499,7 @@ break; \
if (target) {
__block const char* seralizedArguments = nullptr;
__block const char* seralizedOptions = nullptr;
+ SetConvertCurrentPage(pageId);
ConvertToCString(arguments, ^(const char * value) {
if (value != nullptr) {
seralizedArguments = strdup(value);
@@ -1847,6 +1852,7 @@ static WeexCore::ScriptBridge* jsBridge = nullptr;
return;
}
+ SetConvertCurrentPage(pageId);
const std::string page([pageId UTF8String] ?: "");
RenderManager::GetInstance()->CreatePage(page, [&] (RenderPage* pageInstance) -> RenderObject* {
pageInstance->set_before_layout_needed(false); // we do not need before and after layout
@@ -1868,11 +1874,13 @@ static WeexCore::ScriptBridge* jsBridge = nullptr;
+ (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
+ SetConvertCurrentPage(pageId);
WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
}
+ (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
+ SetConvertCurrentPage(pageId);
WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
}
diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
index 449ab92..17fa069 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
@@ -107,6 +107,7 @@ typedef NS_ENUM(int, WXSDKErrCode)
WX_KEY_EXCEPTION_EMPTY_SCREEN_NATIVE = -9701,
WX_KEY_EXCEPTION_NO_BUNDLE_TYPE = -9801,
+ WX_KEY_EXCEPTION_INVALID_JSON_OBJECT = -9802,
WX_KEY_EXCEPTION_HERON_ERROR = -9900,
WX_KEY_EXCEPTION_HERON_RENDER_ERROR = -9901,
diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
index 8d7bc9d..0f06927 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
@@ -105,6 +105,8 @@
@(WX_KEY_EXCEPTION_NO_BUNDLE_TYPE):@{ERROR_TYPE:@(WX_JS_ERROR),ERROR_GROUP:@(WX_JS)},
+ @(WX_KEY_EXCEPTION_INVALID_JSON_OBJECT):@{ERROR_TYPE:@(WX_JS_ERROR),ERROR_GROUP:@(WX_JS)},
+
@(WX_KEY_EXCEPTION_HERON_ERROR):@{ERROR_TYPE:@(WX_NATIVE_ERROR),ERROR_GROUP:@(WX_NATIVE)},
@(WX_KEY_EXCEPTION_HERON_RENDER_ERROR):@{ERROR_TYPE:@(WX_RENDER_ERROR),ERROR_GROUP:@(WX_NATIVE)},
};
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
index 1a09028..360ad4f 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
@@ -49,6 +49,7 @@
#import "WXJSCoreBridge.h"
#import "WXSDKInstance_performance.h"
#import "WXPageEventNotifyEvent.h"
+#import "WXConvertUtility.h"
#import "WXCoreBridge.h"
#import <WeexSDK/WXDataRenderHandler.h>
@@ -599,6 +600,11 @@ typedef enum : NSUInteger {
if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
BOOL enableRTLLayoutDirection = [[configCenter configForKey:@"iOS_weex_ext_config.enableRTLLayoutDirection" defaultValue:@(YES) isDefault:NULL] boolValue];
[WXUtility setEnableRTLLayoutDirection:enableRTLLayoutDirection];
+
+ BOOL isIOS13 = [[[UIDevice currentDevice] systemVersion] integerValue] == 13;
+ BOOL useMRCForInvalidJSONObject = [[configCenter configForKey:@"iOS_weex_ext_config.useMRCForInvalidJSONObject" defaultValue:@(YES) isDefault:NULL] boolValue];
+ BOOL alwaysUseMRCForObjectToWeexCore = [[configCenter configForKey:@"iOS_weex_ext_config.alwaysUseMRC" defaultValue:@(NO) isDefault:NULL] boolValue];
+ ConvertSwitches(isIOS13, useMRCForInvalidJSONObject, alwaysUseMRCForObjectToWeexCore);
}
return NO;
}
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h b/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h
index a5e64f5..2cd8f9b 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h
@@ -47,6 +47,14 @@ NSMutableArray* _Nonnull NSARRAY(std::vector<std::unordered_map<std::string, std
void ConvertToCString(id _Nonnull obj, void (^ _Nonnull callback)(const char* _Nullable));
+extern "C" {
+ void SetConvertCurrentPage(NSString* _Nonnull pageId);
+ void ConvertSwitches(BOOL isIOS13, BOOL invalidJSONObjectUseMRC, BOOL alwaysUseMRC);
+}
+
+#else
+void SetConvertCurrentPage(NSString* _Nonnull pageId);
+void ConvertSwitches(BOOL isIOS13, BOOL invalidJSONObjectUseMRC, BOOL alwaysUseMRC);
#endif
#endif
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.mm b/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.mm
index bec9105..65d035d 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.mm
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.mm
@@ -20,10 +20,32 @@
#import "WXConvertUtility.h"
#import "WXLog.h"
#import "WXAssert.h"
+#import "WXExceptionUtils.h"
+#import "WXSDKError.h"
+
#include <vector>
#include <string>
static NSString* const JSONSTRING_SUFFIX = @"\t\n\t\r";
+static NSString* const OBJC_MRC_SUFFIX = @"\t\t\n\r";
+
+static BOOL bIsIOS13 = NO;
+static BOOL bUseMRCForInvalidJSONObject = NO;
+static BOOL bAlwaysUseMRC = NO;
+
+static NSString* sCurrentPage = nil;
+
+void SetConvertCurrentPage(NSString* pageId)
+{
+ sCurrentPage = pageId;
+}
+
+void ConvertSwitches(BOOL isIOS13, BOOL invalidJSONObjectUseMRC, BOOL alwaysUseMRC)
+{
+ bIsIOS13 = isIOS13;
+ bUseMRCForInvalidJSONObject = invalidJSONObjectUseMRC;
+ bAlwaysUseMRC = alwaysUseMRC;
+}
#if 0
@@ -78,6 +100,28 @@ NSString* TO_JSON(id object)
_detectObjectRecursion(object, nodes);
#endif
+ if (bAlwaysUseMRC) {
+ return [NSString stringWithFormat:@"%p%@", (__bridge_retained void*)object, OBJC_MRC_SUFFIX];
+ }
+
+ if (bIsIOS13) {
+ if (![NSJSONSerialization isValidJSONObject:object]) {
+ [WXExceptionUtils commitCriticalExceptionRT:sCurrentPage
+ errCode:[NSString stringWithFormat:@"%d", WX_KEY_EXCEPTION_INVALID_JSON_OBJECT]
+ function:@""
+ exception:@"Invalid JSON object."
+ extParams:nil];
+
+ // Report for instance.
+ if (bUseMRCForInvalidJSONObject) {
+ return [NSString stringWithFormat:@"%p%@", (__bridge_retained void*)object, OBJC_MRC_SUFFIX];
+ }
+ else {
+ return nil;
+ }
+ }
+ }
+
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:object
options:0
@@ -126,6 +170,15 @@ id TO_OBJECT(NSString* s)
WXAssert(NO, @"Fail to convert json to object. %@", exception);
}
}
+ else if ([s hasSuffix:OBJC_MRC_SUFFIX]) {
+ NSScanner* scanner = [NSScanner scannerWithString:s];
+ unsigned long long address = 0;
+ [scanner scanHexLongLong:&address];
+ if (address != 0) {
+ return (__bridge_transfer id)((void*)address);
+ }
+ }
+
return s; // return s instead
}