diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -576,6 +576,12 @@ self.assertEqual(format(INF, 'f'), 'inf') self.assertEqual(format(INF, 'F'), 'INF') + # issue 17247 + self.assertRaises(ValueError, format, 1.2, "<06") + self.assertRaises(ValueError, format, 1.2, "=06") + self.assertRaises(ValueError, format, 1.2, "x<06") + self.assertRaises(ValueError, format, 1.2, "x=06") + @support.requires_IEEE_754 def test_format_testfile(self): with open(format_testfile) as testfile: diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -410,6 +410,13 @@ else: self.fail("Expected int(%r) to raise a ValueError", s) + def test_format(self): + # issue 17247 + self.assertRaises(ValueError, format, 1, "<06") + self.assertRaises(ValueError, format, 1, "=06") + self.assertRaises(ValueError, format, 1, "x<06") + self.assertRaises(ValueError, format, 1, "x=06") + def test_main(): support.run_unittest(IntTestCases) diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -194,11 +194,19 @@ } /* The special case for 0-padding (backwards compat) */ - if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') { + if (end-pos >= 1 && READ_spec(pos) == '0') { + if (format->fill_char != '\0') { + PyErr_Format(PyExc_ValueError, + "Fill character conflicts with '0' in format specifier"); + return 0; + } + if (align_specified) { + PyErr_Format(PyExc_ValueError, + "Alignment conflicts with '0' in format specifier"); + return 0; + } format->fill_char = '0'; - if (!align_specified) { - format->align = '='; - } + format->align = '='; ++pos; }