Trent Mick <trentm@activestate.com>:
This patch fixes possible overflows in the socket module for 64-bit
platforms (mainly Win64). The changes are:

- abstract the socket type to SOCKET_T (this is SOCKET on Windows, int
on Un*x), this is necessary because sizeof(SOCKET) > sizeof(int) on
Win64

- use INVALID_SOCKET on Win32/64 for an error return value for
accept()

- ensure no overflow of the socket variable for: (1) a PyObject return
value (use PyLong_FromLongLong if necessary); and (2) printf
formatting in repr().

Closes SourceForge patch #100516.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 2c0fc56..31ec8fc 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -221,6 +221,20 @@
 #define FORCE_ANSI_FUNC_DEFS
 #endif
 
+/* abstract the socket file descriptor type */
+#ifdef MS_WINDOWS
+typedef SOCKET SOCKET_T;
+#	ifdef MS_WIN64
+#		define SIZEOF_SOCKET_T 8
+#	else
+#		define SIZEOF_SOCKET_T 4
+#	endif
+#else
+typedef int SOCKET_T;
+#	define SIZEOF_SOCKET_T SIZEOF_INT
+#endif
+
+
 #if defined(PYOS_OS2)
 #define SOCKETCLOSE soclose
 #define NO_DUP /* Sockets are Not Actual File Handles under OS/2 */
@@ -337,7 +351,7 @@
 
 typedef struct {
 	PyObject_HEAD
-	int sock_fd;		/* Socket file descriptor */
+	SOCKET_T sock_fd;		/* Socket file descriptor */
 	int sock_family;	/* Address family, e.g., AF_INET */
 	int sock_type;		/* Socket type, e.g., SOCK_STREAM */
 	int sock_proto;		/* Protocol type, usually 0 */
@@ -387,7 +401,7 @@
    in NEWOBJ()). */
 
 static PySocketSockObject *
-BUILD_FUNC_DEF_4(PySocketSock_New,int,fd, int,family, int,type, int,proto)
+BUILD_FUNC_DEF_4(PySocketSock_New,SOCKET_T,fd, int,family, int,type, int,proto)
 {
 	PySocketSockObject *s;
 	PySocketSock_Type.ob_type = &PyType_Type;
@@ -666,7 +680,7 @@
 BUILD_FUNC_DEF_2(PySocketSock_accept,PySocketSockObject *,s, PyObject *,args)
 {
 	char addrbuf[256];
-	int newfd;
+	SOCKET_T newfd;
 	socklen_t addrlen;
 	PyObject *sock = NULL;
 	PyObject *addr = NULL;
@@ -679,7 +693,11 @@
 	Py_BEGIN_ALLOW_THREADS
 	newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
 	Py_END_ALLOW_THREADS
+#ifdef MS_WINDOWS
+	if (newfd == INVALID_SOCKET)
+#else
 	if (newfd < 0)
+#endif
 		return PySocket_Err();
 
 	/* Create the new object with unspecified family,
@@ -968,7 +986,11 @@
 {
 	if (!PyArg_ParseTuple(args, ":fileno"))
 		return NULL;
+#if SIZEOF_SOCKET_T <= SIZEOF_LONG
 	return PyInt_FromLong((long) s->sock_fd);
+#else
+	return PyLong_FromLongLong((LONG_LONG)s->sock_fd);
+#endif
 }
 
 static char fileno_doc[] =
@@ -983,7 +1005,7 @@
 static PyObject *
 BUILD_FUNC_DEF_2(PySocketSock_dup,PySocketSockObject *,s, PyObject *,args)
 {
-	int newfd;
+	SOCKET_T newfd;
 	PyObject *sock;
 	if (!PyArg_ParseTuple(args, ":dup"))
 		return NULL;
@@ -1109,7 +1131,11 @@
 	extern int fclose Py_PROTO((FILE *));
 	char *mode = "r";
 	int bufsize = -1;
+#ifdef MS_WIN32
+	intptr_t fd;
+#else
 	int fd;
+#endif	
 	FILE *fp;
 	PyObject *f;
 
@@ -1387,9 +1413,19 @@
 BUILD_FUNC_DEF_1(PySocketSock_repr,PySocketSockObject *,s)
 {
 	char buf[512];
+#if SIZEOF_SOCKET_T > SIZEOF_LONG
+	if (s->sock_fd > LONG_MAX) {
+		/* this can occur on Win64, and actually there is a special
+		   ugly printf formatter for decimal pointer length integer
+		   printing, only bother if necessary*/
+		PyErr_SetString(PyExc_OverflowError,
+			"no printf formatter to display the socket descriptor in decimal");
+		return NULL;
+	}
+#endif
 	sprintf(buf, 
-		"<socket object, fd=%d, family=%d, type=%d, protocol=%d>", 
-		s->sock_fd, s->sock_family, s->sock_type, s->sock_proto);
+		"<socket object, fd=%ld, family=%d, type=%d, protocol=%d>", 
+		(long)s->sock_fd, s->sock_family, s->sock_type, s->sock_proto);
 	return PyString_FromString(buf);
 }
 
@@ -1716,11 +1752,7 @@
 BUILD_FUNC_DEF_2(PySocket_socket,PyObject *,self, PyObject *,args)
 {
 	PySocketSockObject *s;
-#ifdef MS_WINDOWS
-	SOCKET fd;
-#else
-	int fd;
-#endif
+	SOCKET_T fd;
 	int family, type, proto = 0;
 	if (!PyArg_ParseTuple(args, "ii|i:socket", &family, &type, &proto))
 		return NULL;
@@ -1766,7 +1798,8 @@
 BUILD_FUNC_DEF_2(PySocket_fromfd,PyObject *,self, PyObject *,args)
 {
 	PySocketSockObject *s;
-	int fd, family, type, proto = 0;
+	SOCKET_T fd;
+	int family, type, proto = 0;
 	if (!PyArg_ParseTuple(args, "iii|i:fromfd",
 			      &fd, &family, &type, &proto))
 		return NULL;
@@ -2113,7 +2146,7 @@
 static PyObject *SSL_SSLwrite(SSLObject *self, PyObject *args)
 {
 	char *data;
-	int len = 0;
+	size_t len = 0;
   
 	if (!PyArg_ParseTuple(args, "s|i:write", &data, &len))
 		return NULL;