Skip to content

Commit 2f084ec

Browse files
committed
Issue #18137: Detect integer overflow on precision in float.__format__() and
complex.__format__().
1 parent da30acf commit 2f084ec

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

Lib/test/test_format.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,23 @@ def test_locale(self):
312312
def test_main():
313313
support.run_unittest(FormatTest)
314314

315+
def test_precision(self):
316+
INT_MAX = 2147483647
317+
318+
f = 1.2
319+
self.assertEqual(format(f, ".0f"), "1")
320+
self.assertEqual(format(f, ".3f"), "1.200")
321+
with self.assertRaises(ValueError) as cm:
322+
format(f, ".%sf" % (INT_MAX + 1))
323+
self.assertEqual(str(cm.exception), "precision too big")
324+
325+
c = complex(f)
326+
self.assertEqual(format(f, ".0f"), "1")
327+
self.assertEqual(format(f, ".3f"), "1.200")
328+
with self.assertRaises(ValueError) as cm:
329+
format(f, ".%sf" % (INT_MAX + 1))
330+
self.assertEqual(str(cm.exception), "precision too big")
331+
315332

316333
if __name__ == "__main__":
317334
unittest.main()

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.3.3 release candidate 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #18137: Detect integer overflow on precision in float.__format__()
16+
and complex.__format__().
17+
1518
- Issue #18183: Fix various unicode operations on strings with large unicode
1619
codepoints.
1720

Python/formatter_unicode.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ format_float_internal(PyObject *value,
977977
Py_ssize_t n_total;
978978
int has_decimal;
979979
double val;
980-
Py_ssize_t precision = format->precision;
980+
Py_ssize_t precision;
981981
Py_ssize_t default_precision = 6;
982982
Py_UCS4 type = format->type;
983983
int add_pct = 0;
@@ -994,6 +994,12 @@ format_float_internal(PyObject *value,
994994
from a hard-code pseudo-locale */
995995
LocaleInfo locale = STATIC_LOCALE_INFO_INIT;
996996

997+
if (format->precision > INT_MAX) {
998+
PyErr_SetString(PyExc_ValueError, "precision too big");
999+
goto done;
1000+
}
1001+
precision = (int)format->precision;
1002+
9971003
if (format->alternate)
9981004
flags |= Py_DTSF_ALT;
9991005

@@ -1127,7 +1133,7 @@ format_complex_internal(PyObject *value,
11271133
Py_ssize_t n_im_total;
11281134
int re_has_decimal;
11291135
int im_has_decimal;
1130-
Py_ssize_t precision = format->precision;
1136+
int precision;
11311137
Py_ssize_t default_precision = 6;
11321138
Py_UCS4 type = format->type;
11331139
Py_ssize_t i_re;
@@ -1155,6 +1161,12 @@ format_complex_internal(PyObject *value,
11551161
from a hard-code pseudo-locale */
11561162
LocaleInfo locale = STATIC_LOCALE_INFO_INIT;
11571163

1164+
if (format->precision > INT_MAX) {
1165+
PyErr_SetString(PyExc_ValueError, "precision too big");
1166+
goto done;
1167+
}
1168+
precision = (int)format->precision;
1169+
11581170
/* Zero padding is not allowed. */
11591171
if (format->fill_char == '0') {
11601172
PyErr_SetString(PyExc_ValueError,

0 commit comments

Comments
 (0)