From 09e3c0ebaa5acee8dafbb7ecf4ebdf3aa2a9abad Mon Sep 17 00:00:00 2001 From: Lars Kanis <kanis@comcard.de> Date: Mon, 13 Feb 2012 12:18:42 +0100 Subject: [PATCH] Fix invalid memory access in final GC call when using FXMenuCommand with acckey Calling other classes while garbage collection is generally dangerous and useless. --- ext/fox16/FXRuby.cpp | 6 +++--- ext/fox16/markfuncs.cpp | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ext/fox16/FXRuby.cpp b/ext/fox16/FXRuby.cpp index 8f5e7dd..faf67c6 100644 --- a/ext/fox16/FXRuby.cpp +++ b/ext/fox16/FXRuby.cpp @@ -1536,7 +1536,7 @@ FXwchar FXRbCallWCharMethod(const FXObject* recv, ID func){ FXRbMenuCommand::~FXRbMenuCommand(){ FXAccelTable *table; FXWindow *owner; - if(acckey){ + if(acckey && !FXRbIsInGC(this)){ owner=getShell()->getOwner(); if(owner){ table=owner->getAccelTable(); @@ -1552,7 +1552,7 @@ FXRbMenuCommand::~FXRbMenuCommand(){ FXRbMenuCheck::~FXRbMenuCheck(){ FXAccelTable *table; FXWindow *owner; - if(acckey){ + if(acckey && !FXRbIsInGC(this)){ owner=getShell()->getOwner(); if(owner){ table=owner->getAccelTable(); @@ -1568,7 +1568,7 @@ FXRbMenuCheck::~FXRbMenuCheck(){ FXRbMenuRadio::~FXRbMenuRadio(){ FXAccelTable *table; FXWindow *owner; - if(acckey){ + if(acckey && !FXRbIsInGC(this)){ owner=getShell()->getOwner(); if(owner){ table=owner->getAccelTable(); diff --git a/ext/fox16/markfuncs.cpp b/ext/fox16/markfuncs.cpp index 87b75f6..040ea3b 100644 --- a/ext/fox16/markfuncs.cpp +++ b/ext/fox16/markfuncs.cpp @@ -53,9 +53,16 @@ void FXRbObject::markfunc(FXObject* obj){ FXTRACE((100,"%s::markfunc(%p)\n",obj?obj->getClassName():"FXRbObject",obj)); } -static void FXRbSetInGCRecursive(FXWindow *window, bool enabled){ +static void FXRbSetInGCParentsRecursive(FXWindow *window, bool enabled){ FXRbSetInGC( window, true ); - if(window->getParent()) FXRbSetInGCRecursive( window->getParent(), enabled ); + if(window->getParent()) FXRbSetInGCParentsRecursive( window->getParent(), enabled ); + } + +static void FXRbSetInGCChildrenRecursive(FXWindow *window, bool enabled){ + FXRbSetInGC( window, true ); + for(FXWindow* child=window->getFirst(); child; child=child->getNext()){ + FXRbSetInGCChildrenRecursive( child, enabled ); + } } @@ -78,9 +85,9 @@ void FXRbObject::freefunc(FXObject* self){ // The parent window should also be scheduled to be free'd. In the other case, // the child window would have been marked as used. if(self->isMemberOf(FXMETACLASS(FXWindow))){ - if(FXWindow *parent = dynamic_cast<FXWindow*>(self)->getParent()){ - FXRbSetInGCRecursive( parent, true ); - } + FXWindow *window = dynamic_cast<FXWindow*>(self); + FXRbSetInGCParentsRecursive( window, true ); + FXRbSetInGCChildrenRecursive( window, true ); } delete self; } -- GitLab