diff --git a/packages/react-native/React/CoreModules/RCTWebSocketModule.mm b/packages/react-native/React/CoreModules/RCTWebSocketModule.mm index e29d76a76a23..e82bde27dfd7 100644 --- a/packages/react-native/React/CoreModules/RCTWebSocketModule.mm +++ b/packages/react-native/React/CoreModules/RCTWebSocketModule.mm @@ -10,6 +10,7 @@ #import #import +#import #import #import #import @@ -66,6 +67,14 @@ - (void)invalidate connect : (NSURL *)URL protocols : (NSArray *)protocols options : (JS::NativeWebSocketModule::SpecConnectOptions &) options socketID : (double)socketID) { + if ((URL == nil) || URL.absoluteString.length == 0u) { + RCTAssert(NO, @"RCTWebSocketModule: Invalid WebSocket URL passed to connect"); + NSNumber *socketIDNumber = @(socketID); + NSDictionary *body = @{@"message" : @"Invalid WebSocket URL", @"id" : socketIDNumber}; + [self sendEventWithName:@"websocketFailed" body:body]; + return; + } + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; // We load cookies from sharedHTTPCookieStorage (shared with XHR and @@ -77,14 +86,48 @@ - (void)invalidate } // Load and set the cookie header. - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:components.URL]; - request.allHTTPHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies]; + if (components != nil && components.URL != nil) { + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:components.URL]; + request.allHTTPHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies]; + } else { + RCTLogError(@"RCTWebSocketModule: Invalid URL components - components or components.URL is nil"); + } // Load supplied headers if ([options.headers() isKindOfClass:NSDictionary.class]) { NSDictionary *headers = (NSDictionary *)options.headers(); - [headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { - [request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key]; + [headers enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + BOOL validKey = [key isKindOfClass:[NSString class]]; + BOOL validValue = [value isKindOfClass:[NSString class]]; + + if (!validKey && !validValue) { + RCTLogError( + @"RCTWebSocketModule: Invalid header key and value types. " + "Expected NSString for both, got key of type %@ and value of type %@.", + NSStringFromClass([key class]), + NSStringFromClass([value class])); + return; + } + + if (!validKey) { + RCTLogError( + @"RCTWebSocketModule: Invalid header key type for value '%@'. " + "Expected NSString, got %@.", + value, + NSStringFromClass([key class])); + return; + } + + if (!validValue) { + RCTLogError( + @"RCTWebSocketModule: Invalid header value type for key '%@'. " + "Expected NSString, got %@.", + key, + NSStringFromClass([value class])); + } + + NSString *headerValue = validValue ? [RCTConvert NSString:value] : @""; + [request addValue:headerValue forHTTPHeaderField:key]; }]; }