cpython: 974ace29ee2d (original) (raw)

Mercurial > cpython

changeset 81587:974ace29ee2d 3.2

Issue #15989: Fix several occurrences of integer overflow when result of PyLong_AsLong() narrowed to int without checks. This is a backport of changesets 13e2e44db99d and 525407d89277. [#15989]

Serhiy Storchaka storchaka@gmail.com
date Sat, 19 Jan 2013 12:26:26 +0200
parents 4a1a88d25fec
children 8f10c9eae183 101e821e5e70
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_socket.py Modules/_ctypes/stgdict.c Modules/_io/_iomodule.c Modules/_io/fileio.c Modules/selectmodule.c Modules/socketmodule.c Objects/fileobject.c Objects/longobject.c Objects/unicodeobject.c
diffstat 16 files changed, 129 insertions(+), 20 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_socket.py 27 Modules/_ctypes/stgdict.c 2 Modules/_io/_iomodule.c 7 Modules/_io/fileio.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 @@ -1142,6 +1143,16 @@ class MixinStrUnicodeUserStringTest: self.checkraises(TypeError, '%10.*f', 'mod', ('foo', 42.)) self.checkraises(ValueError, '%10', 'mod', (42,))

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

--- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -6,6 +6,7 @@ OS/2+EMX doesn't support the file lockin import os import struct import sys +import _testcapi import unittest from test.support import verbose, TESTFN, unlink, run_unittest, import_module @@ -76,6 +77,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 @@ -7,6 +7,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 @@ -346,6 +347,9 @@ class OtherFileTests(unittest.TestCase): if sys.platform == 'win32': import msvcrt self.assertRaises(IOError, 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 @@ -31,6 +31,7 @@ import signal import errno import warnings import pickle +import _testcapi from itertools import cycle, count from collections import deque, UserList from test import support @@ -1903,6 +1904,14 @@ class TextIOWrapperTest(unittest.TestCas t.write("A\rB") self.assertEqual(r.getvalue(), b"XY\nZA\rB")

+ 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 +import _testcapi from test.support import TESTFN, run_unittest try: @@ -150,6 +151,15 @@ class PollTests(unittest.TestCase): if x != 5: self.fail('Overflow must have occurred')

+ def test_main(): run_unittest(PollTests)

--- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -7,6 +7,7 @@ import errno import io import socket import select +import _testcapi import time import traceback import queue @@ -850,11 +851,17 @@ class GeneralModuleTests(unittest.TestCa self.assertRaises(ValueError, fp.writable) self.assertRaises(ValueError, fp.seekable)

+

@unittest.skipUnless(SUPPORTS_IPV6, 'IPv6 required for this test.') @@ -954,6 +961,11 @@ class BasicTCPTest(SocketConnectedTest): def _testShutdown(self): self.serv_conn.send(MSG)

def testDetach(self): @@ -1067,7 +1079,10 @@ class NonBlockingTCPTests(ThreadedTCPSoc def testSetBlocking(self): # Testing whether set blocking works

@@ -1075,6 +1090,10 @@ 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/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -303,7 +303,8 @@ io_open(PyObject *self, PyObject *args, int text = 0, binary = 0, universal = 0; char rawmode[5], *m;

PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; @@ -441,12 +442,12 @@ io_open(PyObject *self, PyObject *args, #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE { struct stat st;

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

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

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

--- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1737,7 +1737,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()) @@ -2219,7 +2219,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) PyObject *meth; if (PyLong_Check(o)) {

if (PyLong_Check(fno)) {

--- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -424,6 +424,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 @@ -9640,7 +9640,7 @@ PyObject *PyUnicode_Format(PyObject for " wants int"); goto onError; }

@@ -9677,7 +9677,7 @@ PyObject *PyUnicode_Format(PyObject for " wants int"); goto onError; }