Author: Armin Rigo <[email protected]>
Branch:
Changeset: r97264:215ea348ccb4
Date: 2019-08-26 16:31 +0200
http://bitbucket.org/pypy/pypy/changeset/215ea348ccb4/
Log: Check for a rare case of someone shrinking the buffer from another
thread while using it in a read() variant
diff --git a/pypy/module/_file/readinto.py b/pypy/module/_file/readinto.py
--- a/pypy/module/_file/readinto.py
+++ b/pypy/module/_file/readinto.py
@@ -4,6 +4,14 @@
from rpython.rlib.rposix import c_read
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.module._file.interp_file import is_wouldblock_error, signal_checker
+from pypy.interpreter.error import oefmt
+
+
+def output_slice(space, rwbuffer, target_pos, data):
+ if target_pos + len(data) > rwbuffer.getlength():
+ raise oefmt(space.w_RuntimeError,
+ "target buffer has shrunk during operation")
+ rwbuffer.setslice(target_pos, data)
def direct_readinto(self, w_rwbuffer):
@@ -27,14 +35,14 @@
MAX_PART = 1024 * 1024 # 1 MB
while size > MAX_PART:
data = self.direct_read(MAX_PART)
- rwbuffer.setslice(target_pos, data)
+ output_slice(self.space, rwbuffer, target_pos, data)
target_pos += len(data)
size -= len(data)
if len(data) != MAX_PART:
break
else:
data = self.direct_read(size)
- rwbuffer.setslice(target_pos, data)
+ output_slice(self.space, rwbuffer, target_pos, data)
target_pos += len(data)
else:
@@ -46,7 +54,7 @@
initial_size = min(size, stream.count_buffered_bytes())
if initial_size > 0:
data = stream.read(initial_size)
- rwbuffer.setslice(target_pos, data)
+ output_slice(self.space, rwbuffer, target_pos, data)
target_pos += len(data)
size -= len(data)
diff --git a/pypy/module/_io/interp_bufferedio.py
b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -101,7 +101,7 @@
raise oefmt(space.w_TypeError, "%s() should return bytes",
methodname)
data = space.bytes_w(w_data)
- rwbuffer.setslice(0, data)
+ self.output_slice(space, rwbuffer, 0, data)
return space.newint(len(data))
W_BufferedIOBase.typedef = TypeDef(
@@ -555,7 +555,7 @@
remaining = n
written = 0
if current_size:
- result_buffer.setslice(
+ self.output_slice(space, result_buffer,
written, self.buffer[self.pos:self.pos + current_size])
remaining -= current_size
written += current_size
@@ -600,7 +600,7 @@
if remaining > 0:
if size > remaining:
size = remaining
- result_buffer.setslice(
+ self.output_slice(space, result_buffer,
written, self.buffer[self.pos:self.pos + size])
self.pos += size
written += size
diff --git a/pypy/module/_io/interp_bytesio.py
b/pypy/module/_io/interp_bytesio.py
--- a/pypy/module/_io/interp_bytesio.py
+++ b/pypy/module/_io/interp_bytesio.py
@@ -48,7 +48,7 @@
size = rwbuffer.getlength()
output = self.read(size)
- rwbuffer.setslice(0, output)
+ self.output_slice(space, rwbuffer, 0, output)
return space.newint(len(output))
def write_w(self, space, w_data):
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -389,7 +389,7 @@
return space.w_None
raise wrap_oserror(space, e,
exception_name='w_IOError')
- rwbuffer.setslice(0, buf)
+ self.output_slice(space, rwbuffer, 0, buf)
return space.newint(len(buf))
else:
# optimized case: reading more than 64 bytes into a rwbuffer
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -275,6 +275,14 @@
else:
break
+ @staticmethod
+ def output_slice(space, rwbuffer, target_pos, data):
+ if target_pos + len(data) > rwbuffer.getlength():
+ raise oefmt(space.w_RuntimeError,
+ "target buffer has shrunk during operation")
+ rwbuffer.setslice(target_pos, data)
+
+
W_IOBase.typedef = TypeDef(
'_io._IOBase',
__new__ = generic_new_descr(W_IOBase),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit