cpython: 13e2e44db99d (original) (raw)

Mercurial > cpython

changeset 81505:13e2e44db99d

Issue #15989: Fix several occurrences of integer overflow when result of PyLong_AsLong() narrowed to int without checks. [#15989]

Serhiy Storchaka storchaka@gmail.com
date Tue, 15 Jan 2013 01:12:17 +0200
parents 628a6af64a46
children de719ed20c74
files Include/longobject.h Lib/ctypes/test/test_structures.py Lib/test/string_tests.py Lib/test/test_fcntl.py Lib/test/test_fileio.py Lib/test/test_io.py Lib/test/test_poll.py Lib/test/test_posix.py Lib/test/test_socket.py Modules/_ctypes/stgdict.c Modules/_io/fileio.c Modules/_io/textio.c Modules/parsermodule.c Modules/posixmodule.c Modules/selectmodule.c Modules/socketmodule.c Objects/fileobject.c Objects/longobject.c Objects/unicodeobject.c
diffstat 19 files changed, 148 insertions(+), 24 deletions(-)[+] [-] Include/longobject.h 3 Lib/ctypes/test/test_structures.py 9 Lib/test/string_tests.py 11 Lib/test/test_fcntl.py 21 Lib/test/test_fileio.py 4 Lib/test/test_io.py 9 Lib/test/test_poll.py 10 Lib/test/test_posix.py 5 Lib/test/test_socket.py 22 Modules/_ctypes/stgdict.c 2 Modules/_io/fileio.c 4 Modules/_io/textio.c 2 Modules/parsermodule.c 24 Modules/posixmodule.c 2 Modules/selectmodule.c 12 Modules/socketmodule.c 6 Objects/fileobject.c 4 Objects/longobject.c 18 Objects/unicodeobject.c 4

line wrap: on

line diff

--- a/Include/longobject.h +++ b/Include/longobject.h @@ -26,6 +26,9 @@ PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t( PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); +#endif PyAPI_FUNC(PyObject ) PyLong_GetInfo(void); / It may be useful in the future. I've added it in the PyInt -> PyLong

--- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -1,6 +1,7 @@ import unittest from ctypes import * from struct import calcsize +import _testcapi class SubclassesTest(unittest.TestCase): def test_subclass(self): @@ -199,6 +200,14 @@ class StructureTestCase(unittest.TestCas "pack": -1} self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)

+ def test_initializers(self): class Person(Structure): fields = [("name", c_char*6),

--- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -5,6 +5,7 @@ Common tests shared by test_str, test_un import unittest, string, sys, struct from test import support from collections import UserList +import _testcapi class Sequence: def init(self, seq='wxyz'): self.seq = seq @@ -1206,6 +1207,16 @@ class MixinStrUnicodeUserStringTest: self.checkraises(ValueError, '%%%df' % (264), 'mod', (3.2)) self.checkraises(ValueError, '%%.%df' % (264), 'mod', (3.2))

+ class X(object): pass self.checkraises(TypeError, 'abc', 'mod', X())

--- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -3,6 +3,7 @@ import os import struct import sys +import _testcapi import unittest from test.support import verbose, TESTFN, unlink, run_unittest, import_module @@ -69,6 +70,26 @@ class TestFcntl(unittest.TestCase): rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata) self.f.close()

+ def test_fcntl_64_bit(self): # Issue #1309352: fcntl shouldn't fail when the third arg fits in a # C 'long' but not in a C 'int'.

--- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -8,6 +8,7 @@ import unittest from array import array from weakref import proxy from functools import wraps +import _testcapi from test.support import TESTFN, check_warnings, run_unittest, make_bad_fd from collections import UserList @@ -347,6 +348,9 @@ class OtherFileTests(unittest.TestCase): if sys.platform == 'win32': import msvcrt self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd())

def testBadModeArgument(self): # verify that we get a sensible error message for bad mode argument

--- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -32,6 +32,7 @@ import time import unittest import warnings import weakref +import _testcapi from collections import deque, UserList from itertools import cycle, count from test import support @@ -1970,6 +1971,14 @@ class TextIOWrapperTest(unittest.TestCas os.environ.clear() os.environ.update(old_environ)

+ def test_encoding(self): # Check the encoding attribute is always set, and valid b = self.BytesIO()

--- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -1,6 +1,7 @@

Test case for the os.poll() function

import os, select, random, unittest, subprocess +import _testcapi from test.support import TESTFN, run_unittest try: @@ -151,6 +152,15 @@ class PollTests(unittest.TestCase): if x != 5: self.fail('Overflow must have occurred')

+ def test_main(): run_unittest(PollTests)

--- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -17,6 +17,7 @@ import stat import tempfile import unittest import warnings +import _testcapi _DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), support.TESTFN + '-dummy-symlink') @@ -537,6 +538,10 @@ class PosixTester(unittest.TestCase): except OSError: pass

+ def test_utime(self): if hasattr(posix, 'utime'): now = time.time()

--- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1262,11 +1262,17 @@ class GeneralModuleTests(unittest.TestCa for protocol in range(pickle.HIGHEST_PROTOCOL + 1): self.assertRaises(TypeError, pickle.dumps, sock, protocol)

+

@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') @@ -1582,6 +1588,11 @@ class BasicTCPTest(SocketConnectedTest): def _testShutdown(self): self.serv_conn.send(MSG)

def testDetach(self): @@ -3563,6 +3574,11 @@ class NonBlockingTCPTests(ThreadedTCPSoc pass end = time.time() self.assertTrue((end - start) < 1.0, "Error setting non-blocking mode.")

def _testSetBlocking(self): pass

--- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -335,7 +335,7 @@ PyCStructUnionType_update_stgdict(PyObje isPacked = PyObject_GetAttrString(type, "pack"); if (isPacked) {

--- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -244,7 +244,7 @@ fileio_init(PyObject *oself, PyObject *a return -1; }

@@ -382,7 +382,7 @@ fileio_init(PyObject *oself, PyObject *a goto error; }

--- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -881,7 +881,7 @@ textiowrapper_init(textio *self, PyObjec } } else {

--- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -725,7 +725,7 @@ build_node_children(PyObject tuple, nod / elem must always be a sequence, however simple / PyObject elem = PySequence_GetItem(tuple, i); int ok = elem != NULL;

if (ok) @@ -736,8 +736,14 @@ build_node_children(PyObject *tuple, nod ok = 0; else { ok = PyLong_Check(temp);

@@ -773,8 +779,16 @@ build_node_children(PyObject *tuple, nod if (len == 3) { PyObject *o = PySequence_GetItem(elem, 2); if (o != NULL) {

--- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7647,7 +7647,7 @@ posix_pipe2(PyObject *self, PyObject *ar int fds[2]; int res;

--- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -352,10 +352,13 @@ update_ufd_array(pollObject *self) i = pos = 0; while (PyDict_Next(self->dict, &pos, &key, &value)) {

@@ -371,10 +374,11 @@ static PyObject * poll_register(pollObject *self, PyObject *args) { PyObject *o, *key, *value;

--- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2013,7 +2013,7 @@ For IP sockets, the address info is a pa static PyObject * sock_setblocking(PySocketSockObject *s, PyObject *arg) {

block = PyLong_AsLong(arg); if (block == -1 && PyErr_Occurred()) @@ -2495,7 +2495,7 @@ sock_listen(PySocketSockObject *s, PyObj int backlog; int res;

--- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -200,7 +200,7 @@ PyObject_AsFileDescriptor(PyObject *o) _Py_IDENTIFIER(fileno); if (PyLong_Check(o)) {

if (PyLong_Check(fno)) {

--- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -434,6 +434,24 @@ PyLong_AsLong(PyObject obj) return result; } +/ Get a C int from a long int object or any object that has an int

+int +_PyLong_AsInt(PyObject *obj) +{

+} + /* Get a Py_ssize_t from a long int object. Returns -1 and sets an error condition if overflow occurs. */

--- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13521,7 +13521,7 @@ unicode_format_arg_parse(struct unicode_ "* wants int"); return -1; }

@@ -13568,7 +13568,7 @@ unicode_format_arg_parse(struct unicode_ "* wants int"); return -1; }