diff options
author | andreas_kupries <akupries@shaw.ca> | 2002-01-21 20:38:06 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2002-01-21 20:38:06 (GMT) |
commit | 50d8ac09b879ca8d7d65a69eb214b4a200061ab3 (patch) | |
tree | b55eec77eccf5f16f69e282f66eca0af288d3ee5 | |
parent | 5555aa01aae3d96fdff9f094f83516fdee086727 (diff) | |
download | tcl-50d8ac09b879ca8d7d65a69eb214b4a200061ab3.zip tcl-50d8ac09b879ca8d7d65a69eb214b4a200061ab3.tar.gz tcl-50d8ac09b879ca8d7d65a69eb214b4a200061ab3.tar.bz2 |
* 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.
-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 |