summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2011-07-15 14:55:07 (GMT)
committerdgp <dgp@users.sourceforge.net>2011-07-15 14:55:07 (GMT)
commitf10d6c78e39de65787b2bb9652689feeca1b0b31 (patch)
tree5583d2b0d444df54a77c543be53f9bf644f1a6af
parent8e85c7b1303dbaf54284cc641b20f6a77d7de502 (diff)
downloadtcl-f10d6c78e39de65787b2bb9652689feeca1b0b31.zip
tcl-f10d6c78e39de65787b2bb9652689feeca1b0b31.tar.gz
tcl-f10d6c78e39de65787b2bb9652689feeca1b0b31.tar.bz2
3357771 Prevent circular references in values with ByteCode intreps.
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclCompile.c14
2 files changed, 19 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 11c28f6..80ca332 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-07-15 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompile.c: [Bug 467523, 3357771] Prevent circular
+ references in values with ByteCode intreps. They can lead to
+ memory leaks.
+
2011-07-14 Donal K. Fellows <dkf@users.sf.net>
* generic/tclOOCall.c (TclOORenderCallChain): [Bug 3365156]: Remove
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 18679b2..8aedf95 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -2443,7 +2443,19 @@ TclInitByteCodeObj(
p += TCL_ALIGN(codeBytes); /* align object array */
codePtr->objArrayPtr = (Tcl_Obj **) p;
for (i = 0; i < numLitObjects; i++) {
- codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr;
+ if (objPtr == envPtr->literalArrayPtr[i].objPtr) {
+ /*
+ * Prevent circular reference where the bytecode intrep of
+ * a value contains a literal which is that same value.
+ * If this is allowed to happen, refcount decrements may not
+ * reach zero, and memory may leak. Bugs 467523, 3357771
+ */
+ codePtr->objArrayPtr[i] = Tcl_DuplicateObj(objPtr);
+ Tcl_IncrRefCount(codePtr->objArrayPtr[i]);
+ Tcl_DecrRefCount(objPtr);
+ } else {
+ codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr;
+ }
}
p += TCL_ALIGN(objArrayBytes); /* align exception range array */