diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index a0aa45e9008a1b..48efe8fb54939c 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1155,11 +1155,6 @@ SSL Sockets to create instances directly. This was never documented or officially supported. - .. versionchanged:: 3.10 - Python now uses ``SSL_read_ex`` and ``SSL_write_ex`` internally. The - functions support reading and writing of data larger than 2 GB. Writing - zero-length data no longer fails with a protocol violation error. - SSL sockets also have the following additional methods and attributes: .. method:: SSLSocket.read(len=1024, buffer=None) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 3b3b869bb53acd..7ddaecdf195e24 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1128,17 +1128,6 @@ def test_connect_ex_error(self): ) self.assertIn(rc, errors) - def test_read_write_zero(self): - # empty reads and writes now work, bpo-42854, bpo-31711 - client_context, server_context, hostname = testing_context() - server = ThreadedEchoServer(context=server_context) - with server: - with client_context.wrap_socket(socket.socket(), - server_hostname=hostname) as s: - s.connect((HOST, server.port)) - self.assertEqual(s.recv(0), b"") - self.assertEqual(s.send(b""), 0) - class ContextTests(unittest.TestCase): diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6071202104fa78..dca648822767f6 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2305,8 +2305,7 @@ static PyObject * _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) /*[clinic end generated code: output=aa7a6be5527358d8 input=77262d994fe5100a]*/ { - size_t count = 0; - int retval; + int len; int sockstate; _PySSLError err; int nonblocking; @@ -2324,6 +2323,12 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) Py_INCREF(sock); } + if (b->len > INT_MAX) { + PyErr_Format(PyExc_OverflowError, + "string longer than %d bytes", INT_MAX); + goto error; + } + if (sock != NULL) { /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); @@ -2354,8 +2359,8 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) do { PySSL_BEGIN_ALLOW_THREADS - retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count); - err = _PySSL_errno(retval == 0, self->ssl, retval); + len = SSL_write(self->ssl, b->buf, (int)b->len); + err = _PySSL_errno(len <= 0, self->ssl, len); PySSL_END_ALLOW_THREADS self->err = err; @@ -2389,11 +2394,11 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) err.ssl == SSL_ERROR_WANT_WRITE); Py_XDECREF(sock); - if (retval == 0) - return PySSL_SetError(self, retval, __FILE__, __LINE__); + if (len <= 0) + return PySSL_SetError(self, len, __FILE__, __LINE__); if (PySSL_ChainExceptions(self) < 0) return NULL; - return PyLong_FromSize_t(count); + return PyLong_FromLong(len); error: Py_XDECREF(sock); PySSL_ChainExceptions(self); @@ -2427,7 +2432,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) /*[clinic input] _ssl._SSLSocket.read - size as len: Py_ssize_t + size as len: int [ buffer: Py_buffer(accept={rwbuffer}) ] @@ -2437,14 +2442,13 @@ Read up to size bytes from the SSL socket. [clinic start generated code]*/ static PyObject * -_ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, - int group_right_1, Py_buffer *buffer) -/*[clinic end generated code: output=49b16e6406023734 input=ec48bf622be1c4a1]*/ +_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, + Py_buffer *buffer) +/*[clinic end generated code: output=00097776cec2a0af input=ff157eb918d0905b]*/ { PyObject *dest = NULL; char *mem; - size_t count = 0; - int retval; + int count; int sockstate; _PySSLError err; int nonblocking; @@ -2507,8 +2511,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, do { PySSL_BEGIN_ALLOW_THREADS - retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count); - err = _PySSL_errno(retval == 0, self->ssl, retval); + count = SSL_read(self->ssl, mem, len); + err = _PySSL_errno(count <= 0, self->ssl, count); PySSL_END_ALLOW_THREADS self->err = err; @@ -2542,8 +2546,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, } while (err.ssl == SSL_ERROR_WANT_READ || err.ssl == SSL_ERROR_WANT_WRITE); - if (retval == 0) { - PySSL_SetError(self, retval, __FILE__, __LINE__); + if (count <= 0) { + PySSL_SetError(self, count, __FILE__, __LINE__); goto error; } if (self->exc_type != NULL) @@ -2556,7 +2560,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, return dest; } else { - return PyLong_FromSize_t(count); + return PyLong_FromLong(count); } error: diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 67b125f3d76167..b9d45968d865d2 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -271,25 +271,25 @@ PyDoc_STRVAR(_ssl__SSLSocket_read__doc__, {"read", (PyCFunction)_ssl__SSLSocket_read, METH_VARARGS, _ssl__SSLSocket_read__doc__}, static PyObject * -_ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, - int group_right_1, Py_buffer *buffer); +_ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, + Py_buffer *buffer); static PyObject * _ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) { PyObject *return_value = NULL; - Py_ssize_t len; + int len; int group_right_1 = 0; Py_buffer buffer = {NULL, NULL}; switch (PyTuple_GET_SIZE(args)) { case 1: - if (!PyArg_ParseTuple(args, "n:read", &len)) { + if (!PyArg_ParseTuple(args, "i:read", &len)) { goto exit; } break; case 2: - if (!PyArg_ParseTuple(args, "nw*:read", &len, &buffer)) { + if (!PyArg_ParseTuple(args, "iw*:read", &len, &buffer)) { goto exit; } group_right_1 = 1; @@ -1361,4 +1361,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=2a488dd0cbc777df input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4bd8aae07d1c50f6 input=a9049054013a1b77]*/