diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2020-11-21 10:02:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-21 10:02:53 (GMT) |
commit | 1db76394ea79030aa4ed5349c950f6c6da51450f (patch) | |
tree | 1c983ea426540a616afb1dbca1d8c737c3ad63b3 /Objects | |
parent | 01a202ab6b0ded546e47073db6498262086c52e9 (diff) | |
download | cpython-1db76394ea79030aa4ed5349c950f6c6da51450f.zip cpython-1db76394ea79030aa4ed5349c950f6c6da51450f.tar.gz cpython-1db76394ea79030aa4ed5349c950f6c6da51450f.tar.bz2 |
bpo-42412: Fix possible leaks and check arguments in PyType_FromModuleAndSpec() (GH-23410)
* There were leaks if Py_tp_bases is used more than once or if some call is
failed before setting tp_bases.
* There was a crash if the bases argument or the Py_tp_bases slot is not a tuple.
* The documentation was not accurate.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index fd018b8..9ebeeeb 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2977,26 +2977,40 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) base = slot->pfunc; else if (slot->slot == Py_tp_bases) { bases = slot->pfunc; - Py_INCREF(bases); } } - if (!bases) + if (!bases) { bases = PyTuple_Pack(1, base); - if (!bases) + if (!bases) + goto fail; + } + else if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); goto fail; + } + else { + Py_INCREF(bases); + } } - else + else if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_SystemError, "bases is not a tuple"); + goto fail; + } + else { Py_INCREF(bases); + } /* Calculate best base, and check that all bases are type objects */ base = best_base(bases); if (base == NULL) { + Py_DECREF(bases); goto fail; } if (!_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { PyErr_Format(PyExc_TypeError, "type '%.100s' is not an acceptable base type", base->tp_name); + Py_DECREF(bases); goto fail; } @@ -3008,7 +3022,6 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) type->tp_as_buffer = &res->as_buffer; /* Set tp_base and tp_bases */ type->tp_bases = bases; - bases = NULL; Py_INCREF(base); type->tp_base = base; |