summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--generic/tclIO.c20
-rw-r--r--tests/io.test15
3 files changed, 48 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index e52c431..986a9b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2002-01-21 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * generic/tclIO.c (WriteChars): Fix for SF #506297, reported by
+ Martin Forssen <ruric@users.sourceforge.net>. The encoding
+ chosen in the script exposing the bug writes out three intro
+ characters when TCL_ENCODING_START is set, but does not consume
+ any input as TCL_ENCODING_END is cleared. As some output was
+ generated the enclosing loop calls UtfToExternal again, again
+ with START set. Three more characters in the out and still no
+ use of input ... To break this infinite loop we remove
+ TCL_ENCODING_START from the set of flags after the first call
+ (no condition is required, the later calls remove an unset flag,
+ which is a no-op). This causes the subsequent calls to
+ UtfToExternal to consume and convert the actual input.
+
2002-01-21 Don Porter <dgp@users.sourceforge.net>
* generic/tcl.decls (Tcl_TraceCommand,Tcl_UntraceCommand,
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 8b67405..d341261 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.c,v 1.47 2002/01/17 04:37:33 dgp Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.48 2002/01/21 20:38:06 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -3129,6 +3129,24 @@ WriteChars(chanPtr, src, srcLen)
Tcl_UtfToExternal(NULL, encoding, stage, stageLen, flags,
&statePtr->outputEncodingState, dst,
dstLen + BUFFER_PADDING, &stageRead, &dstWrote, NULL);
+
+ /* Fix for SF #506297, reported by Martin Forssen <ruric@users.sourceforge.net>.
+ *
+ * The encoding chosen in the script exposing the bug
+ * writes out three intro characters when
+ * TCL_ENCODING_START is set, but does not consume any
+ * input as TCL_ENCODING_END is cleared. As some output
+ * was generated the enclosing loop calls UtfToExternal
+ * again, again with START set. Three more characters in
+ * the out and still no use of input ... To break this
+ * infinite loop we remove TCL_ENCODING_START from the set
+ * of flags after the first call (no condition is
+ * required, the later calls remove an unset flag, which
+ * is a no-op). This causes the subsequent calls to
+ * UtfToExternal to consume and convert the actual input.
+ */
+
+ flags &= ~TCL_ENCODING_START;
if (stageRead + dstWrote == 0) {
/*
* We have an incomplete UTF-8 character at the end of the
diff --git a/tests/io.test b/tests/io.test
index 2d535e6..62cee1f 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -12,7 +12,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: io.test,v 1.22 2001/12/17 22:55:51 andreas_kupries Exp $
+# RCS: @(#) $Id: io.test,v 1.23 2002/01/21 20:38:06 andreas_kupries Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -85,6 +85,19 @@ test io-1.7 {Tcl_WriteChars: WriteChars} {
close $f
contents test1
} "a\x93\xe1\x00"
+test io-1.8 {Tcl_WriteChars: WriteChars} {
+ # This test written for SF bug #506297.
+ #
+ # Executing this test without the fix for the referenced bug
+ # applied to tcl will cause tcl, more specifically WriteChars, to
+ # go into an infinite loop.
+
+ set f [open test2 w]
+ fconfigure $f -encoding iso2022-jp
+ puts -nonewline $f [format %s%c [string repeat " " 4] 12399]
+ close $f
+ contents test2
+} "\x1b(B \x1b\$@\$O"
test io-2.1 {WriteBytes} {
# loop until all bytes are written