mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-10 09:12:46 +08:00
Fixed fuzzer app and ensured that React does not crash when fuzzed
This commit is contained in:
@@ -218,9 +218,10 @@ class MessageQueue {
|
||||
return null;
|
||||
}
|
||||
|
||||
let fn = null;
|
||||
let self = this;
|
||||
if (type === MethodTypes.remoteAsync) {
|
||||
return function(...args) {
|
||||
fn = function(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
self.__nativeCall(module, method, args, resolve, (errorData) => {
|
||||
var error = createErrorFromErrorData(errorData);
|
||||
@@ -229,7 +230,7 @@ class MessageQueue {
|
||||
});
|
||||
};
|
||||
} else {
|
||||
return function(...args) {
|
||||
fn = function(...args) {
|
||||
let lastArg = args.length > 0 ? args[args.length - 1] : null;
|
||||
let secondLastArg = args.length > 1 ? args[args.length - 2] : null;
|
||||
let hasSuccCB = typeof lastArg === 'function';
|
||||
@@ -245,6 +246,8 @@ class MessageQueue {
|
||||
return self.__nativeCall(module, method, args, onFail, onSucc);
|
||||
};
|
||||
}
|
||||
fn.type = type;
|
||||
return fn;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#import "RCTLog.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
typedef void (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
|
||||
typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
|
||||
|
||||
@implementation RCTMethodArgument
|
||||
|
||||
@@ -166,6 +166,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) { \
|
||||
_logic \
|
||||
[invocation setArgument:&value atIndex:(index) + 2]; \
|
||||
return YES; \
|
||||
}];
|
||||
|
||||
__weak RCTModuleMethod *weakSelf = self;
|
||||
@@ -174,7 +175,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
|
||||
if (RCT_DEBUG && json && ![json isKindOfClass:[NSNumber class]]) {
|
||||
RCTLogArgumentError(weakSelf, index, json, "should be a function");
|
||||
return;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
|
||||
@@ -268,13 +269,13 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
|
||||
if (RCT_DEBUG && json && ![json isKindOfClass:[NSNumber class]]) {
|
||||
RCTLogArgumentError(weakSelf, index, json, "should be a function");
|
||||
return;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
|
||||
__autoreleasing id value = (json ? ^(NSError *error) {
|
||||
[bridge _invokeAndProcessModule:@"BatchedBridge"
|
||||
method:@"invokeCallbackAndReturnFlushedQueue"
|
||||
method:@"invokeCallbackAndReturnFlushedQueue"
|
||||
arguments:@[json, @[RCTJSErrorFromNSError(error)]]];
|
||||
} : ^(__unused NSError *error) {});
|
||||
)
|
||||
@@ -285,7 +286,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
RCT_ARG_BLOCK(
|
||||
if (RCT_DEBUG && ![json isKindOfClass:[NSNumber class]]) {
|
||||
RCTLogArgumentError(weakSelf, index, json, "should be a promise resolver function");
|
||||
return;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
|
||||
@@ -302,7 +303,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
RCT_ARG_BLOCK(
|
||||
if (RCT_DEBUG && ![json isKindOfClass:[NSNumber class]]) {
|
||||
RCTLogArgumentError(weakSelf, index, json, "should be a promise rejecter function");
|
||||
return;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
|
||||
@@ -350,12 +351,11 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
if (nullability == RCTNonnullable) {
|
||||
RCTArgumentBlock oldBlock = argumentBlocks[i - 2];
|
||||
argumentBlocks[i - 2] = ^(RCTBridge *bridge, NSUInteger index, id json) {
|
||||
if (json == nil || json == (id)kCFNull) {
|
||||
if (json == nil) {
|
||||
RCTLogArgumentError(weakSelf, index, typeName, "must not be null");
|
||||
id null = nil;
|
||||
[invocation setArgument:&null atIndex:index + 2];
|
||||
return NO;
|
||||
} else {
|
||||
oldBlock(bridge, index, json);
|
||||
return oldBlock(bridge, index, json);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -408,9 +408,11 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
// Set arguments
|
||||
NSUInteger index = 0;
|
||||
for (id json in arguments) {
|
||||
id arg = RCTNilIfNull(json);
|
||||
RCTArgumentBlock block = _argumentBlocks[index];
|
||||
block(bridge, index, arg);
|
||||
if (!block(bridge, index, RCTNilIfNull(json))) {
|
||||
// Invalid argument, abort
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
|
||||
}), @"js_call,json_call", (@{@"objectName": objectName}))];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setContextName:(NSString *)name)
|
||||
RCT_EXPORT_METHOD(setContextName:(nonnull NSString *)name)
|
||||
{
|
||||
if (JSGlobalContextSetName != NULL) {
|
||||
JSStringRef JSName = JSStringCreateWithCFString((__bridge CFStringRef)name);
|
||||
|
||||
@@ -820,6 +820,7 @@ RCT_EXPORT_METHOD(findSubviewIn:(nonnull NSNumber *)reactTag atPoint:(CGPoint)po
|
||||
- (void)batchDidComplete
|
||||
{
|
||||
RCTProfileBeginEvent();
|
||||
|
||||
// Gather blocks to be executed now that all view hierarchy manipulations have
|
||||
// been completed (note that these may still take place before layout has finished)
|
||||
for (RCTComponentData *componentData in _componentDataByName.allValues) {
|
||||
@@ -871,8 +872,13 @@ RCT_EXPORT_METHOD(findSubviewIn:(nonnull NSNumber *)reactTag atPoint:(CGPoint)po
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
RCTProfileEndFlowEvent();
|
||||
RCTProfileBeginEvent();
|
||||
for (dispatch_block_t block in previousPendingUIBlocks) {
|
||||
block();
|
||||
@try {
|
||||
for (dispatch_block_t block in previousPendingUIBlocks) {
|
||||
block();
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Exception thrown while executing UI block: %@", exception);
|
||||
}
|
||||
RCTProfileEndEvent(@"UIManager flushUIBlocks", @"objc_call", @{
|
||||
@"count": @(previousPendingUIBlocks.count),
|
||||
@@ -1043,7 +1049,7 @@ RCT_EXPORT_METHOD(setMainScrollViewTag:(nonnull NSNumber *)reactTag)
|
||||
uiManager.mainScrollView = (id<RCTScrollableProtocol>)view;
|
||||
uiManager.mainScrollView.nativeMainScrollDelegate = uiManager.nativeMainScrollDelegate;
|
||||
} else {
|
||||
RCTAssert(NO, @"Tag #%@ does not conform to RCTScrollableProtocol", reactTag);
|
||||
RCTLogError(@"Tag #%@ does not conform to RCTScrollableProtocol", reactTag);
|
||||
}
|
||||
} else {
|
||||
uiManager.mainScrollView = nil;
|
||||
|
||||
@@ -62,8 +62,9 @@ RCT_EXPORT_METHOD(goBack:(nonnull NSNumber *)reactTag)
|
||||
RCTWebView *view = viewRegistry[reactTag];
|
||||
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||
RCTLogError(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view);
|
||||
} else {
|
||||
[view goBack];
|
||||
}
|
||||
[view goBack];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -73,8 +74,9 @@ RCT_EXPORT_METHOD(goForward:(nonnull NSNumber *)reactTag)
|
||||
id view = viewRegistry[reactTag];
|
||||
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||
RCTLogError(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view);
|
||||
} else {
|
||||
[view goForward];
|
||||
}
|
||||
[view goForward];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -84,9 +86,10 @@ RCT_EXPORT_METHOD(reload:(nonnull NSNumber *)reactTag)
|
||||
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||
RCTWebView *view = viewRegistry[reactTag];
|
||||
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||
RCTLogMustFix(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view);
|
||||
RCTLogError(@"Invalid view returned from registry, expecting RCTWebView, got: %@", view);
|
||||
} else {
|
||||
[view reload];
|
||||
}
|
||||
[view reload];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user