From df01af5a1f05d03ad1464bca1fcbffe495ca0539 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 9 May 2009 18:18:04 +0000 Subject: Methods didn't check for zombies which could crash in the case where a method for an object is kept. func = ob.getMass ...remove ob... func() # crash 2 More refcount fixes spotted by Benoit too --- source/gameengine/Expressions/PyObjectPlus.h | 8 ++++++++ source/gameengine/Ketsji/KX_GameObject.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index c21dc3a6e57..b7f22404c7a 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -225,30 +225,35 @@ typedef struct { #define KX_PYMETHOD(class_name, method_name) \ PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ }; \ #define KX_PYMETHOD_VARARGS(class_name, method_name) \ PyObject* Py##method_name(PyObject* args); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ }; \ #define KX_PYMETHOD_NOARGS(class_name, method_name) \ PyObject* Py##method_name(); \ static PyObject* sPy##method_name( PyObject* self) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ }; \ #define KX_PYMETHOD_O(class_name, method_name) \ PyObject* Py##method_name(PyObject* value); \ static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ }; \ #define KX_PYMETHOD_DOC(class_name, method_name) \ PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ }; \ static const char method_name##_doc[]; \ @@ -256,6 +261,7 @@ typedef struct { #define KX_PYMETHOD_DOC_VARARGS(class_name, method_name) \ PyObject* Py##method_name(PyObject* args); \ static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ }; \ static const char method_name##_doc[]; \ @@ -263,6 +269,7 @@ typedef struct { #define KX_PYMETHOD_DOC_O(class_name, method_name) \ PyObject* Py##method_name(PyObject* value); \ static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ }; \ static const char method_name##_doc[]; \ @@ -270,6 +277,7 @@ typedef struct { #define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \ PyObject* Py##method_name(); \ static PyObject* sPy##method_name( PyObject* self) { \ + if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_SystemError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ }; \ static const char method_name##_doc[]; \ diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 4f3202aafea..c2216fd3514 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1726,7 +1726,7 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE for(i=0; i < (int)self->m_meshes.size(); i++) { KX_MeshProxy* meshproxy = new KX_MeshProxy(self->m_meshes[i]); - PyList_SET_ITEM(meshes, i, meshproxy->GetProxy()); + PyList_SET_ITEM(meshes, i, meshproxy->NewProxy(true)); } return meshes; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 7280071cd1d..208f8fc9461 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1847,5 +1847,9 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time); + + // release here because AddReplicaObject AddRef's + // the object is added to the scene so we dont want python to own a reference + replica->Release(); return replica->GetProxy(); } \ No newline at end of file -- cgit v1.2.3