adium 2775:0a721697cd88: Fix a crash when addresses is empty. Th...

commits at adium.im commits at adium.im
Sat Oct 24 22:37:10 UTC 2009


details:	http://hg.adium.im/adium/rev/0a721697cd88
revision:	2775:0a721697cd88
author:		Zachary West <zacw at adium.im>
date:		Sat Oct 24 18:29:23 2009 -0400

Fix a crash when addresses is empty. This, my friends, is why I dislike CF.

diffs (195 lines):

diff -r b8ac67a7deae -r 0a721697cd88 Frameworks/AIUtilities Framework/Source/AIHostReachabilityMonitor.m
--- a/Frameworks/AIUtilities Framework/Source/AIHostReachabilityMonitor.m	Sat Oct 24 16:47:32 2009 -0400
+++ b/Frameworks/AIUtilities Framework/Source/AIHostReachabilityMonitor.m	Sat Oct 24 18:29:23 2009 -0400
@@ -273,7 +273,7 @@
 		//CFHostGetAddressing returns a CFArrayRef of CFDataRefs which wrap struct sockaddr
 		CFArrayRef addresses = CFHostGetAddressing(theHost, NULL);
 		
-		if (!CFArrayGetCount(addresses)) {
+		if (!addresses || !CFArrayGetCount(addresses)) {
 			/* We were not able to resolve the host name to an IP address.  This is most likely because we have no
 			 * Internet connection or because the user is attempting to connect to MSN.
 			 *
@@ -281,96 +281,96 @@
 			 */
 			[self addUnconfiguredHost:host
 							 observer:observer];
-		}
-		
-		// Only add 1 observer for IPv6 and one for IPv4.
-		BOOL addedIPv4 = NO, addedIPv6 = NO;
-		
-		for (NSData *saData in (NSArray *)addresses) {
-			struct sockaddr							*remoteAddr = (struct sockaddr *)saData.bytes;
+		} else if (addresses) {
+			// Only add 1 observer for IPv6 and one for IPv4.
+			BOOL addedIPv4 = NO, addedIPv6 = NO;
 			
-			if ((remoteAddr->sa_family == AF_INET && addedIPv4) || (remoteAddr->sa_family == AF_INET6 && addedIPv6)) {
-				continue;
-			}
-			
-			if (remoteAddr->sa_family == AF_INET)
-				addedIPv4 = YES;
-			if (remoteAddr->sa_family == AF_INET6)
-				addedIPv6 = YES;
-						
-			SCNetworkReachabilityRef		reachabilityRef;
-			SCNetworkReachabilityContext	reachabilityContext = {
-				.version         = 0,
-				.info            = self,
-				.retain          = CFRetain,
-				.release         = CFRelease,
-				.copyDescription = CFCopyDescription,
-			};
-			SCNetworkConnectionFlags				flags;
-			struct sockaddr_in						localAddr;
-			
-			/* Create a reachability reference pair with localhost and the remote host */
-			
-			//Our local address is 127.0.0.1
-			bzero(&localAddr, sizeof(localAddr));
-			localAddr.sin_len = sizeof(localAddr);
-			localAddr.sin_family = AF_INET;
-			inet_aton("127.0.0.1", &localAddr.sin_addr);
-			
-			//Create the pair
-			reachabilityRef = SCNetworkReachabilityCreateWithAddressPair(NULL, 
-																		 (struct sockaddr *)&localAddr, 
-																		 remoteAddr);
-			
-			//Configure our callback
-			SCNetworkReachabilitySetCallback(reachabilityRef, 
-											 hostReachabilityChangedCallback, 
-											 &reachabilityContext);
-			
-			//Add it to the run loop so we will receive the notifications
-			SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef,
-													 CFRunLoopGetCurrent(),
-													 kCFRunLoopDefaultMode);
-			
-			//Note that we succesfully configured for reachability notifications
-			[self gotReachabilityRef:(SCNetworkReachabilityRef)[(NSObject *)reachabilityRef autorelease]
-							 forHost:host
-							observer:observer];
-
-			if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
-				//We already have valid flags for the reachabilityRef
-		#if CONNECTIVITY_DEBUG
-				NSLog(@"Immediate reachability info for %@", reachabilityRef);
-		#endif
-				hostReachabilityChangedCallback(reachabilityRef,
-												flags,
-												self);
-
-			} else {
-				/* Perform an immediate reachability check, since we've just scheduled checks for future changes
-				* and won't be notified immediately.  We update the hostContext to include our reachabilityRef before
-				* scheduling the info resolution (it's still in our run loop from when we requested the IP address).
-				*/
-				CFHostClientContext	hostContext = {
-					.version		 = 0,
-					.info			 = [NSDictionary dictionaryWithObjectsAndKeys:
-						self, @"self",
-						host, @"host",
-						observer, @"observer",
-						reachabilityRef, @"reachabilityRef",
-						nil],
-					.retain			 = CFRetain,
-					.release		 = CFRelease,
+			for (NSData *saData in (NSArray *)addresses) {
+				struct sockaddr							*remoteAddr = (struct sockaddr *)saData.bytes;
+				
+				if ((remoteAddr->sa_family == AF_INET && addedIPv4) || (remoteAddr->sa_family == AF_INET6 && addedIPv6)) {
+					continue;
+				}
+				
+				if (remoteAddr->sa_family == AF_INET)
+					addedIPv4 = YES;
+				if (remoteAddr->sa_family == AF_INET6)
+					addedIPv6 = YES;
+							
+				SCNetworkReachabilityRef		reachabilityRef;
+				SCNetworkReachabilityContext	reachabilityContext = {
+					.version         = 0,
+					.info            = self,
+					.retain          = CFRetain,
+					.release         = CFRelease,
 					.copyDescription = CFCopyDescription,
 				};
-				CFHostSetClient(theHost,
-								hostResolvedCallback,
-								&hostContext);
-				CFHostStartInfoResolution(theHost,
-										  kCFHostReachability,
-										  NULL);
+				SCNetworkConnectionFlags				flags;
+				struct sockaddr_in						localAddr;
+				
+				/* Create a reachability reference pair with localhost and the remote host */
+				
+				//Our local address is 127.0.0.1
+				bzero(&localAddr, sizeof(localAddr));
+				localAddr.sin_len = sizeof(localAddr);
+				localAddr.sin_family = AF_INET;
+				inet_aton("127.0.0.1", &localAddr.sin_addr);
+				
+				//Create the pair
+				reachabilityRef = SCNetworkReachabilityCreateWithAddressPair(NULL, 
+																			 (struct sockaddr *)&localAddr, 
+																			 remoteAddr);
+				
+				//Configure our callback
+				SCNetworkReachabilitySetCallback(reachabilityRef, 
+												 hostReachabilityChangedCallback, 
+												 &reachabilityContext);
+				
+				//Add it to the run loop so we will receive the notifications
+				SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef,
+														 CFRunLoopGetCurrent(),
+														 kCFRunLoopDefaultMode);
+				
+				//Note that we succesfully configured for reachability notifications
+				[self gotReachabilityRef:(SCNetworkReachabilityRef)[(NSObject *)reachabilityRef autorelease]
+								 forHost:host
+								observer:observer];
+
+				if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
+					//We already have valid flags for the reachabilityRef
+			#if CONNECTIVITY_DEBUG
+					NSLog(@"Immediate reachability info for %@", reachabilityRef);
+			#endif
+					hostReachabilityChangedCallback(reachabilityRef,
+													flags,
+													self);
+
+				} else {
+					/* Perform an immediate reachability check, since we've just scheduled checks for future changes
+					* and won't be notified immediately.  We update the hostContext to include our reachabilityRef before
+					* scheduling the info resolution (it's still in our run loop from when we requested the IP address).
+					*/
+					CFHostClientContext	hostContext = {
+						.version		 = 0,
+						.info			 = [NSDictionary dictionaryWithObjectsAndKeys:
+							self, @"self",
+							host, @"host",
+							observer, @"observer",
+							reachabilityRef, @"reachabilityRef",
+							nil],
+						.retain			 = CFRetain,
+						.release		 = CFRelease,
+						.copyDescription = CFCopyDescription,
+					};
+					CFHostSetClient(theHost,
+									hostResolvedCallback,
+									&hostContext);
+					CFHostStartInfoResolution(theHost,
+											  kCFHostReachability,
+											  NULL);
+				}
+
 			}
-
 		}
 		
 	} else if (typeInfo == kCFHostReachability) {




More information about the commits mailing list