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

Commit

Permalink
[iOS] Protect for invalid JSON object on iOS13 which will crash.
Browse files Browse the repository at this point in the history
  • Loading branch information
qianyuan.wqy committed Sep 23, 2019
1 parent ec1ec23 commit 1461699
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
Expand Up @@ -1302,6 +1302,7 @@ - (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
_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
Expand Down Expand Up @@ -1343,6 +1344,7 @@ - (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*
{
RenderPageCustom* page = [self getPage:pageId];
if (page && page->IsValid()) {
SetConvertCurrentPage(pageId);
page->UpdateAttr([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
}
}
Expand All @@ -1351,6 +1353,7 @@ - (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*
{
RenderPageCustom* page = [self getPage:pageId];
if (page && page->IsValid()) {
SetConvertCurrentPage(pageId);
page->UpdateStyle([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
}
}
Expand Down Expand Up @@ -1406,6 +1409,7 @@ - (BOOL)forwardCallNativeModuleToCustomPage:(NSString*)pageId
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);
Expand Down Expand Up @@ -1495,6 +1499,7 @@ - (void)forwardCallComponentToCustomPage:(NSString*)pageId
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);
Expand Down Expand Up @@ -1847,6 +1852,7 @@ + (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
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
Expand All @@ -1868,11 +1874,13 @@ + (void)callMoveElement:(NSString*)pageId ref:(NSString*)ref parentRef:(NSString

+ (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]);
}

Expand Down
1 change: 1 addition & 0 deletions ios/sdk/WeexSDK/Sources/Engine/WXSDKError.h
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions ios/sdk/WeexSDK/Sources/Engine/WXSDKError.m
Expand Up @@ -105,6 +105,8 @@ +(NSDictionary *) getMap

@(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)},
};
Expand Down
6 changes: 6 additions & 0 deletions ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
Expand Up @@ -49,6 +49,7 @@
#import "WXJSCoreBridge.h"
#import "WXSDKInstance_performance.h"
#import "WXPageEventNotifyEvent.h"
#import "WXConvertUtility.h"
#import "WXCoreBridge.h"
#import <WeexSDK/WXDataRenderHandler.h>

Expand Down Expand Up @@ -599,6 +600,11 @@ - (BOOL)_handleConfigCenter
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;
}
Expand Down
8 changes: 8 additions & 0 deletions ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.h
Expand Up @@ -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
Expand Down
53 changes: 53 additions & 0 deletions ios/sdk/WeexSDK/Sources/Utility/WXConvertUtility.mm
Expand Up @@ -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

Expand Down Expand Up @@ -78,6 +100,28 @@ void _detectObjectRecursion(id object, NSMutableSet* nodes)
_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
Expand Down Expand Up @@ -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
}

Expand Down

0 comments on commit 1461699

Please sign in to comment.