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