[pypy-commit] pypy py3.5: _collections.deque: Raise MemoryError if the size of the deque multiplied by an integer is larger than what would fit in an RPython int.

mjacob pypy.commits at gmail.com
Fri Jun 1 09:30:31 EDT 2018


Author: Manuel Jacob <me at manueljacob.de>
Branch: py3.5
Changeset: r94719:381f24401707
Date: 2018-06-01 15:29 +0200
http://bitbucket.org/pypy/pypy/changeset/381f24401707/

Log:	_collections.deque: Raise MemoryError if the size of the deque
	multiplied by an integer is larger than what would fit in an RPython
	int.

diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -1,5 +1,6 @@
 import sys
 from rpython.rlib.objectmodel import specialize
+from rpython.rlib.rarithmetic import ovfcheck
 from pypy.interpreter import gateway
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
@@ -192,9 +193,13 @@
 
     def mul(self, w_int):
         space = self.space
+        num = space.int_w(w_int)
+        try:
+            ovfcheck(self.len * num)
+        except OverflowError:
+            raise MemoryError
         copied = W_Deque(space)
         copied.maxlen = self.maxlen
-        num = space.int_w(w_int)
 
         for _ in range(num):
             copied.extend(self)
@@ -212,6 +217,10 @@
         if num <= 0:
             self.clear()
             return self
+        try:
+            ovfcheck(self.len * num)
+        except OverflowError:
+            raise MemoryError
         # use a copy to extend self
         copy = W_Deque(space)
         copy.maxlen = self.maxlen
diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py
--- a/pypy/module/_collections/test/test_deque.py
+++ b/pypy/module/_collections/test/test_deque.py
@@ -372,6 +372,20 @@
             assert d == deque('a' * n)
             assert d.maxlen is None
 
+    def test_deque_repeat_big(self):
+        import sys
+        from _collections import deque
+        d = deque([0])
+        d *= 2**8
+        if sys.maxsize <= 2147483647:
+            raises(MemoryError, d.__mul__, 2**24)
+            raises(MemoryError, d.__rmul__, 2**24)
+            raises(MemoryError, d.__imul__, 2**24)
+        else:
+            raises(MemoryError, d.__mul__, 2**56)
+            raises(MemoryError, d.__rmul__, 2**56)
+            raises(MemoryError, d.__imul__, 2**56)
+
     def test_deque_insert(self):
         from _collections import deque
         for i in range(0,11):


More information about the pypy-commit mailing list