cpython: d544873d62e9 (original) (raw)

Mercurial > cpython

changeset 81590:d544873d62e9 2.7

Issue #15989: Fix several occurrences of integer overflow when result of PyInt_AsLong() or 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:55:39 +0200
parents bfe38710d4e6
children 1d33c79d2f6b
files Include/intobject.h 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_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/intobject.c Objects/longobject.c Objects/unicodeobject.c
diffstat 17 files changed, 143 insertions(+), 22 deletions(-)[+] [-] Include/intobject.h 1 Include/longobject.h 1 Lib/ctypes/test/test_structures.py 9 Lib/test/string_tests.py 15 Lib/test/test_fcntl.py 21 Lib/test/test_fileio.py 4 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 8 Objects/intobject.c 14 Objects/longobject.c 18 Objects/unicodeobject.c 8

line wrap: on

line diff

--- a/Include/intobject.h +++ b/Include/intobject.h @@ -40,6 +40,7 @@ PyAPI_FUNC(PyObject *) PyInt_FromSize_t( PyAPI_FUNC(PyObject *) PyInt_FromSsize_t(Py_ssize_t); PyAPI_FUNC(long) PyInt_AsLong(PyObject *); PyAPI_FUNC(Py_ssize_t) PyInt_AsSsize_t(PyObject *); +PyAPI_FUNC(int) _PyInt_AsInt(PyObject *); PyAPI_FUNC(unsigned long) PyInt_AsUnsignedLongMask(PyObject *); #ifdef HAVE_LONG_LONG PyAPI_FUNC(unsigned PY_LONG_LONG) PyInt_AsUnsignedLongLongMask(PyObject *);

--- a/Include/longobject.h +++ b/Include/longobject.h @@ -25,6 +25,7 @@ PyAPI_FUNC(long) PyLong_AsLongAndOverflo PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); +PyAPI_FUNC(int) _PyLong_AsInt(PyObject *); PyAPI_FUNC(PyObject ) PyLong_GetInfo(void); / For use by intobject.c only */

--- 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 test_support from UserList import UserList +import _testcapi class Sequence: def init(self, seq='wxyz'): self.seq = seq @@ -1113,6 +1114,20 @@ 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.test_support import (verbose, TESTFN, unlink, run_unittest, import_module) @@ -81,6 +82,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 @@ -10,6 +10,7 @@ from array import array from weakref import proxy from functools import wraps from UserList import UserList +import _testcapi from test.test_support import TESTFN, check_warnings, run_unittest, make_bad_fd from test.test_support import py3k_bytes as bytes @@ -343,6 +344,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_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.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 @@ -6,6 +6,7 @@ from test import test_support import errno import socket import select +import _testcapi import time import traceback import Queue @@ -700,11 +701,17 @@ class GeneralModuleTests(unittest.TestCa def test_sendall_interrupted_with_timeout(self): self.check_sendall_interrupted(True)

+

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

@unittest.skipUnless(thread, 'Threading required for this test.') @@ -883,7 +895,10 @@ class NonBlockingTCPTests(ThreadedTCPSoc def testSetBlocking(self): # Testing whether set blocking works

@@ -891,6 +906,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 @@ -343,7 +343,7 @@ PyCStructUnionType_update_stgdict(PyObje isPacked = PyObject_GetAttrString(type, "pack"); if (isPacked) {

--- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -300,7 +300,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; @@ -443,12 +444,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 @@ -211,7 +211,7 @@ fileio_init(PyObject *oself, PyObject *a return -1; }

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

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

--- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1713,7 +1713,7 @@ info is a pair (hostaddr, port)."); static PyObject * sock_setblocking(PySocketSockObject *s, PyObject *arg) {

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

--- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -2659,10 +2659,10 @@ int PyObject_AsFileDescriptor(PyObject * PyObject *meth; if (PyInt_Check(o)) {

if (PyInt_Check(fno)) {

--- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -189,6 +189,20 @@ PyInt_AsLong(register PyObject *op) return val; } +int +_PyInt_AsInt(PyObject *obj) +{

+} + Py_ssize_t PyInt_AsSsize_t(register PyObject *op) {

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

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