From 74d5f61ebd1cb14907bf7dae1ad9c1e676707bc5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Nov 2022 12:15:21 +0100 Subject: gh-99845: Clean up _PyObject_VAR_SIZE() usage (#99847) * code_sizeof() now uses an unsigned type (size_t) to compute the result. * Fix _PyObject_ComputedDictPointer(): cast _PyObject_VAR_SIZE() to Py_ssize_t, rather than long: it's a different type on 64-bit Windows. * Clarify that _PyObject_VAR_SIZE() uses an unsigned type (size_t). --- Modules/gcmodule.c | 5 ++--- Objects/codeobject.c | 10 ++++------ Objects/object.c | 13 ++++++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index cacfad7..6630faa 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -2329,7 +2329,6 @@ _PyObject_GC_New(PyTypeObject *tp) PyVarObject * _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) { - size_t size; PyVarObject *op; if (nitems < 0) { @@ -2337,7 +2336,7 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) return NULL; } size_t presize = _PyType_PreHeaderSize(tp); - size = _PyObject_VAR_SIZE(tp, nitems); + size_t size = _PyObject_VAR_SIZE(tp, nitems); op = (PyVarObject *)gc_alloc(size, presize); if (op == NULL) { return NULL; @@ -2351,7 +2350,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) { const size_t basicsize = _PyObject_VAR_SIZE(Py_TYPE(op), nitems); _PyObject_ASSERT((PyObject *)op, !_PyObject_GC_IS_TRACKED(op)); - if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { + if (basicsize > (size_t)PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { return (PyVarObject *)PyErr_NoMemory(); } diff --git a/Objects/codeobject.c b/Objects/codeobject.c index fc1db72..f5d90cf 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1867,15 +1867,13 @@ static PyGetSetDef code_getsetlist[] = { static PyObject * code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) { - Py_ssize_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); - + size_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; if (co_extra != NULL) { - res += sizeof(_PyCodeObjectExtra) + - (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); + res += sizeof(_PyCodeObjectExtra); + res += ((size_t)co_extra->ce_size - 1) * sizeof(co_extra->ce_extras[0]); } - - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } static PyObject * diff --git a/Objects/object.c b/Objects/object.c index a499cb3..687bd36 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1043,22 +1043,25 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) PyObject ** _PyObject_ComputedDictPointer(PyObject *obj) { - Py_ssize_t dictoffset; PyTypeObject *tp = Py_TYPE(obj); - assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); - dictoffset = tp->tp_dictoffset; - if (dictoffset == 0) + + Py_ssize_t dictoffset = tp->tp_dictoffset; + if (dictoffset == 0) { return NULL; + } + if (dictoffset < 0) { assert(dictoffset != -1); + Py_ssize_t tsize = Py_SIZE(obj); if (tsize < 0) { tsize = -tsize; } size_t size = _PyObject_VAR_SIZE(tp, tsize); + assert(size <= (size_t)PY_SSIZE_T_MAX); + dictoffset += (Py_ssize_t)size; - dictoffset += (long)size; _PyObject_ASSERT(obj, dictoffset > 0); _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0); } -- cgit v0.12