diff -r 98456ab88ab0 Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/datetimetester.py Sun Oct 16 01:59:19 2016 +0300 @@ -711,6 +711,14 @@ self.assertRaises(OverflowError, day.__truediv__, 1e-10) self.assertRaises(OverflowError, day.__truediv__, 9e-10) + # test overflow in timedelta constructor + self.assertRaises(OverflowError, timedelta, -1 << 1000) + self.assertRaises(OverflowError, timedelta, -999999999, 0, -1) + self.assertEqual(timedelta.min, timedelta(-999999999, 0, 0)) + self.assertRaises(OverflowError, timedelta, 1e9) + self.assertRaises(OverflowError, timedelta, 1 << 1000) + + @support.requires_IEEE_754 def _test_overflow_special(self): day = timedelta(1) diff -r 98456ab88ab0 Lib/test/string_tests.py --- a/Lib/test/string_tests.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/string_tests.py Sun Oct 16 01:59:19 2016 +0300 @@ -1140,6 +1140,23 @@ # but either raises a MemoryError, or succeeds (if you have 54TiB) #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) + @support.cpython_only + def test_mul_c_limits(self): + from _testcapi import PY_SSIZE_T_MAX, PY_SSIZE_T_MIN + + self.checkraises(OverflowError, '', '__mul__', -1 << 1000) + self.checkraises(OverflowError, '', '__mul__', PY_SSIZE_T_MIN - 1) + self.checkequal('', 'a', '__mul__', PY_SSIZE_T_MIN) + self.checkequal('', '', '__mul__', PY_SSIZE_T_MAX) + self.checkraises(OverflowError, '', '__mul__', PY_SSIZE_T_MAX + 1) + self.checkraises(OverflowError, '', '__mul__', 1 << 1000) + + # result's length can't be bigger than PY_SSIZE_T_MAX + self.checkraises(OverflowError, + 'ab', '__mul__', PY_SSIZE_T_MAX // 2 + 1) + self.checkraises(OverflowError, + 'ab' * 0x1000, '__mul__', PY_SSIZE_T_MAX) + def test_join(self): # join now works with any sequence type # moved here, because the argument order is @@ -1237,6 +1254,14 @@ (PY_SSIZE_T_MAX + 1, '')) self.checkraises(OverflowError, '%.*f', '__mod__', (INT_MAX + 1, 1. / 7)) + + self.checkraises(OverflowError, '%c', '__mod__', -1 << 1000) + self.checkraises(OverflowError, '%c', '__mod__', -1) + self.checkequal('c=\x00', 'c=%c', '__mod__', 0) + self.checkequal('c=\U0010ffff', 'c=%c', '__mod__', 0x10ffff) + self.checkraises(OverflowError, '%c', '__mod__', 0x110000) + self.checkraises(OverflowError, '%c', '__mod__', 1 << 1000) + # Issue 15989 self.checkraises(OverflowError, '%*s', '__mod__', (SIZE_MAX + 1, '')) diff -r 98456ab88ab0 Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_bytes.py Sun Oct 16 01:59:19 2016 +0300 @@ -16,7 +16,7 @@ import test.support import test.string_tests import test.list_tests -from test.support import bigaddrspacetest, MAX_Py_ssize_t +from test.support import bigaddrspacetest, MAX_Py_ssize_t, cpython_only if sys.flags.bytes_warning: @@ -91,6 +91,17 @@ self.assertEqual(self.type2test(b'0'), b'0') self.assertRaises(OverflowError, self.type2test, sys.maxsize + 1) + @cpython_only + def test_from_ssize_c_limits(self): + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + + self.assertRaises(OverflowError, self.type2test, -1 << 1000) + self.assertRaises(OverflowError, self.type2test, PY_SSIZE_T_MIN - 1) + self.assertRaises(ValueError, self.type2test, PY_SSIZE_T_MIN) + self.assertRaises(ValueError, self.type2test, -1) + self.assertRaises(OverflowError, self.type2test, PY_SSIZE_T_MAX + 1) + self.assertRaises(OverflowError, self.type2test, 1 << 1000) + def test_constructor_type_errors(self): self.assertRaises(TypeError, self.type2test, 0.0) class C: @@ -874,6 +885,16 @@ self.assertRaises(OverflowError, PyBytes_FromFormat, b'%c', c_int(256)) + self.assertRaises(OverflowError, b'%c'.__mod__, -1 << 1000) + self.assertRaises(OverflowError, b'%c'.__mod__, 1 << 1000) + + self.assertRaises(OverflowError, b'%c'.__mod__, Indexable(-1 << 1000)) + self.assertRaises(OverflowError, b'%c'.__mod__, Indexable(-1)) + self.assertEqual(b'c=%c' % Indexable(0), b'c=\0') + self.assertEqual(b'c=%c' % Indexable(255), b'c=\xff') + self.assertRaises(OverflowError, b'%c'.__mod__, Indexable(256)) + self.assertRaises(OverflowError, b'%c'.__mod__, Indexable(1 << 1000)) + def test_bytes_blocking(self): class IterationBlocked(list): __bytes__ = None diff -r 98456ab88ab0 Lib/test/test_csv.py --- a/Lib/test/test_csv.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_csv.py Sun Oct 16 01:59:19 2016 +0300 @@ -816,6 +816,23 @@ self.assertEqual(str(cm.exception), '"quotechar" must be string, not int') + @support.cpython_only + def test_quoting_c_limits(self): + from _testcapi import INT_MIN, INT_MAX + + for bad_val in [-1 << 1000, INT_MIN - 1, INT_MAX + 1, 1 << 1000]: + class value_error_quoting_dialect(csv.Dialect): + quoting = bad_val + self.assertRaises(ValueError, value_error_quoting_dialect) + # verify ValueError is not raised + for in_range_val in [INT_MIN, INT_MAX]: + class in_range_qouting_dialect(csv.Dialect): + quoting = in_range_val + try: + in_range_qouting_dialect() + except csv.Error: + pass + def test_delimiter(self): class mydialect(csv.Dialect): delimiter = ";" diff -r 98456ab88ab0 Lib/test/test_curses.py --- a/Lib/test/test_curses.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_curses.py Sun Oct 16 01:59:19 2016 +0300 @@ -15,7 +15,7 @@ import tempfile import unittest -from test.support import requires, import_module, verbose +from test.support import requires, import_module, verbose, cpython_only # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u @@ -193,6 +193,24 @@ self.assertRaises(ValueError, stdscr.instr, -2) self.assertRaises(ValueError, stdscr.instr, 2, 3, -2) + @cpython_only + def test_getstr_and_instr_c_limits(self): + from _testcapi import INT_MIN, INT_MAX + + for meth in [self.stdscr.getstr, self.stdscr.instr]: + self.assertRaises(OverflowError, meth, -1 << 1000) + self.assertRaises(OverflowError, meth, 1, 1, -1 << 1000) + self.assertRaises(OverflowError, meth, INT_MIN - 1) + self.assertRaises(OverflowError, meth, 1, 1, INT_MIN - 1) + self.assertRaises(ValueError, meth, INT_MIN) + self.assertRaises(ValueError, meth, 1, 1, INT_MIN) + self.assertRaises(ValueError, meth, -1) + self.assertRaises(ValueError, meth, 1, 1, -1) + self.assertRaises(OverflowError, meth, INT_MAX + 1) + self.assertRaises(OverflowError, meth, 1, 1, INT_MAX + 1) + self.assertRaises(OverflowError, meth, 1 << 1000) + self.assertRaises(OverflowError, meth, 1, 1, 1 << 1000) + def test_module_funcs(self): "Test module-level functions" @@ -258,6 +276,18 @@ def test_keyname(self): curses.keyname(13) + @cpython_only + @requires_curses_func('keyname') + def test_keyname_c_limits(self): + from _testcapi import INT_MIN, INT_MAX + + self.assertRaises(OverflowError, curses.keyname, -1 << 1000) + self.assertRaises(OverflowError, curses.keyname, INT_MIN - 1) + self.assertRaises(ValueError, curses.keyname, INT_MIN) + self.assertRaises(ValueError, curses.keyname, -1) + self.assertRaises(OverflowError, curses.keyname, INT_MAX + 1) + self.assertRaises(OverflowError, curses.keyname, 1 << 1000) + @requires_curses_func('has_key') def test_has_key(self): curses.has_key(13) diff -r 98456ab88ab0 Lib/test/test_getargs2.py --- a/Lib/test/test_getargs2.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_getargs2.py Sun Oct 16 01:59:19 2016 +0300 @@ -140,10 +140,12 @@ self.assertEqual(1, getargs_b(BadInt2())) self.assertEqual(0, getargs_b(BadInt3())) + self.assertRaises(OverflowError, getargs_b, -1 << 1000) self.assertRaises(OverflowError, getargs_b, -1) self.assertEqual(0, getargs_b(0)) self.assertEqual(UCHAR_MAX, getargs_b(UCHAR_MAX)) self.assertRaises(OverflowError, getargs_b, UCHAR_MAX + 1) + self.assertRaises(OverflowError, getargs_b, 1 << 1000) self.assertEqual(42, getargs_b(42)) self.assertRaises(OverflowError, getargs_b, VERY_LARGE) @@ -239,10 +241,12 @@ self.assertEqual(1, getargs_h(BadInt2())) self.assertEqual(0, getargs_h(BadInt3())) + self.assertRaises(OverflowError, getargs_h, -1 << 1000) self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1) self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN)) self.assertEqual(SHRT_MAX, getargs_h(SHRT_MAX)) self.assertRaises(OverflowError, getargs_h, SHRT_MAX+1) + self.assertRaises(OverflowError, getargs_h, 1 << 1000) self.assertEqual(42, getargs_h(42)) self.assertRaises(OverflowError, getargs_h, VERY_LARGE) @@ -258,10 +262,12 @@ self.assertEqual(1, getargs_i(BadInt2())) self.assertEqual(0, getargs_i(BadInt3())) + self.assertRaises(OverflowError, getargs_i, -1 << 1000) self.assertRaises(OverflowError, getargs_i, INT_MIN-1) self.assertEqual(INT_MIN, getargs_i(INT_MIN)) self.assertEqual(INT_MAX, getargs_i(INT_MAX)) self.assertRaises(OverflowError, getargs_i, INT_MAX+1) + self.assertRaises(OverflowError, getargs_i, 1 << 1000) self.assertEqual(42, getargs_i(42)) self.assertRaises(OverflowError, getargs_i, VERY_LARGE) diff -r 98456ab88ab0 Lib/test/test_hashlib.py --- a/Lib/test/test_hashlib.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_hashlib.py Sun Oct 16 01:59:19 2016 +0300 @@ -873,6 +873,29 @@ def test_pbkdf2_hmac_c(self): self._test_pbkdf2_hmac(c_hashlib.pbkdf2_hmac) + @unittest.skipUnless(hasattr(c_hashlib, 'pbkdf2_hmac'), + ' test requires OpenSSL > 1.0') + @support.cpython_only + def test_pbkdf2_hmac_c_limits(self): + from _testcapi import LONG_MIN, INT_MAX + # test iterations limits + self.assertRaises(OverflowError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', -1 << 1000) + self.assertRaises(OverflowError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', LONG_MIN - 1) + self.assertRaises(ValueError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', LONG_MIN) + self.assertRaises(OverflowError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', INT_MAX + 1) + self.assertRaises(OverflowError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', 1 << 1000) + # test dklen limits + self.assertRaises(ValueError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', 1, -1 << 1000) + self.assertRaises(OverflowError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', 1, INT_MAX + 1) + self.assertRaises(OverflowError, c_hashlib.pbkdf2_hmac, + 'sha1', b'pass', b'salt', 1, 1 << 1000) @unittest.skipUnless(hasattr(c_hashlib, 'scrypt'), ' test requires OpenSSL > 1.1') diff -r 98456ab88ab0 Lib/test/test_long.py --- a/Lib/test/test_long.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_long.py Sun Oct 16 01:59:19 2016 +0300 @@ -712,6 +712,15 @@ self.assertEqual(format(value, format_spec), format(float(value), format_spec)) + @support.cpython_only + def test__format__c_limits(self): + self.assertRaises(OverflowError, format, -1 << 1000, 'c') + self.assertRaises(OverflowError, format, -1, 'c') + self.assertEqual(format(0, 'c'), '\x00') + self.assertEqual(format(0x10ffff, 'c'), '\U0010ffff') + self.assertRaises(OverflowError, format, 0x110000, 'c') + self.assertRaises(OverflowError, format, 1 << 1000, 'c') + def test_nan_inf(self): self.assertRaises(OverflowError, int, float('inf')) self.assertRaises(OverflowError, int, float('-inf')) @@ -921,6 +930,26 @@ with self.assertRaises(OverflowError): 0 << (sys.maxsize + 1) + def test_negative_shift_count(self): + with self.assertRaises(ValueError): + 42 << -3 + with self.assertRaises(ValueError): + 42 >> -3 + + @support.cpython_only + def test_shift_c_limits(self): + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + + for zero_shifter in [(0).__lshift__, (0).__rshift__]: + self.assertRaises(OverflowError, zero_shifter, -1 << 1000) + self.assertRaises(OverflowError, zero_shifter, PY_SSIZE_T_MIN - 1) + self.assertRaises(ValueError, zero_shifter, PY_SSIZE_T_MIN) + self.assertRaises(ValueError, zero_shifter, -1) + self.assertEqual(zero_shifter(0), 0) + self.assertEqual(zero_shifter(PY_SSIZE_T_MAX), 0) + self.assertRaises(OverflowError, zero_shifter, PY_SSIZE_T_MAX + 1) + self.assertRaises(OverflowError, zero_shifter, 1 << 1000) + def test_small_ints(self): for i in range(-5, 257): self.assertIs(i, i + 0) diff -r 98456ab88ab0 Lib/test/test_lzma.py --- a/Lib/test/test_lzma.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_lzma.py Sun Oct 16 01:59:19 2016 +0300 @@ -7,7 +7,7 @@ import unittest from test.support import ( - _4G, TESTFN, import_module, bigmemtest, run_unittest, unlink + _4G, TESTFN, import_module, bigmemtest, run_unittest, unlink, cpython_only ) lzma = import_module("lzma") @@ -58,6 +58,19 @@ lzd.decompress(empty) self.assertRaises(EOFError, lzd.decompress, b"quux") + @cpython_only + def test_INT_TYPE_CONVERTER_FUNC_macro(self): + self.assertRaises(OverflowError, LZMACompressor, preset=-1 << 1000) + self.assertRaises(OverflowError, LZMACompressor, preset=-1) + self.assertRaises(OverflowError, LZMACompressor, preset=1 << 32) + self.assertRaises(OverflowError, LZMACompressor, preset=1 << 1000) + # verify OverflowError is not raised. + for in_range_preset in [0, (1 << 32) - 1]: + try: + LZMACompressor(preset=in_range_preset) + except LZMAError: + pass + def test_bad_filter_spec(self): self.assertRaises(TypeError, LZMACompressor, filters=[b"wobsite"]) self.assertRaises(ValueError, LZMACompressor, filters=[{"xyzzy": 3}]) diff -r 98456ab88ab0 Lib/test/test_memoryio.py --- a/Lib/test/test_memoryio.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_memoryio.py Sun Oct 16 01:59:19 2016 +0300 @@ -780,6 +780,21 @@ memio = self.ioclass(ba) self.assertEqual(sys.getrefcount(ba), old_rc) + @support.cpython_only + def test_truncate_c_limits(self): + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + memio = self.ioclass() + + self.assertRaises(OverflowError, memio.truncate, -1 << 1000) + self.assertRaises(OverflowError, memio.truncate, PY_SSIZE_T_MIN - 1) + self.assertRaises(ValueError, memio.truncate, PY_SSIZE_T_MIN) + self.assertRaises(ValueError, memio.truncate, -1) + # verify OverflowError/ValueError is not raised + memio.truncate(0) + memio.truncate(PY_SSIZE_T_MAX) + self.assertRaises(OverflowError, memio.truncate, PY_SSIZE_T_MAX + 1) + self.assertRaises(OverflowError, memio.truncate, 1 << 1000) + class CStringIOTest(PyStringIOTest): ioclass = io.StringIO UnsupportedOperation = io.UnsupportedOperation @@ -827,6 +842,21 @@ memio.close() self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None)) + @support.cpython_only + def test_truncate_c_limits(self): + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + memio = self.ioclass() + + self.assertRaises(OverflowError, memio.truncate, -1 << 1000) + self.assertRaises(OverflowError, memio.truncate, PY_SSIZE_T_MIN - 1) + self.assertRaises(ValueError, memio.truncate, PY_SSIZE_T_MIN) + self.assertRaises(ValueError, memio.truncate, -1) + # verify OverflowError/ValueError is not raised + memio.truncate(0) + memio.truncate(PY_SSIZE_T_MAX) + self.assertRaises(OverflowError, memio.truncate, PY_SSIZE_T_MAX + 1) + self.assertRaises(OverflowError, memio.truncate, 1 << 1000) + class CStringIOPickleTest(PyStringIOPickleTest): UnsupportedOperation = io.UnsupportedOperation diff -r 98456ab88ab0 Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_mmap.py Sun Oct 16 01:59:19 2016 +0300 @@ -417,6 +417,29 @@ m[x] = b self.assertEqual(m[x], b) + def test_bad_length(self): + self.assertRaises(OverflowError, mmap.mmap, -1, -1 << 1000) + self.assertRaises(OverflowError, mmap.mmap, -1, -1) + + @cpython_only + def test_constructor_c_limits(self): + from _testcapi import INT_MIN, INT_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + + # bad fileno + self.assertRaises(OverflowError, mmap.mmap, -1 << 1000, 16) + self.assertRaises(OverflowError, mmap.mmap, INT_MIN - 1, 16) + self.assertRaises(OverflowError, mmap.mmap, INT_MAX + 1, 16) + self.assertRaises(OverflowError, mmap.mmap, 1 << 1000, 16) + # bad length + self.assertRaises(OverflowError, mmap.mmap, -1, PY_SSIZE_T_MIN - 1) + self.assertRaises(OverflowError, mmap.mmap, -1, PY_SSIZE_T_MAX + 1) + self.assertRaises(OverflowError, mmap.mmap, -1, 1 << 1000) + # bad access + self.assertRaises(OverflowError, mmap.mmap, -1, 16, access=-1 << 1000) + self.assertRaises(OverflowError, mmap.mmap, -1, 16, access=INT_MIN - 1) + self.assertRaises(OverflowError, mmap.mmap, -1, 16, access=INT_MAX + 1) + self.assertRaises(OverflowError, mmap.mmap, -1, 16, access=1 << 1000) + def test_read_all(self): m = mmap.mmap(-1, 16) self.addCleanup(m.close) @@ -446,6 +469,20 @@ self.assertRaises(TypeError, m.read, 5.5) self.assertRaises(TypeError, m.read, [1, 2, 3]) + @cpython_only + def test_read_c_limits(self): + from _testcapi import PY_SSIZE_T_MAX, PY_SSIZE_T_MIN + m = mmap.mmap(-1, 16) + self.addCleanup(m.close) + + self.assertRaises(OverflowError, m.read, -1 << 1000) + self.assertRaises(OverflowError, m.read, PY_SSIZE_T_MIN - 1) + # verify OverflowError is not raised + m.read(PY_SSIZE_T_MIN) + m.read(PY_SSIZE_T_MAX) + self.assertRaises(OverflowError, m.read, PY_SSIZE_T_MAX + 1) + self.assertRaises(OverflowError, m.read, 1 << 1000) + def test_extended_getslice(self): # Test extended slicing by comparing with list slicing. s = bytes(reversed(range(256))) diff -r 98456ab88ab0 Lib/test/test_posix.py --- a/Lib/test/test_posix.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_posix.py Sun Oct 16 01:59:19 2016 +0300 @@ -1086,6 +1086,23 @@ param = posix.sched_param(sched_priority=-large) self.assertRaises(OverflowError, posix.sched_setparam, 0, param) + @support.cpython_only + def test_convert_sched_param_c_limits(self): + from _testcapi import INT_MIN, INT_MAX + orig_param = posix.sched_getparam(0) + self.addCleanup(posix.sched_setparam, 0, orig_param) + + for bad_val in [-1 << 1000, INT_MIN - 1, INT_MAX + 1, 1 << 1000]: + bad_param = posix.sched_param(bad_val) + self.assertRaises(OverflowError, + posix.sched_setparam, 0, bad_param) + # verify OverflowError is not raised + for in_range_int in [INT_MIN, INT_MAX]: + try: + posix.sched_setparam(0, posix.sched_param(in_range_int)) + except OSError: + pass + @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function") def test_sched_rr_get_interval(self): try: @@ -1121,10 +1138,28 @@ posix.sched_setaffinity(0, mask) self.assertEqual(posix.sched_getaffinity(0), mask) self.assertRaises(OSError, posix.sched_setaffinity, 0, []) - self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10]) + self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-1]) + self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-1 << 1000]) self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128]) self.assertRaises(OSError, posix.sched_setaffinity, -1, mask) + @support.cpython_only + @requires_sched_affinity + def test_sched_setaffinity_c_limits(self): + from _testcapi import INT_MAX + orig_mask = posix.sched_getaffinity(0) + self.addCleanup(posix.sched_setaffinity, 0, orig_mask) + + # verify OverflowError is not raised + try: + posix.sched_setaffinity(0, [INT_MAX - 1]) + except OSError: + pass + self.assertRaises(OverflowError, + posix.sched_setaffinity, 0, [INT_MAX]) + self.assertRaises(OverflowError, + posix.sched_setaffinity, 0, [1 << 1000]) + def test_rtld_constants(self): # check presence of major RTLD_* constants posix.RTLD_LAZY diff -r 98456ab88ab0 Lib/test/test_re.py --- a/Lib/test/test_re.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_re.py Sun Oct 16 01:59:19 2016 +0300 @@ -1508,6 +1508,27 @@ with self.assertRaises(TypeError): _sre.compile({}, 0, [], 0, [], []) + @cpython_only + def test_sre_compile_c_limits(self): + import _sre + # Currently SRE_CODE is an alias for Py_UCS4, which is an + # alias for uint32_t. + + with self.assertRaises(OverflowError): + _sre.compile("abc", 0, [-1 << 1000], 0, [], []) + with self.assertRaises(OverflowError): + _sre.compile("abc", 0, [-1], 0, [], []) + # verify OverflowError is not raised + for in_range_code in [0, (1 << 32) - 1]: + try: + _sre.compile("abc", 0, [in_range_code], 0, [], []) + except RuntimeError: + pass + with self.assertRaises(OverflowError): + _sre.compile("abc", 0, [1 << 32], 0, [], []) + with self.assertRaises(OverflowError): + _sre.compile("abc", 0, [1 << 1000], 0, [], []) + def test_search_dot_unicode(self): self.assertTrue(re.search("123.*-", '123abc-')) self.assertTrue(re.search("123.*-", '123\xe9-')) diff -r 98456ab88ab0 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_socket.py Sun Oct 16 01:59:19 2016 +0300 @@ -1215,6 +1215,21 @@ neg_port = port - 65536 self.assertRaises(OverflowError, sock.bind, (HOST, big_port)) self.assertRaises(OverflowError, sock.bind, (HOST, neg_port)) + + self.assertRaises(OverflowError, sock.bind, (HOST, -1 << 1000)) + self.assertRaises(OverflowError, sock.bind, (HOST, -1)) + # verify OverflowError is not raised + for in_range_port in [0, 0xffff]: + try: + sock.bind((HOST, in_range_port)) + except OSError: + pass + else: + sock = socket.socket() + self.addCleanup(sock.close) + self.assertRaises(OverflowError, sock.bind, (HOST, 1 << 16)) + self.assertRaises(OverflowError, sock.bind, (HOST, 1 << 1000)) + # Since find_unused_port() is inherently subject to race conditions, we # call it a couple times if necessary. for i in itertools.count(): @@ -1334,6 +1349,28 @@ # only IP addresses are allowed self.assertRaises(OSError, socket.getnameinfo, ('mail.python.org',0), 0) + # test port boundaries + self.assertRaises(OverflowError, + socket.getnameinfo, (HOST, -1 << 1000), 0) + self.assertRaises(OverflowError, + socket.getnameinfo, (HOST, -1), 0) + # verify OverflowError is not raised + socket.getnameinfo((HOST, 0), 0) + socket.getnameinfo((HOST, 0xffff), 0) + self.assertRaises(OverflowError, + socket.getnameinfo, (HOST, 1 << 16), 0) + self.assertRaises(OverflowError, + socket.getnameinfo, (HOST, 1 << 1000), 0) + + # test flowinfo boundaries + self.assertRaises(OverflowError, + socket.getnameinfo, (support.HOSTv6, 0, -1), 0) + # verify OverflowError is not raised + socket.getnameinfo((support.HOSTv6, 0, 0), 0) + socket.getnameinfo((support.HOSTv6, 0, (1 << 20) - 1), 0) + self.assertRaises(OverflowError, + socket.getnameinfo, (support.HOSTv6, 0, 1 << 20), 0) + @unittest.skipUnless(support.is_resource_enabled('network'), 'network is not enabled') def test_idna(self): diff -r 98456ab88ab0 Lib/test/test_stat.py --- a/Lib/test/test_stat.py Sat Oct 15 01:39:21 2016 +0000 +++ b/Lib/test/test_stat.py Sun Oct 16 01:59:19 2016 +0300 @@ -1,7 +1,7 @@ import unittest import os import sys -from test.support import TESTFN, import_fresh_module +from test.support import TESTFN, import_fresh_module, cpython_only c_stat = import_fresh_module('stat', fresh=['_stat']) py_stat = import_fresh_module('stat', blocked=['_stat']) @@ -222,6 +222,23 @@ format_funcs = TestFilemode.format_funcs | {'S_ISDOOR', 'S_ISPORT', 'S_ISWHT'} + @cpython_only + def test_mode_t_converter(self): + from _testcapi import USHRT_MAX + + self.assertRaises(TypeError, c_stat.S_IMODE, 1.0) + self.assertRaises(TypeError, c_stat.S_IMODE, '1') + + self.assertRaises(OverflowError, c_stat.S_IMODE, -1 << 1000) + self.assertRaises(OverflowError, c_stat.S_IMODE, -1) + c_stat.S_IMODE(0) # verify OverflowError is not raised + self.assertRaises(OverflowError, c_stat.S_IMODE, 1 << 1000) + + # test platform specific mode_t upper limit + if sys.platform == 'win32': + c_stat.S_IMODE(USHRT_MAX) # verify OverflowError is not raised + self.assertRaises(OverflowError, c_stat.S_IMODE, USHRT_MAX + 1) + class TestFilemodePyStat(TestFilemode, unittest.TestCase): statmod = py_stat diff -r 98456ab88ab0 Modules/_blake2/blake2b_impl.c --- a/Modules/_blake2/blake2b_impl.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_blake2/blake2b_impl.c Sun Oct 16 01:59:19 2016 +0300 @@ -159,6 +159,10 @@ if (leaf_size_obj != NULL) { leaf_size = PyLong_AsUnsignedLong(leaf_size_obj); if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "leaf_size does not fit in C unsigned long"); + } goto error; } if (leaf_size > 0xFFFFFFFFU) { diff -r 98456ab88ab0 Modules/_blake2/blake2s_impl.c --- a/Modules/_blake2/blake2s_impl.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_blake2/blake2s_impl.c Sun Oct 16 01:59:19 2016 +0300 @@ -159,6 +159,10 @@ if (leaf_size_obj != NULL) { leaf_size = PyLong_AsUnsignedLong(leaf_size_obj); if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "leaf_size does not fit in C unsigned long"); + } goto error; } if (leaf_size > 0xFFFFFFFFU) { diff -r 98456ab88ab0 Modules/_csv.c --- a/Modules/_csv.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_csv.c Sun Oct 16 01:59:19 2016 +0300 @@ -209,22 +209,21 @@ if (src == NULL) *target = dflt; else { - long value; + int value; if (!PyLong_CheckExact(src)) { PyErr_Format(PyExc_TypeError, "\"%s\" must be an integer", name); return -1; } - value = PyLong_AsLong(src); - if (value == -1 && PyErr_Occurred()) - return -1; -#if SIZEOF_LONG > SIZEOF_INT - if (value > INT_MAX || value < INT_MIN) { + value = _PyLong_AsInt(src); + if (value == -1 && PyErr_Occurred()) { + /* PyLong_Check(arg) is true, so it must be that + _PyLong_AsInt raised an OverflowError. */ + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Format(PyExc_ValueError, - "integer out of range for \"%s\"", name); + "\"%s\" value does not fit in C int", name); return -1; } -#endif *target = (int)value; } return 0; diff -r 98456ab88ab0 Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_ctypes/_ctypes.c Sun Oct 16 01:59:19 2016 +0300 @@ -1339,7 +1339,7 @@ length = PyLong_AsLongAndOverflow(length_attr, &overflow); if (overflow) { PyErr_SetString(PyExc_OverflowError, - "The '_length_' attribute is too large"); + "The '_length_' attribute does not fit in C long"); Py_DECREF(length_attr); goto error; } diff -r 98456ab88ab0 Modules/_ctypes/callproc.c --- a/Modules/_ctypes/callproc.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_ctypes/callproc.c Sun Oct 16 01:59:19 2016 +0300 @@ -650,7 +650,8 @@ pa->value.i = PyLong_AsLong(obj); if (pa->value.i == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_OverflowError, - "int too long to convert"); + "Python int fits neither C unsigned long nor " + "C long"); return -1; } } diff -r 98456ab88ab0 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_cursesmodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -245,6 +245,8 @@ else if (PyLong_CheckExact(obj)) { int long_overflow; value = PyLong_AsLongAndOverflow(obj, &long_overflow); + /* PyLong_Check(obj) is true, so it is guaranteed that + no error occurred in PyLong_AsLongAndOverflow. */ if (long_overflow) goto overflow; } @@ -261,7 +263,7 @@ overflow: PyErr_SetString(PyExc_OverflowError, - "byte doesn't fit in chtype"); + "Python object does not fit in C chtype"); return 0; } @@ -311,9 +313,11 @@ else if (PyLong_CheckExact(obj)) { int overflow; value = PyLong_AsLongAndOverflow(obj, &overflow); + /* PyLong_Check(obj) is true, so it is guaranteed that + no error occurred in PyLong_AsLongAndOverflow. */ if (overflow) { PyErr_SetString(PyExc_OverflowError, - "int doesn't fit in long"); + "Python int does not fit in C chtype"); return 0; } } @@ -327,7 +331,7 @@ *ch = (chtype)value; if ((long)*ch != value) { PyErr_Format(PyExc_OverflowError, - "byte doesn't fit in chtype"); + "Python object does not fit in C chtype"); return 0; } return 1; @@ -1219,10 +1223,12 @@ Py_END_ALLOW_THREADS break; case 1: - if (!PyArg_ParseTuple(args,"i;n", &n)) + if (!PyArg_ParseTuple(args, "i:getstr", &n)) { return NULL; + } if (n < 0) { - PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); + PyErr_SetString(PyExc_ValueError, + "getstr: 'n' must be nonnegative"); return NULL; } Py_BEGIN_ALLOW_THREADS @@ -1230,8 +1236,9 @@ Py_END_ALLOW_THREADS break; case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) + if (!PyArg_ParseTuple(args, "ii:getstr", &y, &x)) { return NULL; + } Py_BEGIN_ALLOW_THREADS #ifdef STRICT_SYSV_CURSES rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023); @@ -1241,10 +1248,12 @@ Py_END_ALLOW_THREADS break; case 3: - if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n)) + if (!PyArg_ParseTuple(args, "iii:getstr", &y, &x, &n)) { return NULL; + } if (n < 0) { - PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); + PyErr_SetString(PyExc_ValueError, + "getstr: 'n' must be nonnegative"); return NULL; } #ifdef STRICT_SYSV_CURSES @@ -1391,24 +1400,29 @@ rtn2 = winnstr(self->win,rtn, 1023); break; case 1: - if (!PyArg_ParseTuple(args,"i;n", &n)) + if (!PyArg_ParseTuple(args, "i:instr", &n)) { return NULL; + } if (n < 0) { - PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); + PyErr_SetString(PyExc_ValueError, + "instr: 'n' must be nonnegative"); return NULL; } rtn2 = winnstr(self->win, rtn, Py_MIN(n, 1023)); break; case 2: - if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) + if (!PyArg_ParseTuple(args, "ii:instr", &y, &x)) { return NULL; + } rtn2 = mvwinnstr(self->win,y,x,rtn,1023); break; case 3: - if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n)) + if (!PyArg_ParseTuple(args, "iii:instr", &y, &x, &n)) { return NULL; + } if (n < 0) { - PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative"); + PyErr_SetString(PyExc_ValueError, + "instr: 'n' must be nonnegative"); return NULL; } rtn2 = mvwinnstr(self->win, y, x, rtn, Py_MIN(n,1023)); @@ -2620,10 +2634,13 @@ PyCursesInitialised; - if (!PyArg_ParseTuple(args,"i",&ch)) return NULL; + if (!PyArg_ParseTuple(args, "i:keyname" ,&ch)) { + return NULL; + } if (ch < 0) { - PyErr_SetString(PyExc_ValueError, "invalid key number"); + PyErr_SetString(PyExc_ValueError, + "keyname: key number must be nonnegative"); return NULL; } knp = keyname(ch); @@ -3126,15 +3143,17 @@ long value; int overflow; value = PyLong_AsLongAndOverflow(obj, &overflow); + /* PyLong_Check(obj) is true, so it is guaranteed that + no error occurred in PyLong_AsLongAndOverflow. */ if (overflow) { PyErr_SetString(PyExc_OverflowError, - "int doesn't fit in long"); + "Python int does not fit in C wchar_t"); return 0; } *wch = (wchar_t)value; if ((long)*wch != value) { PyErr_Format(PyExc_OverflowError, - "character doesn't fit in wchar_t"); + "Python int does not fit in C wchar_t"); return 0; } return 1; diff -r 98456ab88ab0 Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_datetimemodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -1583,13 +1583,10 @@ if (num == NULL) goto Done; Py_INCREF(num); - temp = PyLong_AsLong(num); - if (temp == -1 && PyErr_Occurred()) - goto Done; - d = (int)temp; - if ((long)d != temp) { - PyErr_SetString(PyExc_OverflowError, "normalized days too " - "large to fit in a C int"); + d = _PyLong_AsInt(num); + if (d == -1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_OverflowError, + "normalized days does not fit in C int"); goto Done; } result = new_delta_ex(d, s, us, 0, type); @@ -2151,7 +2148,7 @@ "minutes", "hours", "weeks", NULL }; - if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:__new__", + if (PyArg_ParseTupleAndKeywords(args, kw, "|OOOOOOO:timedelta.__new__", keywords, &day, &second, &us, &ms, &minute, &hour, &week) == 0) @@ -2498,7 +2495,7 @@ return (PyObject *)me; } - if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, + if (PyArg_ParseTupleAndKeywords(args, kw, "iii:date.__new__", date_kws, &year, &month, &day)) { if (check_date_args(year, month, day) < 0) return NULL; @@ -3583,7 +3580,8 @@ return (PyObject *)me; } - if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws, + if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i:time.__new__", + time_kws, &hour, &minute, &second, &usecond, &tzinfo, &fold)) { if (check_time_args(hour, minute, second, usecond, fold) < 0) @@ -4164,7 +4162,8 @@ return (PyObject *)me; } - if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, + if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i:datetime.__new__", + datetime_kws, &year, &month, &day, &hour, &minute, &second, &usecond, &tzinfo, &fold)) { if (check_date_args(year, month, day) < 0) diff -r 98456ab88ab0 Modules/_hashopenssl.c --- a/Modules/_hashopenssl.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_hashopenssl.c Sun Oct 16 01:59:19 2016 +0300 @@ -629,6 +629,7 @@ long iterations, dklen; int retval; const EVP_MD *digest; + int overflow = 0; if (!PyArg_ParseTupleAndKeywords(args, kwdict, "sy*y*l|O:pbkdf2_hmac", kwlist, &name, &password, &salt, @@ -668,22 +669,22 @@ if (dklen_obj == Py_None) { dklen = EVP_MD_size(digest); } else { - dklen = PyLong_AsLong(dklen_obj); - if ((dklen == -1) && PyErr_Occurred()) { + dklen = PyLong_AsLongAndOverflow(dklen_obj, &overflow); + if (dklen == -1 && PyErr_Occurred()) { goto end; } } - if (dklen < 1) { + if (overflow == 1 || dklen > INT_MAX) { + /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */ + PyErr_SetString(PyExc_OverflowError, + "key length is too large."); + goto end; + } + if (overflow == -1 || dklen < 1) { PyErr_SetString(PyExc_ValueError, "key length must be greater than 0."); goto end; } - if (dklen > INT_MAX) { - /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */ - PyErr_SetString(PyExc_OverflowError, - "key length is too great."); - goto end; - } key_obj = PyBytes_FromStringAndSize(NULL, dklen); if (key_obj == NULL) { diff -r 98456ab88ab0 Modules/_io/bytesio.c --- a/Modules/_io/bytesio.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_io/bytesio.c Sun Oct 16 01:59:19 2016 +0300 @@ -599,22 +599,30 @@ if (PyLong_Check(arg)) { size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) + if (size == -1 && PyErr_Occurred()) { + /* PyLong_Check(arg) is true, so it must be that + PyLong_AsSsize_t raised an OverflowError. */ + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "truncate: size value does not fit in C " + "Py_ssize_t"); return NULL; + } } else if (arg == Py_None) { /* Truncate to current position if no argument is passed. */ size = self->pos; } else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", + PyErr_Format(PyExc_TypeError, + "truncate: integer argument expected, got '%s'", Py_TYPE(arg)->tp_name); return NULL; } if (size < 0) { PyErr_Format(PyExc_ValueError, - "negative size value %zd", size); + "truncate: negative size value %zd", size); return NULL; } diff -r 98456ab88ab0 Modules/_io/stringio.c --- a/Modules/_io/stringio.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_io/stringio.c Sun Oct 16 01:59:19 2016 +0300 @@ -480,22 +480,29 @@ if (PyNumber_Check(arg)) { size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) + if (size == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "truncate: size value does not fit in C " + "Py_ssize_t"); + } return NULL; + } } else if (arg == Py_None) { /* Truncate to current position if no argument is passed. */ size = self->pos; } else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", + PyErr_Format(PyExc_TypeError, + "truncate: integer argument expected, got '%s'", Py_TYPE(arg)->tp_name); return NULL; } if (size < 0) { PyErr_Format(PyExc_ValueError, - "Negative size value %zd", size); + "truncate: negative size value %zd", size); return NULL; } diff -r 98456ab88ab0 Modules/_lzmamodule.c --- a/Modules/_lzmamodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_lzmamodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -166,22 +166,28 @@ to be strictly correct, we need to define two separate converters. */ -#define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \ - static int \ - FUNCNAME(PyObject *obj, void *ptr) \ - { \ - unsigned long long val; \ - \ - val = PyLong_AsUnsignedLongLong(obj); \ - if (PyErr_Occurred()) \ - return 0; \ - if ((unsigned long long)(TYPE)val != val) { \ - PyErr_SetString(PyExc_OverflowError, \ - "Value too large for " #TYPE " type"); \ - return 0; \ - } \ - *(TYPE *)ptr = (TYPE)val; \ - return 1; \ +#define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \ + static int \ + FUNCNAME(PyObject *obj, void *ptr) \ + { \ + unsigned long long val; \ + \ + val = PyLong_AsUnsignedLongLong(obj); \ + if (val == (unsigned long long)-1 && PyErr_Occurred()) { \ + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) { \ + return 0; \ + } \ + } \ + else if ((unsigned long long)(TYPE)val == val) { \ + *(TYPE *)ptr = (TYPE)val; \ + return 1; \ + } \ + \ + /* Either PyExc_OverflowError occurred in \ + PyLong_AsUnsignedLongLong, or val didn't fit in TYPE. */ \ + PyErr_SetString(PyExc_OverflowError, \ + "Python int does not fit in C " #TYPE); \ + return 0; \ } INT_TYPE_CONVERTER_FUNC(uint32_t, uint32_converter) diff -r 98456ab88ab0 Modules/_pickle.c --- a/Modules/_pickle.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_pickle.c Sun Oct 16 01:59:19 2016 +0300 @@ -1817,9 +1817,12 @@ const char long_op = LONG; + assert(PyLong_CheckExact(obj)); val= PyLong_AsLong(obj); if (val == -1 && PyErr_Occurred()) { - /* out of range for int pickling */ + /* PyLong_Check(obj) is true, so it must be that + PyLong_AsLong raised an OverflowError, i.e. obj is out + of range for int pickling */ PyErr_Clear(); } else if (self->bin && @@ -1880,8 +1883,12 @@ return 0; } nbits = _PyLong_NumBits(obj); - if (nbits == (size_t)-1 && PyErr_Occurred()) + if (nbits == (size_t)-1 && PyErr_Occurred()) { + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "Python int too large to pickle"); goto error; + } /* How many bytes do we need? There are nbits >> 3 full * bytes of data, and nbits & 7 leftover bits. If there * are any leftover bits, then we clearly need another @@ -1899,7 +1906,7 @@ nbytes = (nbits >> 3) + 1; if (nbytes > 0x7fffffffL) { PyErr_SetString(PyExc_OverflowError, - "int too large to pickle"); + "Python int too large to pickle"); goto error; } repr = PyBytes_FromStringAndSize(NULL, (Py_ssize_t)nbytes); diff -r 98456ab88ab0 Modules/_sqlite/util.c --- a/Modules/_sqlite/util.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_sqlite/util.c Sun Oct 16 01:59:19 2016 +0300 @@ -148,6 +148,6 @@ } } PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to SQLite INTEGER"); + "Python int does not fit in C sqlite_int64"); return -1; } diff -r 98456ab88ab0 Modules/_sre.c --- a/Modules/_sre.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_sre.c Sun Oct 16 01:59:19 2016 +0300 @@ -1472,12 +1472,16 @@ self->code[i] = (SRE_CODE) value; if ((unsigned long) self->code[i] != value) { PyErr_SetString(PyExc_OverflowError, - "regular expression code size limit exceeded"); + "regular expression code out of range"); break; } } if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "regular expression code out of range"); + } Py_DECREF(self); return NULL; } diff -r 98456ab88ab0 Modules/_stat.c --- a/Modules/_stat.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/_stat.c Sun Oct 16 01:59:19 2016 +0300 @@ -251,12 +251,18 @@ mode_t mode; value = PyLong_AsUnsignedLong(op); - if ((value == (unsigned long)-1) && PyErr_Occurred()) + if ((value == (unsigned long)-1) && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "Python int does not fit in C mode_t"); + } return (mode_t)-1; + } mode = (mode_t)value; if ((unsigned long)mode != value) { - PyErr_SetString(PyExc_OverflowError, "mode out of range"); + PyErr_SetString(PyExc_OverflowError, + "Python int does not fit in C mode_t"); return (mode_t)-1; } return mode; @@ -267,7 +273,7 @@ static PyObject * \ stat_ ##isfunc (PyObject *self, PyObject *omode) \ { \ - mode_t mode = _PyLong_AsMode_t(omode); \ + mode_t mode = _PyLong_AsMode_t(omode); \ if ((mode == (mode_t)-1) && PyErr_Occurred()) \ return NULL; \ return PyBool_FromLong(isfunc(mode)); \ diff -r 98456ab88ab0 Modules/arraymodule.c --- a/Modules/arraymodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/arraymodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -197,20 +197,24 @@ /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore must use the next size up that is signed ('h') and manually do the overflow checking */ - if (!PyArg_Parse(v, "h;array item must be integer", &x)) + if (!PyArg_Parse(v, "h:array('b').__setitem__", &x)) { return -1; + } else if (x < -128) { PyErr_SetString(PyExc_OverflowError, - "signed char is less than minimum"); + "array('b').__setitem__() value argument too small " + "to convert to C char"); return -1; } else if (x > 127) { PyErr_SetString(PyExc_OverflowError, - "signed char is greater than maximum"); + "array('b').__setitem__() value argument too large " + "to convert to C char"); return -1; } - if (i >= 0) + if (i >= 0) { ((char *)ap->ob_item)[i] = (char)x; + } return 0; } @@ -226,10 +230,12 @@ { unsigned char x; /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */ - if (!PyArg_Parse(v, "b;array item must be integer", &x)) + if (!PyArg_Parse(v, "b:array('B').__setitem__", &x)) { return -1; - if (i >= 0) + } + if (i >= 0) { ((char *)ap->ob_item)[i] = x; + } return 0; } @@ -270,10 +276,12 @@ { short x; /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */ - if (!PyArg_Parse(v, "h;array item must be integer", &x)) + if (!PyArg_Parse(v, "h:array('h').__setitem__", &x)) { return -1; - if (i >= 0) - ((short *)ap->ob_item)[i] = x; + } + if (i >= 0) { + ((short *)ap->ob_item)[i] = x; + } return 0; } @@ -289,20 +297,24 @@ int x; /* PyArg_Parse's 'h' formatter is for a signed short, therefore must use the next size up and manually do the overflow checking */ - if (!PyArg_Parse(v, "i;array item must be integer", &x)) + if (!PyArg_Parse(v, "i:array('H').__setitem__", &x)) { return -1; + } else if (x < 0) { PyErr_SetString(PyExc_OverflowError, - "unsigned short is less than minimum"); + "array('H').__setitem__() value argument can't be " + "negative"); return -1; } else if (x > USHRT_MAX) { PyErr_SetString(PyExc_OverflowError, - "unsigned short is greater than maximum"); + "array('H').__setitem__() value argument too large " + "to convert to C unsigned short"); return -1; } - if (i >= 0) + if (i >= 0) { ((short *)ap->ob_item)[i] = (short)x; + } return 0; } @@ -317,10 +329,12 @@ { int x; /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */ - if (!PyArg_Parse(v, "i;array item must be integer", &x)) + if (!PyArg_Parse(v, "i:array('i').__setitem__", &x)) { return -1; - if (i >= 0) - ((int *)ap->ob_item)[i] = x; + } + if (i >= 0) { + ((int *)ap->ob_item)[i] = x; + } return 0; } @@ -337,16 +351,23 @@ unsigned long x; if (PyLong_Check(v)) { x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long) -1 && PyErr_Occurred()) + if (x == (unsigned long) -1 && PyErr_Occurred()) { + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "array('I').__setitem__() value argument does " + "not fit in C unsigned int"); return -1; + } } else { long y; - if (!PyArg_Parse(v, "l;array item must be integer", &y)) + if (!PyArg_Parse(v, "l:array('I').__setitem__", &y)) { return -1; + } if (y < 0) { PyErr_SetString(PyExc_OverflowError, - "unsigned int is less than minimum"); + "array('I').__setitem__() value argument can't " + "be negative"); return -1; } x = (unsigned long)y; @@ -354,12 +375,14 @@ } if (x > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, - "unsigned int is greater than maximum"); + "array('I').__setitem__() value argument too large " + "to convert to C unsigned int"); return -1; } - if (i >= 0) + if (i >= 0) { ((unsigned int *)ap->ob_item)[i] = (unsigned int)x; + } return 0; } @@ -373,10 +396,12 @@ l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { long x; - if (!PyArg_Parse(v, "l;array item must be integer", &x)) + if (!PyArg_Parse(v, "l:array('l').__setitem__", &x)) { return -1; - if (i >= 0) - ((long *)ap->ob_item)[i] = x; + } + if (i >= 0) { + ((long *)ap->ob_item)[i] = x; + } return 0; } @@ -392,29 +417,32 @@ unsigned long x; if (PyLong_Check(v)) { x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long) -1 && PyErr_Occurred()) + if (x == (unsigned long) -1 && PyErr_Occurred()) { + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "array('L').__setitem__() value argument does " + "not fit in C unsigned long"); return -1; + } } else { long y; - if (!PyArg_Parse(v, "l;array item must be integer", &y)) + if (!PyArg_Parse(v, "l:array('L').__setitem__", &y)) { return -1; + } if (y < 0) { PyErr_SetString(PyExc_OverflowError, - "unsigned long is less than minimum"); + "array('L').__setitem__() value argument can't " + "be negative"); return -1; } x = (unsigned long)y; } - if (x > ULONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "unsigned long is greater than maximum"); - return -1; + + if (i >= 0) { + ((unsigned long *)ap->ob_item)[i] = x; } - - if (i >= 0) - ((unsigned long *)ap->ob_item)[i] = x; return 0; } @@ -428,10 +456,12 @@ q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { long long x; - if (!PyArg_Parse(v, "L;array item must be integer", &x)) + if (!PyArg_Parse(v, "L:array('q').__setitem__", &x)) { return -1; - if (i >= 0) + } + if (i >= 0) { ((long long *)ap->ob_item)[i] = x; + } return 0; } @@ -448,23 +478,31 @@ unsigned long long x; if (PyLong_Check(v)) { x = PyLong_AsUnsignedLongLong(v); - if (x == (unsigned long long) -1 && PyErr_Occurred()) + if (x == (unsigned long long) -1 && PyErr_Occurred()) { + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "array('Q').__setitem__() value argument does " + "not fit in C unsigned long long"); return -1; + } } else { long long y; - if (!PyArg_Parse(v, "L;array item must be integer", &y)) + if (!PyArg_Parse(v, "L:array('Q').__setitem__", &y)) { return -1; + } if (y < 0) { PyErr_SetString(PyExc_OverflowError, - "unsigned long long is less than minimum"); + "array('Q').__setitem__() value argument can't " + "be negative"); return -1; } x = (unsigned long long)y; } - if (i >= 0) + if (i >= 0) { ((unsigned long long *)ap->ob_item)[i] = x; + } return 0; } diff -r 98456ab88ab0 Modules/mmapmodule.c --- a/Modules/mmapmodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/mmapmodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -271,8 +271,15 @@ PyObject *result; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "|O&:read", mmap_convert_ssize_t, &num_bytes)) + if (!PyArg_ParseTuple(args, "|O&:read", + mmap_convert_ssize_t, &num_bytes)) { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "read count does not fit in C Py_ssize_t"); + } return(NULL); + } /* silently 'adjust' out-of-range requests */ remaining = (self->pos < self->size) ? self->size - self->pos : 0; @@ -1089,18 +1096,20 @@ "flags", "prot", "access", "offset", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|iii" _Py_PARSE_OFF_T, keywords, - &fd, &map_size, &flags, &prot, - &access, &offset)) + if (!PyArg_ParseTupleAndKeywords(args, kwdict, + "in|iii" _Py_PARSE_OFF_T ":mmap", + keywords, &fd, &map_size, &flags, &prot, + &access, &offset)) { return NULL; + } if (map_size < 0) { PyErr_SetString(PyExc_OverflowError, - "memory mapped length must be postiive"); + "memory mapped length must be positive"); return NULL; } if (offset < 0) { PyErr_SetString(PyExc_OverflowError, - "memory mapped offset must be positive"); + "memory mapped offset must be positive"); return NULL; } @@ -1249,7 +1258,7 @@ "tagname", "access", "offset", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|ziL", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|ziL:mmap", keywords, &fileno, &map_size, &tagname, &access, &offset)) { return NULL; @@ -1275,12 +1284,12 @@ if (map_size < 0) { PyErr_SetString(PyExc_OverflowError, - "memory mapped length must be postiive"); + "memory mapped length must be positive"); return NULL; } if (offset < 0) { PyErr_SetString(PyExc_OverflowError, - "memory mapped offset must be positive"); + "memory mapped offset must be positive"); return NULL; } diff -r 98456ab88ab0 Modules/posixmodule.c --- a/Modules/posixmodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/posixmodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -5371,20 +5371,21 @@ static int convert_sched_param(PyObject *param, struct sched_param *res) { - long priority; + int priority; if (Py_TYPE(param) != &SchedParamType) { PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); return 0; } - priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0)); - if (priority == -1 && PyErr_Occurred()) + priority = _PyLong_AsInt(PyStructSequence_GET_ITEM(param, 0)); + if (priority == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "sched_priority value does not fit in C int"); + } return 0; - if (priority > INT_MAX || priority < INT_MIN) { - PyErr_SetString(PyExc_OverflowError, "sched_priority out of range"); - return 0; - } - res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); + } + res->sched_priority = priority; return 1; } #endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */ @@ -5540,7 +5541,7 @@ os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask) /*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/ { - int ncpus; + int ncpus, overflow; size_t setsize; cpu_set_t *cpu_set = NULL; PyObject *iterator = NULL, *item; @@ -5568,15 +5569,17 @@ Py_DECREF(item); goto error; } - cpu = PyLong_AsLong(item); + cpu = PyLong_AsLongAndOverflow(item, &overflow); + /* PyLong_Check(item) is true, so it is guaranteed that + no error occurred in PyLong_AsLongAndOverflow. */ + assert(!(cpu == -1 && PyErr_Occurred())); Py_DECREF(item); - if (cpu < 0) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, "negative CPU number"); + if (overflow == 1 || cpu > INT_MAX - 1) { + PyErr_SetString(PyExc_OverflowError, "CPU number too large"); goto error; } - if (cpu > INT_MAX - 1) { - PyErr_SetString(PyExc_OverflowError, "CPU number too large"); + if (overflow == -1 || cpu < 0) { + PyErr_SetString(PyExc_ValueError, "negative CPU number"); goto error; } if (cpu >= ncpus) { diff -r 98456ab88ab0 Modules/selectmodule.c --- a/Modules/selectmodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/selectmodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -384,7 +384,7 @@ return 0; if (uval > USHRT_MAX) { PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned short"); + "Python int too large to convert to C unsigned short"); return 0; } @@ -407,8 +407,16 @@ unsigned short events = POLLIN | POLLPRI | POLLOUT; int err; - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) + if (!PyArg_ParseTuple(args, "O|O&:register", + &o, ushort_converter, &events)) { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "register: eventmask value does not fit in C " + "unsigned short"); + } return NULL; + } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -450,8 +458,16 @@ unsigned short events; int err; - if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events)) + if (!PyArg_ParseTuple(args, "OO&:modify", + &o, ushort_converter, &events)) { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "modify: eventmask value does not fit in C " + "unsigned short"); + } return NULL; + } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -790,8 +806,16 @@ if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) + if (!PyArg_ParseTuple(args, "O|O&:register/modify", + &o, ushort_converter, &events)) { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "register/modify: eventmask value does not fit " + "in C unsigned short"); + } return NULL; + } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; diff -r 98456ab88ab0 Modules/socketmodule.c --- a/Modules/socketmodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/socketmodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -1657,7 +1657,7 @@ Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "O&i|II", + if (!PyArg_ParseTuple(args, "O&i|II:getsockaddrarg", idna_converter, &host, &port, &flowinfo, &scope_id)) { return 0; @@ -1804,10 +1804,11 @@ Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "si|iiy*", &interfaceName, + if (!PyArg_ParseTuple(args, "si|iiy*:getsockaddrarg", &interfaceName, &protoNumber, &pkttype, &hatype, - &haddr)) + &haddr)) { return 0; + } strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)); ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { @@ -5539,8 +5540,13 @@ if (PyLong_Check(arg)) { x = PyLong_AsUnsignedLong(arg); - if (x == (unsigned long) -1 && PyErr_Occurred()) + if (x == (unsigned long) -1 && PyErr_Occurred()) { + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "ntohl: Python int does not fit in C 32-bit " + "unsigned integer"); return NULL; + } #if SIZEOF_LONG > 4 { unsigned long y; @@ -5548,7 +5554,8 @@ y = x & 0xFFFFFFFFUL; if (y ^ x) return PyErr_Format(PyExc_OverflowError, - "int larger than 32 bits"); + "ntohl: Python int too large to convert " + "to C 32-bit unsigned integer"); x = y; } #endif @@ -5610,8 +5617,13 @@ if (PyLong_Check(arg)) { x = PyLong_AsUnsignedLong(arg); - if (x == (unsigned long) -1 && PyErr_Occurred()) + if (x == (unsigned long) -1 && PyErr_Occurred()) { + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "htonl: Python int does not fit in C 32-bit " + "unsigned integer"); return NULL; + } #if SIZEOF_LONG > 4 { unsigned long y; @@ -5619,7 +5631,8 @@ y = x & 0xFFFFFFFFUL; if (y ^ x) return PyErr_Format(PyExc_OverflowError, - "int larger than 32 bits"); + "htonl: Python int too large to convert " + "to C 32-bit unsigned integer"); x = y; } #endif @@ -5628,7 +5641,7 @@ return PyErr_Format(PyExc_TypeError, "expected int, %s found", Py_TYPE(arg)->tp_name); - return PyLong_FromUnsignedLong(htonl((unsigned long)x)); + return PyLong_FromUnsignedLong(htonl(x)); } PyDoc_STRVAR(htonl_doc, @@ -6107,12 +6120,18 @@ "getnameinfo() argument 1 must be a tuple"); return NULL; } - if (!PyArg_ParseTuple(sa, "si|II", - &hostp, &port, &flowinfo, &scope_id)) + if (!PyArg_ParseTuple(sa, "si|II:getnameinfo", + &hostp, &port, &flowinfo, &scope_id)) { return NULL; + } + if (port < 0 || port > 0xffff) { + PyErr_SetString(PyExc_OverflowError, + "getnameinfo: port must be 0-65535."); + return NULL; + } if (flowinfo > 0xfffff) { PyErr_SetString(PyExc_OverflowError, - "getsockaddrarg: flowinfo must be 0-1048575."); + "getnameinfo: flowinfo must be 0-1048575."); return NULL; } PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port); diff -r 98456ab88ab0 Modules/timemodule.c --- a/Modules/timemodule.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Modules/timemodule.c Sun Oct 16 01:59:19 2016 +0300 @@ -428,11 +428,12 @@ return 0; } - if (!PyArg_ParseTuple(args, "iiiiiiiii", + if (!PyArg_ParseTuple(args, "iiiiiiiii:mktime/asctime/strftime", &y, &p->tm_mon, &p->tm_mday, &p->tm_hour, &p->tm_min, &p->tm_sec, - &p->tm_wday, &p->tm_yday, &p->tm_isdst)) + &p->tm_wday, &p->tm_yday, &p->tm_isdst)) { return 0; + } p->tm_year = y - 1900; p->tm_mon--; p->tm_wday = (p->tm_wday + 1) % 7; diff -r 98456ab88ab0 Objects/abstract.c --- a/Objects/abstract.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Objects/abstract.c Sun Oct 16 01:59:19 2016 +0300 @@ -930,8 +930,14 @@ Py_ssize_t count; if (PyIndex_Check(n)) { count = PyNumber_AsSsize_t(n, PyExc_OverflowError); - if (count == -1 && PyErr_Occurred()) + if (count == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "sequence repeat count does not fit in C " + "Py_ssize_t"); + } return NULL; + } } else { return type_error("can't multiply sequence by " diff -r 98456ab88ab0 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Objects/bytearrayobject.c Sun Oct 16 01:59:19 2016 +0300 @@ -798,10 +798,15 @@ if (PyIndex_Check(arg)) { count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (count == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "bytearray: count does not fit in C " + "Py_ssize_t"); + } return -1; } if (count < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); + PyErr_SetString(PyExc_ValueError, "bytearray: negative count"); return -1; } if (count > 0) { diff -r 98456ab88ab0 Objects/bytesobject.c --- a/Objects/bytesobject.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Objects/bytesobject.c Sun Oct 16 01:59:19 2016 +0300 @@ -507,13 +507,19 @@ if (iobj == NULL) { if (!PyErr_ExceptionMatches(PyExc_TypeError)) return 0; - goto onError; + PyErr_SetString(PyExc_TypeError, + "%c requires an integer in range(256) or a " + "single byte"); + return 0; } ival = PyLong_AsLongAndOverflow(iobj, &overflow); Py_DECREF(iobj); } - if (!overflow && ival == -1 && PyErr_Occurred()) - goto onError; + /* If we reached here, PyLong_AsLongAndOverflow was called + for an object such that PyLong_Check(object) is true, so + it is guaranteed that no error occurred in it. */ + assert(!(ival == -1 && PyErr_Occurred())); + if (overflow || !(0 <= ival && ival <= 255)) { PyErr_SetString(PyExc_OverflowError, "%c arg not in range(256)"); @@ -522,10 +528,6 @@ *p = (char)ival; return 1; } - onError: - PyErr_SetString(PyExc_TypeError, - "%c requires an integer in range(256) or a single byte"); - return 0; } static PyObject * @@ -2565,10 +2567,14 @@ if (PyIndex_Check(x)) { size = PyNumber_AsSsize_t(x, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "bytes: count does not fit in C Py_ssize_t"); + } return NULL; } if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); + PyErr_SetString(PyExc_ValueError, "bytes: negative count"); return NULL; } new = _PyBytes_FromSize(size, 1); diff -r 98456ab88ab0 Objects/longobject.c --- a/Objects/longobject.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Objects/longobject.c Sun Oct 16 01:59:19 2016 +0300 @@ -471,12 +471,14 @@ { int overflow; long result = PyLong_AsLongAndOverflow(obj, &overflow); - if (overflow) { - /* XXX: could be cute and give a different - message for overflow == -1 */ + if (overflow == 1) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C long"); } + else if (overflow == -1) { + PyErr_SetString(PyExc_OverflowError, + "Python int too small to convert to C long"); + } return result; } @@ -488,13 +490,19 @@ { int overflow; long result = PyLong_AsLongAndOverflow(obj, &overflow); - if (overflow || result > INT_MAX || result < INT_MIN) { - /* XXX: could be cute and give a different - message for overflow == -1 */ + if (result == -1 && PyErr_Occurred()) { + return -1; + } + if (overflow == 1 || result > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int"); return -1; } + else if (overflow == -1 || result < INT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "Python int too small to convert to C int"); + return -1; + } return (int)result; } @@ -548,8 +556,14 @@ /* else overflow */ overflow: - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C ssize_t"); + if (sign == 1) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C Py_ssize_t"); + } + else { + PyErr_SetString(PyExc_OverflowError, + "Python int too small to convert to C Py_ssize_t"); + } return -1; } @@ -577,7 +591,8 @@ x = 0; if (i < 0) { PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to unsigned int"); + "can't convert negative Python int to C " + "unsigned long"); return (unsigned long) -1; } switch (i) { @@ -621,7 +636,7 @@ x = 0; if (i < 0) { PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to size_t"); + "can't convert negative Python int to C size_t"); return (size_t) -1; } switch (i) { @@ -633,7 +648,7 @@ x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C size_t"); + "Python int too large to convert to C size_t"); return (size_t) -1; } } @@ -734,8 +749,9 @@ return result; Overflow: - PyErr_SetString(PyExc_OverflowError, "int has too many bits " - "to express in a platform size_t"); + PyErr_SetString(PyExc_OverflowError, + "number of bits of Python int too large to express in C " + "size_t"); return (size_t)-1; } @@ -4300,11 +4316,17 @@ } else { shiftby = PyLong_AsSsize_t((PyObject *)b); - if (shiftby == -1L && PyErr_Occurred()) + if (shiftby == -1L && PyErr_Occurred()) { + /* PyLong_Check(b) is true, so it must be that + PyLong_AsSsize_t raised an OverflowError. */ + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "shift count does not fit in C Py_ssize_t"); return NULL; + } if (shiftby < 0) { PyErr_SetString(PyExc_ValueError, - "negative shift count"); + "shift count can't be negative"); return NULL; } wordshift = shiftby / PyLong_SHIFT; @@ -4341,10 +4363,16 @@ CHECK_BINOP(a, b); shiftby = PyLong_AsSsize_t((PyObject *)b); - if (shiftby == -1L && PyErr_Occurred()) + if (shiftby == -1L && PyErr_Occurred()) { + /* PyLong_Check(b) is true, so it must be that + PyLong_AsSsize_t raised an OverflowError. */ + assert(PyErr_ExceptionMatches(PyExc_OverflowError)); + PyErr_SetString(PyExc_OverflowError, + "shift count does not fit in C Py_ssize_t"); return NULL; + } if (shiftby < 0) { - PyErr_SetString(PyExc_ValueError, "negative shift count"); + PyErr_SetString(PyExc_ValueError, "shift count can't be negative"); return NULL; } diff -r 98456ab88ab0 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Objects/unicodeobject.c Sun Oct 16 01:59:19 2016 +0300 @@ -14200,6 +14200,7 @@ static Py_UCS4 formatchar(PyObject *v) { + int overflow; /* presume that the buffer is at least 3 characters long */ if (PyUnicode_Check(v)) { if (PyUnicode_GET_LENGTH(v) == 1) { @@ -14220,11 +14221,12 @@ Py_DECREF(iobj); } /* Integer input truncated to a character */ - x = PyLong_AsLong(v); - if (x == -1 && PyErr_Occurred()) - goto onError; - - if (x < 0 || x > MAX_UNICODE) { + x = PyLong_AsLongAndOverflow(v, &overflow); + /* PyLong_Check(v) is true, so it is guaranteed that no + error occurred in PyLong_AsLongAndOverflow. */ + assert(!(x == -1 && PyErr_Occurred())); + + if (overflow || x < 0 || x > MAX_UNICODE) { PyErr_SetString(PyExc_OverflowError, "%c arg not in range(0x110000)"); return (Py_UCS4) -1; diff -r 98456ab88ab0 Python/formatter_unicode.c --- a/Python/formatter_unicode.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Python/formatter_unicode.c Sun Oct 16 01:59:19 2016 +0300 @@ -860,6 +860,7 @@ Py_ssize_t prefix = 0; NumberFieldWidths spec; long x; + int overflow; /* Locale settings, either from the actual locale or from a hard-code pseudo-locale */ @@ -891,10 +892,11 @@ /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ - x = PyLong_AsLong(value); - if (x == -1 && PyErr_Occurred()) + x = PyLong_AsLongAndOverflow(value, &overflow); + if (x == -1 && PyErr_Occurred()) { goto done; - if (x < 0 || x > 0x10ffff) { + } + if (overflow || x < 0 || x > 0x10ffff) { PyErr_SetString(PyExc_OverflowError, "%c arg not in range(0x110000)"); goto done; diff -r 98456ab88ab0 Python/getargs.c --- a/Python/getargs.c Sat Oct 15 01:39:21 2016 +0000 +++ b/Python/getargs.c Sun Oct 16 01:59:19 2016 +0300 @@ -67,7 +67,8 @@ /* Forward */ static int vgetargs1(PyObject *, const char *, va_list *, int); -static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); +static void seterror(Py_ssize_t, const char *, int *, const char *, + const char *, const char *); static const char *convertitem(PyObject *, const char **, va_list *, int, int *, char *, size_t, freelist_t *); static const char *converttuple(PyObject *, const char **, va_list *, int, @@ -241,6 +242,7 @@ freelist.first_available = 0; freelist.entries_malloced = 0; + assert(format != NULL); assert(compat || (args != (PyObject*)NULL)); flags = flags & ~FLAG_COMPAT; @@ -325,7 +327,7 @@ msgbuf, sizeof(msgbuf), &freelist); if (msg == NULL) return cleanreturn(1, &freelist); - seterror(levels[0], msg, levels+1, fname, message); + seterror(levels[0], msg, levels+1, fname, message, format); return cleanreturn(0, &freelist); } else { @@ -366,7 +368,7 @@ flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg) { - seterror(i+1, msg, levels, fname, message); + seterror(i+1, msg, levels, fname, message, format); return cleanreturn(0, &freelist); } } @@ -386,14 +388,21 @@ static void seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, - const char *message) + const char *message, const char *p_format_code) { char buf[512]; int i; char *p = buf; - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + assert(p_format_code != NULL); + if (PyErr_ExceptionMatches(PyExc_OverflowError) && fname != NULL && + strchr("bhilLn", *p_format_code)) { + PyErr_Format(PyExc_OverflowError, + "%.150s() argument out of range", fname); + } return; + } else if (message == NULL) { if (fname != NULL) { PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname); @@ -598,7 +607,11 @@ When failing, an exception may or may not have been raised. Don't call if a tuple is expected. - When you add new format codes, please don't forget poor skipitem() below. + When you add new format codes, please don't forget poor skipitem() + below. + In case the new format code is for a conversion to an integer that + might overflow, please don't forget the strchr argument in poor + seterror() above. */ static const char * @@ -626,6 +639,7 @@ const char *format = *p_format; char c = *format++; char *sarg; + int overflow; switch (c) { @@ -634,17 +648,19 @@ long ival; if (float_argument_error(arg)) RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + ival = PyLong_AsLongAndOverflow(arg, &overflow); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; - else if (ival < 0) { + else if (overflow == 1 || ival > UCHAR_MAX) { PyErr_SetString(PyExc_OverflowError, - "unsigned byte integer is less than minimum"); + "Python int too large to convert to C unsigned " + "char"); RETURN_ERR_OCCURRED; } - else if (ival > UCHAR_MAX) { + else if (overflow == -1 || ival < 0) { PyErr_SetString(PyExc_OverflowError, - "unsigned byte integer is greater than maximum"); + "can't convert negative Python int to C unsigned " + "char"); RETURN_ERR_OCCURRED; } else @@ -671,17 +687,17 @@ long ival; if (float_argument_error(arg)) RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + ival = PyLong_AsLongAndOverflow(arg, &overflow); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; - else if (ival < SHRT_MIN) { + else if (overflow == 1 || ival > SHRT_MAX) { PyErr_SetString(PyExc_OverflowError, - "signed short integer is less than minimum"); + "Python int too large to convert to C short"); RETURN_ERR_OCCURRED; } - else if (ival > SHRT_MAX) { + else if (overflow == -1 || ival < SHRT_MIN) { PyErr_SetString(PyExc_OverflowError, - "signed short integer is greater than maximum"); + "Python int too small to convert to C short"); RETURN_ERR_OCCURRED; } else @@ -705,22 +721,12 @@ case 'i': {/* signed int */ int *p = va_arg(*p_va, int *); - long ival; + int ival; if (float_argument_error(arg)) RETURN_ERR_OCCURRED; - ival = PyLong_AsLong(arg); + ival = _PyLong_AsInt(arg); if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED; - else if (ival > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "signed integer is greater than maximum"); - RETURN_ERR_OCCURRED; - } - else if (ival < INT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "signed integer is less than minimum"); - RETURN_ERR_OCCURRED; - } else *p = ival; break; @@ -1738,7 +1744,7 @@ msg = convertitem(current_arg, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg) { - seterror(i+1, msg, levels, fname, custom_msg); + seterror(i+1, msg, levels, fname, custom_msg, format); return cleanreturn(0, &freelist); } continue; @@ -2057,6 +2063,7 @@ } format = parser->format; + assert(format != NULL); /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ for (i = 0; i < len; i++) { keyword = (i >= pos) ? PyTuple_GET_ITEM(kwtuple, i - pos) : NULL; @@ -2099,7 +2106,8 @@ msg = convertitem(current_arg, &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg) { - seterror(i+1, msg, levels, parser->fname, parser->custom_msg); + seterror(i+1, msg, levels, parser->fname, parser->custom_msg, + format); return cleanreturn(0, &freelist); } continue;