summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--generic/tclIOCmd.c15
2 files changed, 20 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 707f919..4d33b26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2002-01-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * generic/tclIOCmd.c (Tcl_GetsObjCmd): Fixed bug #504642 as
+ reported by Brian Griffin <bgriffin@users.sourceforge.net>,
+ using his patch. Before the patch the generic I/O layer held an
+ unannounced reference to the interp result to store the read
+ line into. This unfortunately has disastrous results if the
+ channel driver executes a tcl script to perform its operation,
+ this freeing the interp result. In that case we are
+ dereferencing essentially a dangling reference. It is not truly
+ dangling because the object is in the free list, but this only
+ causes us to smash the free list and have the error occur later
+ somewhere else. The patch simply creates a new object for the
+ line and later sets it into the interp result when we are done
+ with reading.
+
2002-01-16 Mo DeJong <mdejong@users.sourceforge.net>
* unix/tcl.m4 (SC_LOAD_TCLCONFIG):
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index a14c9f1..bc61a94 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.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: tclIOCmd.c,v 1.11 2002/01/17 04:37:33 dgp Exp $
+ * RCS: @(#) $Id: tclIOCmd.c,v 1.12 2002/01/17 20:35:22 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -245,16 +245,7 @@ Tcl_GetsObjCmd(dummy, interp, objc, objv)
return TCL_ERROR;
}
- if (objc == 3) {
- /*
- * Variable gets line, interp get bytecount.
- */
-
- linePtr = Tcl_NewObj();
- }
- else {
- linePtr = Tcl_GetObjResult(interp);
- }
+ linePtr = Tcl_NewObj();
lineLen = Tcl_GetsObj(chan, linePtr);
if (lineLen < 0) {
@@ -278,6 +269,8 @@ Tcl_GetsObjCmd(dummy, interp, objc, objv)
resultPtr = Tcl_GetObjResult(interp);
Tcl_SetIntObj(resultPtr, lineLen);
return TCL_OK;
+ } else {
+ Tcl_SetObjResult(interp, linePtr);
}
return TCL_OK;
}