From a6cecbcb34c1ad70425f3aaaf6cb4d2650c8ba3d Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 27 Dec 2020 15:14:59 +0100 Subject: [PATCH] Fix invalid access when reinterpret_casting a non-pybind11 PyObject* to instance* (found by Valgrind in #2746) --- include/pybind11/pybind11.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 70ba635ebe..4e15406510 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -504,15 +504,15 @@ class cpp_function : public function { auto self_value_and_holder = value_and_holder(); if (overloads->is_constructor) { - const auto tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr()); - const auto pi = reinterpret_cast(parent.ptr()); - self_value_and_holder = pi->get_value_and_holder(tinfo, false); - - if (!self_value_and_holder.type || !self_value_and_holder.inst) { + if (!PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) { PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument"); return nullptr; } + const auto tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr()); + const auto pi = reinterpret_cast(parent.ptr()); + self_value_and_holder = pi->get_value_and_holder(tinfo, true); + // If this value is already registered it must mean __init__ is invoked multiple times; // we really can't support that in C++, so just ignore the second __init__. if (self_value_and_holder.instance_registered())