summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2011-02-25 23:07:44 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2011-02-25 23:07:44 (GMT)
commit68e5c044e898c474750baeaee3234be8e27b5607 (patch)
treeca1deb15535e8a4b352b052406bc3e539db71836
parentfc1cf41911fcb91da0802ebc4e49e7f342f59e21 (diff)
downloadcpython-68e5c044e898c474750baeaee3234be8e27b5607.zip
cpython-68e5c044e898c474750baeaee3234be8e27b5607.tar.gz
cpython-68e5c044e898c474750baeaee3234be8e27b5607.tar.bz2
Issue #7322: Trying to read from a socket's file-like object after a timeout
occurred now raises an error instead of silently losing data. Patch by Ross Lagerwall.
-rw-r--r--Lib/socket.py6
-rw-r--r--Lib/test/test_socket.py17
-rw-r--r--Misc/NEWS3
3 files changed, 26 insertions, 0 deletions
diff --git a/Lib/socket.py b/Lib/socket.py
index 95901ae..1e28549 100644
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -257,6 +257,7 @@ class SocketIO(io.RawIOBase):
self._mode = mode
self._reading = "r" in mode
self._writing = "w" in mode
+ self._timeout_occurred = False
def readinto(self, b):
"""Read up to len(b) bytes into the writable buffer *b* and return
@@ -268,9 +269,14 @@ class SocketIO(io.RawIOBase):
"""
self._checkClosed()
self._checkReadable()
+ if self._timeout_occurred:
+ raise IOError("cannot read from timed out object")
while True:
try:
return self._sock.recv_into(b)
+ except timeout:
+ self._timeout_occurred = True
+ raise
except error as e:
n = e.args[0]
if n == EINTR:
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 9d5d8ca..5a5a214 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1109,6 +1109,23 @@ class FileObjectClassTestCase(SocketConnectedTest):
self.write_file = None
SocketConnectedTest.clientTearDown(self)
+ def testReadAfterTimeout(self):
+ # Issue #7322: A file object must disallow further reads
+ # after a timeout has occurred.
+ self.cli_conn.settimeout(1)
+ self.read_file.read(3)
+ # First read raises a timeout
+ self.assertRaises(socket.timeout, self.read_file.read, 1)
+ # Second read is disallowed
+ with self.assertRaises(IOError) as ctx:
+ self.read_file.read(1)
+ self.assertIn("cannot read from timed out object", str(ctx.exception))
+
+ def _testReadAfterTimeout(self):
+ self.write_file.write(self.write_msg[0:3])
+ self.write_file.flush()
+ self.serv_finished.wait()
+
def testSmallRead(self):
# Performing small file read test
first_seg = self.read_file.read(len(self.read_msg)-3)
diff --git a/Misc/NEWS b/Misc/NEWS
index 59e01cd..443f15f 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -35,6 +35,9 @@ Core and Builtins
Library
-------
+- Issue #7322: Trying to read from a socket's file-like object after a timeout
+ occurred now raises an error instead of silently losing data.
+
- Issue 11291: poplib.POP no longer suppresses errors on quit().
- Issue 11177: asyncore's create_socket() arguments can now be omitted.