Skip to content

Commit f89b505

Browse files
lukeharveyzoontek
authored andcommitted
Fix crash in RCTWebSocketModule when delegate callbacks fire after module invalidation (facebook#55858)
Summary: Guard against nil socketID in all SRWebSocketDelegate callbacks in RCTWebSocketModule. When the module is invalidated during teardown, invalidate nils the delegate and closes each socket. However, SocketRocket's network thread may have already dispatched a delegate callback to the main queue via setDelegateDispatchQueue:. By the time the block executes, the SRWebSocket has been deallocated and reactTag (an associated object) returns nil, causing either an objc_retain crash on a dangling pointer or an NSInvalidArgumentException when inserting nil into an NSDictionary literal. The didFailWithError: callback already had a partial nil guard (socketID ?: @(-1)), but didCloseWithCode:, webSocketDidOpen:, and didReceiveMessage: did not. This adds consistent early-return nil checks to all four callbacks. Previously reported in facebook#28278, facebook#29525, and facebook#31048 — all closed by the stale bot without a fix being merged. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [IOS] [FIXED] - Fix crash in RCTWebSocketModule when delegate callbacks fire after module invalidation Pull Request resolved: facebook#55858 Test Plan: This is a race condition during module teardown that is difficult to reproduce deterministically — it surfaces in production Crashlytics reports (< 0.1% of sessions). The fix is a nil guard matching the defensive pattern already present in didFailWithError:. Reviewed By: javache Differential Revision: D95056045 Pulled By: cipolleschi fbshipit-source-id: 02d715dfdf1816b5366ec077849d560133a857c8
1 parent fdc8f40 commit f89b505

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

packages/react-native/React/CoreModules/RCTWebSocketModule.mm

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
166166
NSString *type;
167167

168168
NSNumber *socketID = [webSocket reactTag];
169+
if (!socketID) {
170+
return;
171+
}
169172
id contentHandler = _contentHandlers[socketID];
170173
if (contentHandler) {
171174
message = [contentHandler processWebsocketMessage:message forSocketID:socketID withType:&type];
@@ -178,18 +181,25 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
178181
}
179182
}
180183

181-
[self sendEventWithName:@"websocketMessage" body:@{@"data" : message, @"type" : type, @"id" : webSocket.reactTag}];
184+
[self sendEventWithName:@"websocketMessage" body:@{@"data" : message, @"type" : type, @"id" : socketID}];
182185
}
183186

184187
- (void)webSocketDidOpen:(SRWebSocket *)webSocket
185188
{
189+
NSNumber *socketID = [webSocket reactTag];
190+
if (!socketID) {
191+
return;
192+
}
186193
[self sendEventWithName:@"websocketOpen"
187-
body:@{@"id" : webSocket.reactTag, @"protocol" : webSocket.protocol ? webSocket.protocol : @""}];
194+
body:@{@"id" : socketID, @"protocol" : webSocket.protocol ? webSocket.protocol : @""}];
188195
}
189196

190197
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
191198
{
192199
NSNumber *socketID = [webSocket reactTag];
200+
if (!socketID) {
201+
return;
202+
}
193203
_contentHandlers[socketID] = nil;
194204
_sockets[socketID] = nil;
195205
NSDictionary *body =
@@ -203,6 +213,9 @@ - (void)webSocket:(SRWebSocket *)webSocket
203213
wasClean:(BOOL)wasClean
204214
{
205215
NSNumber *socketID = [webSocket reactTag];
216+
if (!socketID) {
217+
return;
218+
}
206219
_contentHandlers[socketID] = nil;
207220
_sockets[socketID] = nil;
208221
[self sendEventWithName:@"websocketClosed"

0 commit comments

Comments
 (0)