summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2020-11-21 10:02:53 (GMT)
committerGitHub <noreply@github.com>2020-11-21 10:02:53 (GMT)
commit1db76394ea79030aa4ed5349c950f6c6da51450f (patch)
tree1c983ea426540a616afb1dbca1d8c737c3ad63b3 /Objects
parent01a202ab6b0ded546e47073db6498262086c52e9 (diff)
downloadcpython-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.c23
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;