From a1b7cb53307a9cb62a560b3632906b0457a75218 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sun, 16 Dec 2012 21:31:19 +0100 Subject: [PATCH] Fix memory leak if nasal::Ghost creation fails --- simgear/nasal/cppbind/Ghost.hxx | 41 +++++++++++++------------- simgear/nasal/cppbind/cppbind_test.cxx | 5 ++++ 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/simgear/nasal/cppbind/Ghost.hxx b/simgear/nasal/cppbind/Ghost.hxx index d2a5d22c..39b4f3c3 100644 --- a/simgear/nasal/cppbind/Ghost.hxx +++ b/simgear/nasal/cppbind/Ghost.hxx @@ -94,7 +94,7 @@ namespace nasal */ static T* createInstance(const T& ptr) { - return new T(ptr); + return ptr ? new T(ptr) : 0; } static pointer getPtr(void* ptr) @@ -800,31 +800,32 @@ namespace nasal static naRef makeGhost(naContext c, void *ptr) { - if( !Ghost::getRawPtr(ptr) ) - return naNil(); - - naGhostType* ghost_type = 0; - if( Ghost::returns_dynamic_type::value ) - // For pointer policies already returning instances of an object with - // the dynamic type of this Ghost's raw_type the type is always the - // same. - ghost_type = &getSingletonPtr()->_ghost_type; - else - // If wrapping eg. shared pointers the users passes an already - // existing instance of an object which will then be hold be a new - // shared pointer. We therefore have to check for the dynamic type - // of the object as it might differ from the passed static type. - ghost_type = getTypeFor( Ghost::getRawPtr(ptr) ); + if( Ghost::getRawPtr(ptr) ) + { + naGhostType* ghost_type = 0; + if( Ghost::returns_dynamic_type::value ) + // For pointer policies already returning instances of an object + // with the dynamic type of this Ghost's raw_type the type is always + // the same. + ghost_type = &getSingletonPtr()->_ghost_type; + else + // If wrapping eg. shared pointers the users passes an already + // existing instance of an object which will then be hold be a new + // shared pointer. We therefore have to check for the dynamic type + // of the object as it might differ from the passed static type. + ghost_type = getTypeFor( Ghost::getRawPtr(ptr) ); - if( !ghost_type ) - return naNil(); + if( ghost_type ) + return naNewGhost2(c, ghost_type, ptr); + } - return naNewGhost2(c, ghost_type, ptr); + destroyGhost(ptr); + return naNil(); } static void destroyGhost(void *ptr) { - delete (T*)ptr; + delete static_cast(ptr); } /** diff --git a/simgear/nasal/cppbind/cppbind_test.cxx b/simgear/nasal/cppbind/cppbind_test.cxx index 47a437bc..d8b29b1b 100644 --- a/simgear/nasal/cppbind/cppbind_test.cxx +++ b/simgear/nasal/cppbind/cppbind_test.cxx @@ -45,6 +45,10 @@ typedef boost::shared_ptr DoubleDerivedPtr; typedef boost::shared_ptr DoubleDerived2Ptr; naRef member(Derived&, const nasal::CallContext&) { return naNil(); } +naRef f_derivedGetX(naContext c, const Derived& d) +{ + return nasal::to_nasal(c, d.getX()); +} int main(int argc, char* argv[]) { @@ -104,6 +108,7 @@ int main(int argc, char* argv[]) Ghost::init("Derived") .bases() .member("x", &Derived::getX, &Derived::setX) + .member("x_alternate", &f_derivedGetX) .method_func<&member>("free_member"); naRef derived = Ghost::create(c); -- 2.39.5