diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2010-06-24 22:49:57 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2010-06-24 22:49:57 (GMT) |
commit | 94fbaac58def9d3c289e5904e82a1598d4577f9a (patch) | |
tree | cc59a0cfda417af407a5b985b483922787409b6e /Modules | |
parent | 53ec7d53d09ed475c2b0856777f58c721660b8ee (diff) | |
download | cpython-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.c | 80 |
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, |