diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2015-11-21 22:22:49 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2015-11-21 22:22:49 (GMT) |
commit | 6b4bc6bb8d46722088d73bd4a93f51e7fc65dbf4 (patch) | |
tree | 0eeb703224f6ae757ab409e4196bc4b0ceb50199 /generic/tclOO.c | |
parent | 67929efb233a934a2d625216ee8d3b1d8022d33e (diff) | |
download | tcl-6b4bc6bb8d46722088d73bd4a93f51e7fc65dbf4.zip tcl-6b4bc6bb8d46722088d73bd4a93f51e7fc65dbf4.tar.gz tcl-6b4bc6bb8d46722088d73bd4a93f51e7fc65dbf4.tar.bz2 |
[3d96b7076e] Prevent crashes when destroying an object's class inside a method call.
Diffstat (limited to 'generic/tclOO.c')
-rw-r--r-- | generic/tclOO.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/generic/tclOO.c b/generic/tclOO.c index 84bb85a..5fca220 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -951,6 +951,16 @@ ReleaseClassContents( } if (!IsRootClass(oPtr)) { FOREACH(instancePtr, clsPtr->instances) { + int j; + if (instancePtr->selfCls == clsPtr) { + instancePtr->flags |= CLASS_GONE; + } + for(j=0 ; j<instancePtr->mixins.num ; j++) { + Class *mixin = instancePtr->mixins.list[j]; + if (mixin == clsPtr) { + instancePtr->mixins.list[j] = NULL; + } + } if (instancePtr != NULL && !IsRoot(instancePtr)) { AddRef(instancePtr); } @@ -1131,12 +1141,14 @@ ObjectNamespaceDeleted( * methods on the object. */ - if (!IsRootObject(oPtr)) { + if (!IsRootObject(oPtr) && !(oPtr->flags & CLASS_GONE)) { TclOORemoveFromInstances(oPtr, oPtr->selfCls); } FOREACH(mixinPtr, oPtr->mixins) { - TclOORemoveFromInstances(oPtr, mixinPtr); + if (mixinPtr) { + TclOORemoveFromInstances(oPtr, mixinPtr); + } } if (i) { ckfree(oPtr->mixins.list); @@ -1908,13 +1920,13 @@ Tcl_CopyObjectInstance( */ FOREACH(mixinPtr, o2Ptr->mixins) { - if (mixinPtr != o2Ptr->selfCls) { + if (mixinPtr && mixinPtr != o2Ptr->selfCls) { TclOORemoveFromInstances(o2Ptr, mixinPtr); } } DUPLICATE(o2Ptr->mixins, oPtr->mixins, Class *); FOREACH(mixinPtr, o2Ptr->mixins) { - if (mixinPtr != o2Ptr->selfCls) { + if (mixinPtr && mixinPtr != o2Ptr->selfCls) { TclOOAddToInstances(o2Ptr, mixinPtr); } } |