Skip to content

Commit bed7f1a

Browse files
committed
Issue python#23804: Fix SSL zero-length recv() calls to not block and raise EOF
1 parent c95300a commit bed7f1a

3 files changed

Lines changed: 32 additions & 8 deletions

File tree

Lib/test/test_ssl.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,20 +2793,13 @@ def _recvfrom_into():
27932793
# consume data
27942794
s.read()
27952795

2796-
data = b"data"
2797-
27982796
# read(-1, buffer) is supported, even though read(-1) is not
2797+
data = b"data"
27992798
s.send(data)
28002799
buffer = bytearray(len(data))
28012800
self.assertEqual(s.read(-1, buffer), len(data))
28022801
self.assertEqual(buffer, data)
28032802

2804-
# recv/read(0) should return no data
2805-
s.send(data)
2806-
self.assertEqual(s.recv(0), b"")
2807-
self.assertEqual(s.read(0), b"")
2808-
self.assertEqual(s.read(), data)
2809-
28102803
# Make sure sendmsg et al are disallowed to avoid
28112804
# inadvertent disclosure of data and/or corruption
28122805
# of the encrypted data stream
@@ -2822,6 +2815,26 @@ def _recvfrom_into():
28222815

28232816
s.close()
28242817

2818+
def test_recv_zero(self):
2819+
server = ThreadedEchoServer(CERTFILE)
2820+
server.__enter__()
2821+
self.addCleanup(server.__exit__, None, None)
2822+
s = socket.create_connection((HOST, server.port))
2823+
self.addCleanup(s.close)
2824+
s = ssl.wrap_socket(s, suppress_ragged_eofs=False)
2825+
self.addCleanup(s.close)
2826+
2827+
# recv/read(0) should return no data
2828+
s.send(b"data")
2829+
self.assertEqual(s.recv(0), b"")
2830+
self.assertEqual(s.read(0), b"")
2831+
self.assertEqual(s.read(), b"data")
2832+
2833+
# Should not block if the other end sends no data
2834+
s.setblocking(False)
2835+
self.assertEqual(s.recv(0), b"")
2836+
self.assertEqual(s.recv_into(bytearray()), 0)
2837+
28252838
def test_nonblocking_send(self):
28262839
server = ThreadedEchoServer(CERTFILE,
28272840
certreqs=ssl.CERT_NONE,

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ Core and Builtins
1919
Library
2020
-------
2121

22+
- Issue #23804: Fix SSL zero-length recv() calls to not block and not raise
23+
an error about unclean EOF.
24+
2225
- Issue #27466: Change time format returned by http.cookie.time2netscape,
2326
confirming the netscape cookie format and making it consistent with
2427
documentation.

Modules/_ssl.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,10 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1,
19131913
dest = PyBytes_FromStringAndSize(NULL, len);
19141914
if (dest == NULL)
19151915
goto error;
1916+
if (len == 0) {
1917+
Py_XDECREF(sock);
1918+
return dest;
1919+
}
19161920
mem = PyBytes_AS_STRING(dest);
19171921
}
19181922
else {
@@ -1924,6 +1928,10 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1,
19241928
"maximum length can't fit in a C 'int'");
19251929
goto error;
19261930
}
1931+
if (len == 0) {
1932+
count = 0;
1933+
goto done;
1934+
}
19271935
}
19281936
}
19291937

0 commit comments

Comments
 (0)