summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-06-24 22:49:57 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-06-24 22:49:57 (GMT)
commit94fbaac58def9d3c289e5904e82a1598d4577f9a (patch)
treecc59a0cfda417af407a5b985b483922787409b6e /Modules
parent53ec7d53d09ed475c2b0856777f58c721660b8ee (diff)
downloadcpython-94fbaac58def9d3c289e5904e82a1598d4577f9a.zip
cpython-94fbaac58def9d3c289e5904e82a1598d4577f9a.tar.gz
cpython-94fbaac58def9d3c289e5904e82a1598d4577f9a.tar.bz2
Merged revisions 82204 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r82204 | antoine.pitrou | 2010-06-25 00:34:04 +0200 (ven., 25 juin 2010) | 5 lines Issue #8682: The ssl module now temporary increments the reference count of a socket object got through `PyWeakref_GetObject`, so as to avoid possible deallocation while the object is still being used. ........
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_ssl.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 5bc2e50..52fd3f9 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -199,8 +199,11 @@ PySSL_SetError(PySSLObject *obj, int ret, char *filename, int lineno)
errstr = "EOF occurred in violation of protocol";
} else if (ret == -1) {
/* underlying BIO reported an I/O error */
+ Py_INCREF(s);
ERR_clear_error();
- return s->errorhandler();
+ v = s->errorhandler();
+ Py_DECREF(s);
+ return v;
} else { /* possible? */
p = PY_SSL_ERROR_SYSCALL;
errstr = "Some I/O error occurred";
@@ -454,6 +457,7 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
return NULL;
}
+ Py_INCREF(sock);
/* just in case the blocking state of the socket has been changed */
nonblocking = (sock->sock_timeout >= 0.0);
@@ -468,9 +472,8 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
ret = SSL_do_handshake(self->ssl);
err = SSL_get_error(self->ssl, ret);
PySSL_END_ALLOW_THREADS
- if(PyErr_CheckSignals()) {
- return NULL;
- }
+ if (PyErr_CheckSignals())
+ goto error;
if (err == SSL_ERROR_WANT_READ) {
sockstate = check_socket_and_wait_for_timeout(sock, 0);
} else if (err == SSL_ERROR_WANT_WRITE) {
@@ -481,19 +484,20 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
if (sockstate == SOCKET_HAS_TIMED_OUT) {
PyErr_SetString(PySSLErrorObject,
ERRSTR("The handshake operation timed out"));
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
PyErr_SetString(PySSLErrorObject,
ERRSTR("Underlying socket has been closed."));
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
PyErr_SetString(PySSLErrorObject,
ERRSTR("Underlying socket too large for select()."));
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_IS_NONBLOCKING) {
break;
}
} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+ Py_DECREF(sock);
if (ret < 1)
return PySSL_SetError(self, ret, __FILE__, __LINE__);
self->ssl->debug = 1;
@@ -506,6 +510,10 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
Py_INCREF(Py_None);
return Py_None;
+
+error:
+ Py_DECREF(sock);
+ return NULL;
}
static PyObject *
@@ -1175,9 +1183,12 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
return NULL;
}
+ Py_INCREF(sock);
- if (!PyArg_ParseTuple(args, "y#:write", &data, &count))
+ if (!PyArg_ParseTuple(args, "y#:write", &data, &count)) {
+ Py_DECREF(sock);
return NULL;
+ }
/* just in case the blocking state of the socket has been changed */
nonblocking = (sock->sock_timeout >= 0.0);
@@ -1188,15 +1199,15 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
if (sockstate == SOCKET_HAS_TIMED_OUT) {
PyErr_SetString(PySSLErrorObject,
"The write operation timed out");
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
PyErr_SetString(PySSLErrorObject,
"Underlying socket has been closed.");
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
PyErr_SetString(PySSLErrorObject,
"Underlying socket too large for select().");
- return NULL;
+ goto error;
}
do {
err = 0;
@@ -1204,9 +1215,8 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
len = SSL_write(self->ssl, data, count);
err = SSL_get_error(self->ssl, len);
PySSL_END_ALLOW_THREADS
- if(PyErr_CheckSignals()) {
- return NULL;
- }
+ if (PyErr_CheckSignals())
+ goto error;
if (err == SSL_ERROR_WANT_READ) {
sockstate = check_socket_and_wait_for_timeout(sock, 0);
} else if (err == SSL_ERROR_WANT_WRITE) {
@@ -1217,19 +1227,25 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
if (sockstate == SOCKET_HAS_TIMED_OUT) {
PyErr_SetString(PySSLErrorObject,
"The write operation timed out");
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
PyErr_SetString(PySSLErrorObject,
"Underlying socket has been closed.");
- return NULL;
+ goto error;
} else if (sockstate == SOCKET_IS_NONBLOCKING) {
break;
}
} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
+
+ Py_DECREF(sock);
if (len > 0)
return PyLong_FromLong(len);
else
return PySSL_SetError(self, len, __FILE__, __LINE__);
+
+error:
+ Py_DECREF(sock);
+ return NULL;
}
PyDoc_STRVAR(PySSL_SSLwrite_doc,
@@ -1277,21 +1293,23 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
return NULL;
}
+ Py_INCREF(sock);
if (!PyArg_ParseTuple(args, "|Oi:read", &dest, &count))
- return NULL;
+ goto error;
+
if ((dest == NULL) || (dest == Py_None)) {
if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
- return NULL;
+ goto error;
mem = PyByteArray_AS_STRING(dest);
} else if (PyLong_Check(dest)) {
len = PyLong_AS_LONG(dest);
if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
- return NULL;
+ goto error;
mem = PyByteArray_AS_STRING(dest);
} else {
if (PyObject_GetBuffer(dest, &buf, PyBUF_CONTIG) < 0)
- return NULL;
+ goto error;
mem = buf.buf;
len = buf.len;
if ((count > 0) && (count <= len))
@@ -1358,6 +1376,7 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
goto error;
}
done:
+ Py_DECREF(sock);
if (!buf_passed) {
PyObject *res = PyBytes_FromStringAndSize(mem, count);
Py_DECREF(dest);
@@ -1367,8 +1386,9 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
return PyLong_FromLong(count);
}
error:
+ Py_DECREF(sock);
if (!buf_passed) {
- Py_DECREF(dest);
+ Py_XDECREF(dest);
} else {
PyBuffer_Release(&buf);
}
@@ -1393,6 +1413,7 @@ static PyObject *PySSL_SSLshutdown(PySSLObject *self)
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
return NULL;
}
+ Py_INCREF(sock);
/* Just in case the blocking state of the socket has been changed */
nonblocking = (sock->sock_timeout >= 0.0);
@@ -1442,24 +1463,29 @@ static PyObject *PySSL_SSLshutdown(PySSLObject *self)
else
PyErr_SetString(PySSLErrorObject,
"The write operation timed out");
- return NULL;
+ goto error;
}
else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
PyErr_SetString(PySSLErrorObject,
"Underlying socket too large for select().");
- return NULL;
+ goto error;
}
else if (sockstate != SOCKET_OPERATION_OK)
/* Retain the SSL error code */
break;
}
- if (err < 0)
+ if (err < 0) {
+ Py_DECREF(sock);
return PySSL_SetError(self, err, __FILE__, __LINE__);
- else {
- Py_INCREF(sock);
- return (PyObject *) sock;
}
+ else
+ /* It's already INCREF'ed */
+ return (PyObject *) sock;
+
+error:
+ Py_DECREF(sock);
+ return NULL;
}
PyDoc_STRVAR(PySSL_SSLshutdown_doc,