diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | generic/tclIO.c | 20 | ||||
-rw-r--r-- | tests/io.test | 15 |
3 files changed, 48 insertions, 2 deletions
@@ -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 |