Check of return values and proper error handling.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 9817872..27eb313 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -344,9 +344,12 @@
case AF_INET:
{
struct sockaddr_in *a = (struct sockaddr_in *) addr;
- PyObject *addr = makeipaddr(a);
- PyObject *ret = Py_BuildValue("Oi", addr, ntohs(a->sin_port));
- Py_XDECREF(addr);
+ PyObject *addrobj = makeipaddr(a);
+ PyObject *ret = NULL;
+ if (addrobj) {
+ ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port));
+ Py_DECREF(addrobj);
+ }
return ret;
}
@@ -361,7 +364,8 @@
/* More cases here... */
default:
- PyErr_SetString(PySocket_Error, "return unknown socket address type");
+ PyErr_SetString(PySocket_Error,
+ "return unknown socket address type");
return NULL;
}
@@ -389,7 +393,8 @@
if (!PyArg_Parse(args, "s#", &path, &len))
return 0;
if (len > sizeof addr->sun_path) {
- PyErr_SetString(PySocket_Error, "AF_UNIX path too long");
+ PyErr_SetString(PySocket_Error,
+ "AF_UNIX path too long");
return 0;
}
addr->sun_family = AF_UNIX;
@@ -468,7 +473,10 @@
{
char addrbuf[256];
int addrlen, newfd;
- PyObject *sock, *addr, *res;
+ PyObject *sock = NULL;
+ PyObject *addr = NULL;
+ PyObject *res = NULL;
+
if (!PyArg_NoArgs(args))
return NULL;
if (!getsockaddrlen(s, &addrlen))
@@ -478,16 +486,24 @@
Py_END_ALLOW_THREADS
if (newfd < 0)
return PySocket_Err();
+
/* Create the new object with unspecified family,
to avoid calls to bind() etc. on it. */
sock = (PyObject *) PySocketSock_New(newfd,
s->sock_family,
s->sock_type,
s->sock_proto);
- if (sock == NULL)
+ if (sock == NULL) {
close(newfd);
- addr = makesockaddr((struct sockaddr *) addrbuf, addrlen);
- res = Py_BuildValue("OO", sock, addr);
+ goto finally;
+ }
+ if (!(addr = makesockaddr((struct sockaddr *) addrbuf, addrlen)))
+ goto finally;
+
+ if (!(res = Py_BuildValue("OO", sock, addr)))
+ goto finally;
+
+ finally:
Py_XDECREF(sock);
Py_XDECREF(addr);
return res;
@@ -543,7 +559,8 @@
}
else {
PyErr_Clear();
- if (!PyArg_Parse(args, "(iis#)", &level, &optname, &buf, &buflen))
+ if (!PyArg_Parse(args, "(iis#)", &level, &optname,
+ &buf, &buflen))
return NULL;
}
res = setsockopt(s->sock_fd, level, optname, (ANY *)buf, buflen);
@@ -581,7 +598,8 @@
return PyInt_FromLong(flag);
}
if (buflen <= 0 || buflen > 1024) {
- PyErr_SetString(PySocket_Error, "getsockopt buflen out of range");
+ PyErr_SetString(PySocket_Error,
+ "getsockopt buflen out of range");
return NULL;
}
buf = PyString_FromStringAndSize((char *)NULL, buflen);
@@ -683,9 +701,9 @@
if (newfd < 0)
return PySocket_Err();
sock = (PyObject *) PySocketSock_New(newfd,
- s->sock_family,
- s->sock_type,
- s->sock_proto);
+ s->sock_family,
+ s->sock_type,
+ s->sock_proto);
if (sock == NULL)
close(newfd);
return sock;
@@ -825,7 +843,10 @@
BUILD_FUNC_DEF_2(PySocketSock_recvfrom,PySocketSockObject *,s, PyObject *,args)
{
char addrbuf[256];
- PyObject *buf, *addr, *ret;
+ PyObject *buf = NULL;
+ PyObject *addr = NULL;
+ PyObject *ret = NULL;
+
int addrlen, len, n, flags = 0;
if (!PyArg_ParseTuple(args, "i|i", &len, &flags))
return NULL;
@@ -837,10 +858,11 @@
Py_BEGIN_ALLOW_THREADS
n = recvfrom(s->sock_fd, PyString_AsString(buf), len, flags,
#ifndef MS_WINDOWS
- (ANY *)addrbuf, &addrlen);
+ (ANY *)addrbuf, &addrlen
#else
- (struct sockaddr *)addrbuf, &addrlen);
+ (struct sockaddr *)addrbuf, &addrlen
#endif
+ );
Py_END_ALLOW_THREADS
if (n < 0) {
Py_DECREF(buf);
@@ -848,8 +870,12 @@
}
if (n != len && _PyString_Resize(&buf, n) < 0)
return NULL;
- addr = makesockaddr((struct sockaddr *)addrbuf, addrlen);
+
+ if (!(addr = makesockaddr((struct sockaddr *)addrbuf, addrlen)))
+ goto finally;
+
ret = Py_BuildValue("OO", buf, addr);
+ finally:
Py_XDECREF(addr);
Py_XDECREF(buf);
return ret;
@@ -1073,19 +1099,25 @@
if ((addr_list = PyList_New(0)) == NULL)
goto err;
for (pch = h->h_aliases; *pch != NULL; pch++) {
+ int status;
tmp = PyString_FromString(*pch);
if (tmp == NULL)
goto err;
- PyList_Append(name_list, tmp);
+ status = PyList_Append(name_list, tmp);
Py_DECREF(tmp);
+ if (status)
+ goto err;
}
for (pch = h->h_addr_list; *pch != NULL; pch++) {
+ int status;
memcpy((char *) &addr.sin_addr, *pch, h->h_length);
tmp = makeipaddr(&addr);
if (tmp == NULL)
goto err;
- PyList_Append(addr_list, tmp);
+ status = PyList_Append(addr_list, tmp);
Py_DECREF(tmp);
+ if (status)
+ goto err;
}
rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
err:
@@ -1276,20 +1308,18 @@
/* Convenience routine to export an integer value.
- For simplicity, errors (which are unlikely anyway) are ignored. */
-
+ *
+ * Since this function is called only from initsocket/init_socket(), any
+ * errors trigger a fatal exception.
+ */
static void
BUILD_FUNC_DEF_3(insint,PyObject *,d, char *,name, int,value)
{
PyObject *v = PyInt_FromLong((long) value);
- if (v == NULL) {
- /* Don't bother reporting this error */
- PyErr_Clear();
- }
- else {
- PyDict_SetItemString(d, name, v);
- Py_DECREF(v);
- }
+ if (!v || PyDict_SetItemString(d, name, v))
+ Py_FatalError("can't initialize socket module");
+
+ Py_DECREF(v);
}