Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-87020: Revert "use SSL_write/read_ex() GH-27271, GH-25468" #95593

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Doc/library/ssl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1078,11 +1078,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)
Expand Down
11 changes: 0 additions & 11 deletions Lib/test/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,17 +888,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):

Expand Down
40 changes: 22 additions & 18 deletions Modules/_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2302,8 +2302,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;
Expand All @@ -2321,6 +2320,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);
Expand Down Expand Up @@ -2351,8 +2356,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;

Expand Down Expand Up @@ -2386,11 +2391,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);
Expand Down Expand Up @@ -2424,7 +2429,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})
]
Expand All @@ -2434,14 +2439,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;
Expand Down Expand Up @@ -2504,8 +2508,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;

Expand Down Expand Up @@ -2539,8 +2543,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)
Expand All @@ -2553,7 +2557,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
return dest;
}
else {
return PyLong_FromSize_t(count);
return PyLong_FromLong(count);
}

error:
Expand Down
12 changes: 6 additions & 6 deletions Modules/clinic/_ssl.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.