summaryrefslogtreecommitdiffstats
path: root/generic/tclOO.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2015-11-21 22:22:49 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2015-11-21 22:22:49 (GMT)
commit6b4bc6bb8d46722088d73bd4a93f51e7fc65dbf4 (patch)
tree0eeb703224f6ae757ab409e4196bc4b0ceb50199 /generic/tclOO.c
parent67929efb233a934a2d625216ee8d3b1d8022d33e (diff)
downloadtcl-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.c20
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);
}
}