Author: Brian Kearns <[email protected]>
Branch: stdlib-2.7.6
Changeset: r69586:de582fef597e
Date: 2014-03-01 18:37 -0500
http://bitbucket.org/pypy/pypy/changeset/de582fef597e/

Log:    fix old format overflow check

diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -1,7 +1,8 @@
 """
 String formatting routines.
 """
-from pypy.interpreter.error import OperationError
+import sys
+from pypy.interpreter.error import OperationError, oefmt
 from rpython.rlib import jit
 from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rlib.rfloat import formatd, DTSF_ALT, isnan, isinf
@@ -217,7 +218,7 @@
 
             self.peel_flags()
 
-            self.width = self.peel_num()
+            self.width = self.peel_num('width', sys.maxsize)
             if self.width < 0:
                 # this can happen:  '%*s' % (-5, "hi")
                 self.f_ljust = True
@@ -225,7 +226,7 @@
 
             if self.peekchr() == '.':
                 self.forward()
-                self.prec = self.peel_num()
+                self.prec = self.peel_num('prec', sys.maxint)
                 if self.prec < 0:
                     self.prec = 0    # this can happen:  '%.*f' % (-5, 3)
             else:
@@ -263,7 +264,7 @@
 
         # Same as getmappingkey
         @jit.unroll_safe
-        def peel_num(self):
+        def peel_num(self, name, maxval):
             space = self.space
             c = self.peekchr()
             if c == '*':
@@ -272,14 +273,12 @@
                 return space.int_w(maybe_int(space, w_value))
             result = 0
             while True:
-                n = ord(c) - ord('0')
-                if not (0 <= n < 10):
+                digit = ord(c) - ord('0')
+                if not (0 <= digit <= 9):
                     break
-                try:
-                    result = ovfcheck(ovfcheck(result * 10) + n)
-                except OverflowError:
-                    raise OperationError(space.w_OverflowError,
-                                         space.wrap("precision too large"))
+                if result > (maxval - digit) / 10:
+                    raise oefmt(space.w_ValueError, "%s too big", name)
+                result = result * 10 + digit
                 self.forward()
                 c = self.peekchr()
             return result
diff --git a/pypy/objspace/std/test/test_stringformat.py 
b/pypy/objspace/std/test/test_stringformat.py
--- a/pypy/objspace/std/test/test_stringformat.py
+++ b/pypy/objspace/std/test/test_stringformat.py
@@ -204,6 +204,17 @@
 
         assert "%x" % IntFails() == '0'
 
+    def test_formatting_huge_precision(self):
+        import sys
+        format_string = "%.{}f".format(sys.maxint + 1)
+        exc = raises(ValueError, "format_string % 2.34")
+        assert exc.value[0] == 'prec too big'
+
+    def test_formatting_huge_width(self):
+        import sys
+        format_string = "%{}f".format(sys.maxsize + 1)
+        exc = raises(ValueError, "format_string % 2.34")
+        assert exc.value[0] == 'width too big'
 
 class AppTestWidthPrec:
     def test_width(self):
@@ -324,3 +335,15 @@
     def test_invalid_char(self):
         f = 4
         raises(ValueError, 'u"%\u1234" % (f,)')
+
+    def test_formatting_huge_precision(self):
+        import sys
+        format_string = u"%.{}f".format(sys.maxint + 1)
+        exc = raises(ValueError, "format_string % 2.34")
+        assert exc.value[0] == 'prec too big'
+
+    def test_formatting_huge_width(self):
+        import sys
+        format_string = u"%{}f".format(sys.maxsize + 1)
+        exc = raises(ValueError, "format_string % 2.34")
+        assert exc.value[0] == 'width too big'
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to