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

Log:    fix newformat overflow check

diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -1,12 +1,12 @@
 """The unicode/str format() method"""
 
+import sys
 import string
 
-from pypy.interpreter.error import OperationError
-from rpython.rlib import rstring, runicode, rlocale, rarithmetic, rfloat, jit
+from pypy.interpreter.error import OperationError, oefmt
+from rpython.rlib import rstring, runicode, rlocale, rfloat, jit
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rfloat import copysign, formatd
-from rpython.tool import sourcetools
 
 
 @specialize.argtype(1)
@@ -19,14 +19,12 @@
     result = 0
     i = start
     while i < end:
-        c = ord(s[i])
-        if ord("0") <= c <= ord("9"):
-            try:
-                result = rarithmetic.ovfcheck(result * 10)
-            except OverflowError:
-                msg = "too many decimal digits in format string"
-                raise OperationError(space.w_ValueError, space.wrap(msg))
-            result += c - ord("0")
+        digit = ord(s[i]) - ord('0')
+        if 0 <= digit <= 9:
+            if result > (sys.maxsize - digit) / 10:
+                raise oefmt(space.w_ValueError,
+                            "too many decimal digits in format string")
+            result = result * 10 + digit
         else:
             break
         i += 1
@@ -384,8 +382,8 @@
 class NumberSpec(object):
     pass
 
+
 class BaseFormatter(object):
-
     def format_int_or_long(self, w_num, kind):
         raise NotImplementedError
 
diff --git a/pypy/objspace/std/test/test_newformat.py 
b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -169,9 +169,23 @@
         raises(ValueError, '{0!r'.format, 5)
         raises(ValueError, '{0!rs}'.format, 5)
 
+    def test_format_huge_precision(self):
+        import sys
+        format_string = self.s(".{}f").format(sys.maxsize + 1)
+        raises(ValueError, "format(2.34, format_string)")
+
+    def test_format_huge_width(self):
+        import sys
+        format_string = self.s("{}f").format(sys.maxsize + 1)
+        raises(ValueError, "format(2.34, format_string)")
+
+    def test_format_huge_item_number(self):
+        import sys
+        format_string = self.s("{{{}:.6f}}").format(sys.maxsize + 1)
+        raises(ValueError, "format(2.34, format_string)")
+
 
 class AppTestUnicodeFormat(BaseStringFormatTests):
-
     def setup_class(cls):
         cls.w_s = cls.space.w_unicode
 
@@ -190,9 +204,7 @@
         raises(KeyError, self.s("{\u1000}").format)
 
 
-
 class AppTestStringFormat(BaseStringFormatTests):
-
     def setup_class(cls):
         cls.w_s = cls.space.w_str
 
@@ -209,7 +221,6 @@
 
 
 class AppTestBoolFormat:
-
     def test_str_format(self):
         assert format(False) == "False"
         assert format(True) == "True"
@@ -224,9 +235,7 @@
         assert "{:g}".format(True) == "1"
 
 
-
 class BaseIntegralFormattingTest:
-
     def test_simple(self):
         assert format(self.i(2)) == "2"
         assert isinstance(format(self.i(2), u""), unicode)
@@ -302,13 +311,11 @@
 
 
 class AppTestIntFormatting(BaseIntegralFormattingTest):
-
     def setup_class(cls):
         cls.w_i = cls.space.w_int
 
 
 class AppTestLongFormatting(BaseIntegralFormattingTest):
-
     def setup_class(cls):
         cls.w_i = cls.space.w_long
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to