summaryrefslogtreecommitdiffstats
path: root/generic/tclEncoding.c
diff options
context:
space:
mode:
authorferrieux <ferrieux@noemail.net>2009-11-16 17:38:07 (GMT)
committerferrieux <ferrieux@noemail.net>2009-11-16 17:38:07 (GMT)
commitd73969eaf6bc0dd28660e17cb09e021d4c0cb348 (patch)
tree1b93d42b56b88ab1862f7389658528282be889d6 /generic/tclEncoding.c
parentd32322b5bf45ec3a8502f075532a84eb10228f56 (diff)
downloadtcl-d73969eaf6bc0dd28660e17cb09e021d4c0cb348.zip
tcl-d73969eaf6bc0dd28660e17cb09e021d4c0cb348.tar.gz
tcl-d73969eaf6bc0dd28660e17cb09e021d4c0cb348.tar.bz2
(forward port) Fix [Bug 2891556] and improve test to detect similar manifestations in the future. Add tcltest support for finalization.
FossilOrigin-Name: 8fa4d0a5b9522d777f23908a685d9c58ccef2d34
Diffstat (limited to 'generic/tclEncoding.c')
-rw-r--r--generic/tclEncoding.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index 441e099..2188256 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclEncoding.c,v 1.66 2009/02/10 22:49:55 nijtmans Exp $
+ * RCS: @(#) $Id: tclEncoding.c,v 1.67 2009/11/16 17:38:08 ferrieux Exp $
*/
#include "tclInt.h"
@@ -844,6 +844,9 @@ FreeEncoding(
if (encodingPtr == NULL) {
return;
}
+ if (encodingPtr->refCount<=0) {
+ Tcl_Panic("FreeEncoding: refcount problem !!!");
+ }
encodingPtr->refCount--;
if (encodingPtr->refCount == 0) {
if (encodingPtr->freeProc != NULL) {
@@ -3385,11 +3388,24 @@ EscapeFreeProc(
if (dataPtr == NULL) {
return;
}
- subTablePtr = dataPtr->subTables;
- for (i = 0; i < dataPtr->numSubTables; i++) {
- FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
- subTablePtr++;
- }
+ /*
+ * The subTables should be freed recursively in normal operation but not
+ * during TclFinalizeEncodingSubsystem because they are also present as a
+ * weak reference in the toplevel encodingTable (ie they don't have a +1
+ * refcount for this), and unpredictable nuking order could remove them
+ * from under the following loop's feet [Bug 2891556].
+ *
+ * The encodingsInitialized flag, being reset on entry to TFES, can serve
+ * as a "not in finalization" test.
+ */
+ if (encodingsInitialized)
+ {
+ subTablePtr = dataPtr->subTables;
+ for (i = 0; i < dataPtr->numSubTables; i++) {
+ FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
+ subTablePtr++;
+ }
+ }
ckfree((char *) dataPtr);
}