Bug #340899 - Validate getaddrinfo() results.
diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py
index 83b7bb9..0ac7e3d 100644
--- a/pym/_emerge/actions.py
+++ b/pym/_emerge/actions.py
@@ -59,6 +59,7 @@
 from _emerge.search import search
 from _emerge.SetArg import SetArg
 from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
+from _emerge.sync.getaddrinfo_validate import getaddrinfo_validate
 from _emerge.sync.old_tree_timestamp import old_tree_timestamp_warn
 from _emerge.unmerge import unmerge
 from _emerge.UnmergeDepPriority import UnmergeDepPriority
@@ -2086,34 +2087,46 @@
 			("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
 			family = socket.AF_INET6
 
+		addrinfos = None
 		uris = []
 
 		try:
-			addrinfos = socket.getaddrinfo(hostname, None,
-				family, socket.SOCK_STREAM)
+			addrinfos = getaddrinfo_validate(
+				socket.getaddrinfo(hostname, None,
+				family, socket.SOCK_STREAM))
 		except socket.error as e:
-			writemsg("!!! getaddrinfo failed for '%s': %s\n" % (hostname, e), noiselevel=-1)
+			writemsg_level(
+				"!!! getaddrinfo failed for '%s': %s\n" % (hostname, e),
+				noiselevel=-1, level=logging.ERROR)
+
+		if not addrinfos:
 			# With some configurations we need to use the plain hostname
 			# rather than try to resolve the ip addresses (bug #340817).
 			uris.append(syncuri)
 		else:
+
+			AF_INET = socket.AF_INET
+			AF_INET6 = None
+			if socket.has_ipv6:
+				AF_INET6 = socket.AF_INET6
+
 			ips_v4 = []
 			ips_v6 = []
 
 			for addrinfo in addrinfos:
-				if socket.has_ipv6 and addrinfo[0] == socket.AF_INET6:
+				if addrinfo[0] == AF_INET:
+					ips_v4.append("%s" % addrinfo[4][0])
+				elif AF_INET6 is not None and addrinfo[0] == AF_INET6:
 					# IPv6 addresses need to be enclosed in square brackets
 					ips_v6.append("[%s]" % addrinfo[4][0])
-				else:
-					ips_v4.append(addrinfo[4][0])
 
 			random.shuffle(ips_v4)
 			random.shuffle(ips_v6)
 
 			# Give priority to the address family that
 			# getaddrinfo() returned first.
-			if socket.has_ipv6 and addrinfos and \
-				addrinfos[0][0] == socket.AF_INET6:
+			if AF_INET6 is not None and addrinfos and \
+				addrinfos[0][0] == AF_INET6:
 				ips = ips_v6 + ips_v4
 			else:
 				ips = ips_v4 + ips_v6
diff --git a/pym/_emerge/sync/getaddrinfo_validate.py b/pym/_emerge/sync/getaddrinfo_validate.py
new file mode 100644
index 0000000..5e6009c
--- /dev/null
+++ b/pym/_emerge/sync/getaddrinfo_validate.py
@@ -0,0 +1,29 @@
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import sys
+
+if sys.hexversion >= 0x3000000:
+	basestring = str
+
+def getaddrinfo_validate(addrinfos):
+	"""
+	Validate structures returned from getaddrinfo(),
+	since they may be corrupt, especially when python
+	has IPv6 support disabled (bug #340899).
+	"""
+	valid_addrinfos = []
+	for addrinfo in addrinfos:
+		try:
+			if len(addrinfo) != 5:
+				continue
+			if len(addrinfo[4]) < 2:
+				continue
+			if not isinstance(addrinfo[4][0], basestring):
+				continue
+		except TypeError:
+			continue
+
+		valid_addrinfos.append(addrinfo)
+
+	return valid_addrinfos