summaryrefslogtreecommitdiffstats
path: root/Lib/_pyio.py
diff options
context:
space:
mode:
author6t8k <58048945+6t8k@users.noreply.github.com>2024-02-17 11:16:06 (GMT)
committerGitHub <noreply@github.com>2024-02-17 11:16:06 (GMT)
commit26800cf25a0970d46934fa9a881c0ef6881d642b (patch)
tree94787f4406c4ab79490877d58612437787fd2068 /Lib/_pyio.py
parentd5a30a1777f04523c7b151b894e999f5714d8e96 (diff)
downloadcpython-26800cf25a0970d46934fa9a881c0ef6881d642b.zip
cpython-26800cf25a0970d46934fa9a881c0ef6881d642b.tar.gz
cpython-26800cf25a0970d46934fa9a881c0ef6881d642b.tar.bz2
gh-95782: Fix io.BufferedReader.tell() etc. being able to return offsets < 0 (GH-99709)
lseek() always returns 0 for character pseudo-devices like `/dev/urandom` (for other non-regular files, e.g. `/dev/stdin`, it always returns -1, to which CPython reacts by raising appropriate exceptions). They are thus technically seekable despite not having seek semantics. When calling read() on e.g. an instance of `io.BufferedReader` that wraps such a file, `BufferedReader` reads ahead, filling its buffer, creating a discrepancy between the number of bytes read and the internal `tell()` always returning 0, which previously resulted in e.g. `BufferedReader.tell()` or `BufferedReader.seek()` being able to return positions < 0 even though these are supposed to be always >= 0. Invariably keep the return value non-negative by returning max(former_return_value, 0) instead, and add some corresponding tests.
Diffstat (limited to 'Lib/_pyio.py')
-rw-r--r--Lib/_pyio.py3
1 files changed, 2 insertions, 1 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 8a0d0dc..a3fede6 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1197,7 +1197,8 @@ class BufferedReader(_BufferedIOMixin):
return written
def tell(self):
- return _BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos
+ # GH-95782: Keep return value non-negative
+ return max(_BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos, 0)
def seek(self, pos, whence=0):
if whence not in valid_seek_flags: