Skip to content

Commit c541c8c

Browse files
authored
fix: avoid race condition crash in [RCTDataRequestHandler invalidate] (#2383)
## Summary: Upstreaming a fix by @ntre that fixes a crash we saw internally related to `[_queue cancelAllOperations]`. >Calling [_queue cancelAllOperations] will release all references to any active operations. >If the blocks of those operations have a reference to itself, it will result in dangling pointers, which could conceptually trigger a later crash if there's a race between the operation completing and it being pulled out of the queue. > >Add explicit strong reference while block is running. >For good measure, fix same pattern also in RCTFileRequestHandler. > >Note: separately, that this code is passing the op itself as a requestToken to [delegate URLRequest:] methods is suspect. That delegate can retain said token. ## Test Plan: Tested internally.
1 parent 82fd28a commit c541c8c

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

packages/react-native/Libraries/Network/RCTDataRequestHandler.mm

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequ
4040

4141
__weak __block NSBlockOperation *weakOp;
4242
__block NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
43+
// [macOS
44+
NSBlockOperation *strongOp = weakOp; // Strong reference to avoid deallocation during execution
45+
if (strongOp == nil || [strongOp isCancelled]) {
46+
return;
47+
}
48+
// macOS]
49+
4350
// Get mime type
4451
NSRange firstSemicolon = [request.URL.resourceSpecifier rangeOfString:@";"];
4552
NSString *mimeType =
@@ -51,15 +58,15 @@ - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequ
5158
expectedContentLength:-1
5259
textEncodingName:nil];
5360

54-
[delegate URLRequest:weakOp didReceiveResponse:response];
61+
[delegate URLRequest:strongOp didReceiveResponse:response]; // [macOS]
5562

5663
// Load data
5764
NSError *error;
5865
NSData *data = [NSData dataWithContentsOfURL:request.URL options:NSDataReadingMappedIfSafe error:&error];
5966
if (data) {
60-
[delegate URLRequest:weakOp didReceiveData:data];
67+
[delegate URLRequest:strongOp didReceiveData:data]; // [macOS]
6168
}
62-
[delegate URLRequest:weakOp didCompleteWithError:error];
69+
[delegate URLRequest:strongOp didCompleteWithError:error]; // [macOS]
6370
}];
6471

6572
weakOp = op;

packages/react-native/Libraries/Network/RCTFileRequestHandler.mm

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,19 @@ - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequ
4848

4949
__weak __block NSBlockOperation *weakOp;
5050
__block NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
51+
// [macOS
52+
NSBlockOperation *strongOp = weakOp; // Strong reference to avoid deallocation during execution
53+
if (strongOp == nil || [strongOp isCancelled]) {
54+
return;
55+
}
56+
// macOS]
57+
5158
// Get content length
5259
NSError *error = nil;
5360
NSFileManager *fileManager = [NSFileManager new];
5461
NSDictionary<NSString *, id> *fileAttributes = [fileManager attributesOfItemAtPath:request.URL.path error:&error];
5562
if (!fileAttributes) {
56-
[delegate URLRequest:weakOp didCompleteWithError:error];
63+
[delegate URLRequest:strongOp didCompleteWithError:error]; // [macOS]
5764
return;
5865
}
5966

@@ -70,14 +77,14 @@ - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequ
7077
expectedContentLength:[fileAttributes[NSFileSize] ?: @-1 integerValue]
7178
textEncodingName:nil];
7279

73-
[delegate URLRequest:weakOp didReceiveResponse:response];
80+
[delegate URLRequest:strongOp didReceiveResponse:response]; // [macOS]
7481

7582
// Load data
7683
NSData *data = [NSData dataWithContentsOfURL:request.URL options:NSDataReadingMappedIfSafe error:&error];
7784
if (data) {
78-
[delegate URLRequest:weakOp didReceiveData:data];
85+
[delegate URLRequest:strongOp didReceiveData:data]; // [macOS]
7986
}
80-
[delegate URLRequest:weakOp didCompleteWithError:error];
87+
[delegate URLRequest:strongOp didCompleteWithError:error]; // [macOS]
8188
}];
8289

8390
weakOp = op;

0 commit comments

Comments
 (0)