summaryrefslogtreecommitdiffstats
path: root/generic/tclObj.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-03-11 17:37:15 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-03-11 17:37:15 (GMT)
commitedadbbc515cfa8428b349a8ec75c37a386080d98 (patch)
tree70ddeff3adae0fc6e6c8dc1d29a5e7eac704a78d /generic/tclObj.c
parent950d5f67e55c88bd2094c93e236c405ec3fde818 (diff)
downloadtcl-edadbbc515cfa8428b349a8ec75c37a386080d98.zip
tcl-edadbbc515cfa8428b349a8ec75c37a386080d98.tar.gz
tcl-edadbbc515cfa8428b349a8ec75c37a386080d98.tar.bz2
Greater protection against double TclFreeObj() calls in TCL_MEM_DEBUG mode.
Diffstat (limited to 'generic/tclObj.c')
-rw-r--r--generic/tclObj.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 24b818b..96a4082 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -1322,9 +1322,21 @@ TclFreeObj(
ObjInitDeletionContext(context);
+ /*
+ * Check for a double free of the same value. This is slightly tricky
+ * because it is customary to free a Tcl_Obj when its refcount falls
+ * either from 1 to 0, or from 0 to -1. Falling from -1 to -2, though,
+ * and so on, is always a sign of a botch in the caller.
+ */
if (objPtr->refCount < -1) {
Tcl_Panic("Reference count for %lx was negative", objPtr);
}
+ /*
+ * Now, in case we just approved drop from 1 to 0 as acceptable, make
+ * sure we do not accept a second free when falling from 0 to -1.
+ * Skip that possibility so any double free will trigger the panic.
+ */
+ objPtr->refCount = -1;
/* Invalidate the string rep first so we can use the bytes value
* for our pointer chain, and signal an obj deletion (as opposed