Skip to content
This repository was archived by the owner on Jun 3, 2021. It is now read-only.

Commit 1461699

Browse files
author
qianyuan.wqy
committed
[iOS] Protect for invalid JSON object on iOS13 which will crash.
1 parent ec1ec23 commit 1461699

File tree

6 files changed

+78
-0
lines changed

6 files changed

+78
-0
lines changed

ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,7 @@ - (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
13021302
_customPages[sId] = page;
13031303
}
13041304

1305+
SetConvertCurrentPage(pageId);
13051306
[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) {
13061307
if (parentRef.empty()) {
13071308
// is root body
@@ -1343,6 +1344,7 @@ - (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*
13431344
{
13441345
RenderPageCustom* page = [self getPage:pageId];
13451346
if (page && page->IsValid()) {
1347+
SetConvertCurrentPage(pageId);
13461348
page->UpdateAttr([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
13471349
}
13481350
}
@@ -1351,6 +1353,7 @@ - (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*
13511353
{
13521354
RenderPageCustom* page = [self getPage:pageId];
13531355
if (page && page->IsValid()) {
1356+
SetConvertCurrentPage(pageId);
13541357
page->UpdateStyle([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
13551358
}
13561359
}
@@ -1406,6 +1409,7 @@ - (BOOL)forwardCallNativeModuleToCustomPage:(NSString*)pageId
14061409
if (target && target->shouldHandleModuleMethod([moduleName UTF8String] ?: "", [methodName UTF8String] ?: "")) {
14071410
__block const char* seralizedArguments = nullptr;
14081411
__block const char* seralizedOptions = nullptr;
1412+
SetConvertCurrentPage(pageId);
14091413
ConvertToCString(arguments, ^(const char * value) {
14101414
if (value != nullptr) {
14111415
seralizedArguments = strdup(value);
@@ -1495,6 +1499,7 @@ - (void)forwardCallComponentToCustomPage:(NSString*)pageId
14951499
if (target) {
14961500
__block const char* seralizedArguments = nullptr;
14971501
__block const char* seralizedOptions = nullptr;
1502+
SetConvertCurrentPage(pageId);
14981503
ConvertToCString(arguments, ^(const char * value) {
14991504
if (value != nullptr) {
15001505
seralizedArguments = strdup(value);
@@ -1847,6 +1852,7 @@ + (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
18471852
return;
18481853
}
18491854

1855+
SetConvertCurrentPage(pageId);
18501856
const std::string page([pageId UTF8String] ?: "");
18511857
RenderManager::GetInstance()->CreatePage(page, [&] (RenderPage* pageInstance) -> RenderObject* {
18521858
pageInstance->set_before_layout_needed(false); // we do not need before and after layout
@@ -1868,11 +1874,13 @@ + (void)callMoveElement:(NSString*)pageId ref:(NSString*)ref parentRef:(NSString
18681874

18691875
+ (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
18701876
{
1877+
SetConvertCurrentPage(pageId);
18711878
WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
18721879
}
18731880

18741881
+ (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
18751882
{
1883+
SetConvertCurrentPage(pageId);
18761884
WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
18771885
}
18781886

ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ typedef NS_ENUM(int, WXSDKErrCode)
107107
WX_KEY_EXCEPTION_EMPTY_SCREEN_NATIVE = -9701,
108108

109109
WX_KEY_EXCEPTION_NO_BUNDLE_TYPE = -9801,
110+
WX_KEY_EXCEPTION_INVALID_JSON_OBJECT = -9802,
110111

111112
WX_KEY_EXCEPTION_HERON_ERROR = -9900,
112113
WX_KEY_EXCEPTION_HERON_RENDER_ERROR = -9901,

ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ +(NSDictionary *) getMap
105105

106106
@(WX_KEY_EXCEPTION_NO_BUNDLE_TYPE):@{ERROR_TYPE:@(WX_JS_ERROR),ERROR_GROUP:@(WX_JS)},
107107

108+
@(WX_KEY_EXCEPTION_INVALID_JSON_OBJECT):@{ERROR_TYPE:@(WX_JS_ERROR),ERROR_GROUP:@(WX_JS)},
109+
108110
@(WX_KEY_EXCEPTION_HERON_ERROR):@{ERROR_TYPE:@(WX_NATIVE_ERROR),ERROR_GROUP:@(WX_NATIVE)},
109111
@(WX_KEY_EXCEPTION_HERON_RENDER_ERROR):@{ERROR_TYPE:@(WX_RENDER_ERROR),ERROR_GROUP:@(WX_NATIVE)},
110112
};

ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#import "WXJSCoreBridge.h"
5050
#import "WXSDKInstance_performance.h"
5151
#import "WXPageEventNotifyEvent.h"
52+
#import "WXConvertUtility.h"
5253
#import "WXCoreBridge.h"
5354
#import <WeexSDK/WXDataRenderHandler.h>
5455

@@ -599,6 +600,11 @@ - (BOOL)_handleConfigCenter
599600
if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
600601
BOOL enableRTLLayoutDirection = [[configCenter configForKey:@"iOS_weex_ext_config.enableRTLLayoutDirection" defaultValue:@(YES) isDefault:NULL] boolValue];
601602
[WXUtility setEnableRTLLayoutDirection:enableRTLLayoutDirection];
603+
604+
BOOL isIOS13 = [[[UIDevice currentDevice] systemVersion] integerValue] == 13;
605+
BOOL useMRCForInvalidJSONObject = [[configCenter configForKey:@"iOS_weex_ext_config.useMRCForInvalidJSONObject" defaultValue:@(YES) isDefault:NULL] boolValue];
606+
BOOL alwaysUseMRCForObjectToWeexCore = [[configCenter configForKey:@"iOS_weex_ext_config.alwaysUseMRC" defaultValue:@(NO) isDefault:NULL] boolValue];
607+
ConvertSwitches(isIOS13, useMRCForInvalidJSONObject, alwaysUseMRCForObjectToWeexCore);
602608
}
603609
return NO;
604610
}

ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ NSMutableArray* _Nonnull NSARRAY(std::vector<std::unordered_map<std::string, std
4747

4848
void ConvertToCString(id _Nonnull obj, void (^ _Nonnull callback)(const char* _Nullable));
4949

50+
extern "C" {
51+
void SetConvertCurrentPage(NSString* _Nonnull pageId);
52+
void ConvertSwitches(BOOL isIOS13, BOOL invalidJSONObjectUseMRC, BOOL alwaysUseMRC);
53+
}
54+
55+
#else
56+
void SetConvertCurrentPage(NSString* _Nonnull pageId);
57+
void ConvertSwitches(BOOL isIOS13, BOOL invalidJSONObjectUseMRC, BOOL alwaysUseMRC);
5058
#endif
5159

5260
#endif

ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.mm

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,32 @@
2020
#import "WXConvertUtility.h"
2121
#import "WXLog.h"
2222
#import "WXAssert.h"
23+
#import "WXExceptionUtils.h"
24+
#import "WXSDKError.h"
25+
2326
#include <vector>
2427
#include <string>
2528

2629
static NSString* const JSONSTRING_SUFFIX = @"\t\n\t\r";
30+
static NSString* const OBJC_MRC_SUFFIX = @"\t\t\n\r";
31+
32+
static BOOL bIsIOS13 = NO;
33+
static BOOL bUseMRCForInvalidJSONObject = NO;
34+
static BOOL bAlwaysUseMRC = NO;
35+
36+
static NSString* sCurrentPage = nil;
37+
38+
void SetConvertCurrentPage(NSString* pageId)
39+
{
40+
sCurrentPage = pageId;
41+
}
42+
43+
void ConvertSwitches(BOOL isIOS13, BOOL invalidJSONObjectUseMRC, BOOL alwaysUseMRC)
44+
{
45+
bIsIOS13 = isIOS13;
46+
bUseMRCForInvalidJSONObject = invalidJSONObjectUseMRC;
47+
bAlwaysUseMRC = alwaysUseMRC;
48+
}
2749

2850
#if 0
2951

@@ -78,6 +100,28 @@ void _detectObjectRecursion(id object, NSMutableSet* nodes)
78100
_detectObjectRecursion(object, nodes);
79101
#endif
80102

103+
if (bAlwaysUseMRC) {
104+
return [NSString stringWithFormat:@"%p%@", (__bridge_retained void*)object, OBJC_MRC_SUFFIX];
105+
}
106+
107+
if (bIsIOS13) {
108+
if (![NSJSONSerialization isValidJSONObject:object]) {
109+
[WXExceptionUtils commitCriticalExceptionRT:sCurrentPage
110+
errCode:[NSString stringWithFormat:@"%d", WX_KEY_EXCEPTION_INVALID_JSON_OBJECT]
111+
function:@""
112+
exception:@"Invalid JSON object."
113+
extParams:nil];
114+
115+
// Report for instance.
116+
if (bUseMRCForInvalidJSONObject) {
117+
return [NSString stringWithFormat:@"%p%@", (__bridge_retained void*)object, OBJC_MRC_SUFFIX];
118+
}
119+
else {
120+
return nil;
121+
}
122+
}
123+
}
124+
81125
NSError *error = nil;
82126
NSData *data = [NSJSONSerialization dataWithJSONObject:object
83127
options:0
@@ -126,6 +170,15 @@ id TO_OBJECT(NSString* s)
126170
WXAssert(NO, @"Fail to convert json to object. %@", exception);
127171
}
128172
}
173+
else if ([s hasSuffix:OBJC_MRC_SUFFIX]) {
174+
NSScanner* scanner = [NSScanner scannerWithString:s];
175+
unsigned long long address = 0;
176+
[scanner scanHexLongLong:&address];
177+
if (address != 0) {
178+
return (__bridge_transfer id)((void*)address);
179+
}
180+
}
181+
129182
return s; // return s instead
130183
}
131184

0 commit comments

Comments
 (0)