mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
[3.12] gh-117021: Fix integer overflow in PyLong_AsPid() on non-Windows 64-bit platforms (GH-117064) (GH-117070)
(cherry picked from commit 519b2ae22b
)
This commit is contained in:
parent
0325a8a8cd
commit
da2f9d1417
6 changed files with 60 additions and 4 deletions
|
@ -49,6 +49,9 @@
|
||||||
#include "bytearrayobject.h"
|
#include "bytearrayobject.h"
|
||||||
#include "bytesobject.h"
|
#include "bytesobject.h"
|
||||||
#include "unicodeobject.h"
|
#include "unicodeobject.h"
|
||||||
|
#include "cpython/initconfig.h"
|
||||||
|
#include "pystate.h"
|
||||||
|
#include "pyerrors.h"
|
||||||
#include "longobject.h"
|
#include "longobject.h"
|
||||||
#include "cpython/longintrepr.h"
|
#include "cpython/longintrepr.h"
|
||||||
#include "boolobject.h"
|
#include "boolobject.h"
|
||||||
|
@ -74,8 +77,6 @@
|
||||||
#include "sliceobject.h"
|
#include "sliceobject.h"
|
||||||
#include "cpython/cellobject.h"
|
#include "cpython/cellobject.h"
|
||||||
#include "iterobject.h"
|
#include "iterobject.h"
|
||||||
#include "cpython/initconfig.h"
|
|
||||||
#include "pystate.h"
|
|
||||||
#include "cpython/genobject.h"
|
#include "cpython/genobject.h"
|
||||||
#include "descrobject.h"
|
#include "descrobject.h"
|
||||||
#include "genericaliasobject.h"
|
#include "genericaliasobject.h"
|
||||||
|
@ -85,7 +86,6 @@
|
||||||
#include "cpython/picklebufobject.h"
|
#include "cpython/picklebufobject.h"
|
||||||
#include "cpython/pytime.h"
|
#include "cpython/pytime.h"
|
||||||
#include "codecs.h"
|
#include "codecs.h"
|
||||||
#include "pyerrors.h"
|
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
#include "cpython/context.h"
|
#include "cpython/context.h"
|
||||||
#include "modsupport.h"
|
#include "modsupport.h"
|
||||||
|
|
|
@ -34,7 +34,24 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
|
||||||
#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
|
#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
|
||||||
#define _Py_PARSE_PID "i"
|
#define _Py_PARSE_PID "i"
|
||||||
#define PyLong_FromPid PyLong_FromLong
|
#define PyLong_FromPid PyLong_FromLong
|
||||||
|
# ifndef Py_LIMITED_API
|
||||||
|
# define PyLong_AsPid _PyLong_AsInt
|
||||||
|
# elif SIZEOF_INT == SIZEOF_LONG
|
||||||
# define PyLong_AsPid PyLong_AsLong
|
# define PyLong_AsPid PyLong_AsLong
|
||||||
|
# else
|
||||||
|
static inline int
|
||||||
|
PyLong_AsPid(PyObject *obj)
|
||||||
|
{
|
||||||
|
int overflow;
|
||||||
|
long result = PyLong_AsLongAndOverflow(obj, &overflow);
|
||||||
|
if (overflow || result > INT_MAX || result < INT_MIN) {
|
||||||
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
"Python int too large to convert to C int");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int)result;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
#elif SIZEOF_PID_T == SIZEOF_LONG
|
#elif SIZEOF_PID_T == SIZEOF_LONG
|
||||||
#define _Py_PARSE_PID "l"
|
#define _Py_PARSE_PID "l"
|
||||||
#define PyLong_FromPid PyLong_FromLong
|
#define PyLong_FromPid PyLong_FromLong
|
||||||
|
|
|
@ -400,6 +400,29 @@ class LongTests(unittest.TestCase):
|
||||||
self.assertRaises(OverflowError, asvoidptr, -2**1000)
|
self.assertRaises(OverflowError, asvoidptr, -2**1000)
|
||||||
# CRASHES asvoidptr(NULL)
|
# CRASHES asvoidptr(NULL)
|
||||||
|
|
||||||
|
def test_long_aspid(self):
|
||||||
|
# Test PyLong_AsPid()
|
||||||
|
aspid = _testcapi.pylong_aspid
|
||||||
|
from _testcapi import SIZEOF_PID_T
|
||||||
|
bits = 8 * SIZEOF_PID_T
|
||||||
|
PID_T_MIN = -2**(bits-1)
|
||||||
|
PID_T_MAX = 2**(bits-1) - 1
|
||||||
|
# round trip (object -> long -> object)
|
||||||
|
for value in (PID_T_MIN, PID_T_MAX, -1, 0, 1, 1234):
|
||||||
|
with self.subTest(value=value):
|
||||||
|
self.assertEqual(aspid(value), value)
|
||||||
|
|
||||||
|
self.assertEqual(aspid(IntSubclass(42)), 42)
|
||||||
|
self.assertEqual(aspid(Index(42)), 42)
|
||||||
|
self.assertEqual(aspid(MyIndexAndInt()), 10)
|
||||||
|
|
||||||
|
self.assertRaises(OverflowError, aspid, PID_T_MIN - 1)
|
||||||
|
self.assertRaises(OverflowError, aspid, PID_T_MAX + 1)
|
||||||
|
self.assertRaises(TypeError, aspid, 1.0)
|
||||||
|
self.assertRaises(TypeError, aspid, b'2')
|
||||||
|
self.assertRaises(TypeError, aspid, '3')
|
||||||
|
self.assertRaises(SystemError, aspid, NULL)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix integer overflow in :c:func:`PyLong_AsPid` on non-Windows 64-bit
|
||||||
|
platforms.
|
|
@ -750,6 +750,18 @@ pylong_asvoidptr(PyObject *module, PyObject *arg)
|
||||||
return Py_NewRef((PyObject *)value);
|
return Py_NewRef((PyObject *)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pylong_aspid(PyObject *module, PyObject *arg)
|
||||||
|
{
|
||||||
|
NULLABLE(arg);
|
||||||
|
pid_t value = PyLong_AsPid(arg);
|
||||||
|
if (value == -1 && PyErr_Occurred()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyLong_FromPid(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef test_methods[] = {
|
static PyMethodDef test_methods[] = {
|
||||||
{"test_long_and_overflow", test_long_and_overflow, METH_NOARGS},
|
{"test_long_and_overflow", test_long_and_overflow, METH_NOARGS},
|
||||||
{"test_long_api", test_long_api, METH_NOARGS},
|
{"test_long_api", test_long_api, METH_NOARGS},
|
||||||
|
@ -778,6 +790,7 @@ static PyMethodDef test_methods[] = {
|
||||||
{"pylong_as_size_t", pylong_as_size_t, METH_O},
|
{"pylong_as_size_t", pylong_as_size_t, METH_O},
|
||||||
{"pylong_asdouble", pylong_asdouble, METH_O},
|
{"pylong_asdouble", pylong_asdouble, METH_O},
|
||||||
{"pylong_asvoidptr", pylong_asvoidptr, METH_O},
|
{"pylong_asvoidptr", pylong_asvoidptr, METH_O},
|
||||||
|
{"pylong_aspid", pylong_aspid, METH_O},
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3986,6 +3986,7 @@ PyInit__testcapi(void)
|
||||||
PyModule_AddObject(m, "SIZEOF_WCHAR_T", PyLong_FromSsize_t(sizeof(wchar_t)));
|
PyModule_AddObject(m, "SIZEOF_WCHAR_T", PyLong_FromSsize_t(sizeof(wchar_t)));
|
||||||
PyModule_AddObject(m, "SIZEOF_VOID_P", PyLong_FromSsize_t(sizeof(void*)));
|
PyModule_AddObject(m, "SIZEOF_VOID_P", PyLong_FromSsize_t(sizeof(void*)));
|
||||||
PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t)));
|
PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t)));
|
||||||
|
PyModule_AddObject(m, "SIZEOF_PID_T", PyLong_FromSsize_t(sizeof(pid_t)));
|
||||||
PyModule_AddObject(m, "Py_Version", PyLong_FromUnsignedLong(Py_Version));
|
PyModule_AddObject(m, "Py_Version", PyLong_FromUnsignedLong(Py_Version));
|
||||||
Py_INCREF(&PyInstanceMethod_Type);
|
Py_INCREF(&PyInstanceMethod_Type);
|
||||||
PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type);
|
PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue