Attachment "escape2times.patch" to
ticket [1516109fff]
added by
mdejong
2006-07-03 09:57:15.
2006-07-02 Mo DeJong <[email protected]>
* generic/tclEncoding.c (EscapeFromUtfProc):
Clear the TCL_ENCODING_END flag when end
bytes are written. This fix keep this method
from writing escape bytes for an encoding
like iso2022-jp multiple times when the
escape byte overlap with the end of the
IO buffer.
* tests/io.test: Add test case for escape
byte overlap case.
Index: generic/tclEncoding.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclEncoding.c,v
retrieving revision 1.42
diff -u -r1.42 tclEncoding.c
--- generic/tclEncoding.c 5 Apr 2006 00:18:50 -0000 1.42
+++ generic/tclEncoding.c 3 Jul 2006 02:36:07 -0000
@@ -2973,7 +2973,7 @@
if (flags & TCL_ENCODING_START) {
state = 0;
- if (dst + dataPtr->initLen > dstEnd) {
+ if ((dst + dataPtr->initLen) > dstEnd) {
*srcReadPtr = 0;
*dstWrotePtr = 0;
return TCL_CONVERT_NOSPACE;
@@ -3081,7 +3081,17 @@
if ((result == TCL_OK) && (flags & TCL_ENCODING_END)) {
unsigned int len = dataPtr->subTables[0].sequenceLen;
- if (dst + dataPtr->finalLen + (state?len:0) > dstEnd) {
+ /*
+ * Certain encodings like iso2022-jp need to write
+ * an escape sequence after all characters have
+ * been converted. This logic checks that enough
+ * room is available in the buffer for the escape bytes.
+ * The TCL_ENCODING_END flag is cleared after a final
+ * escape sequence has been added to the buffer so
+ * that another call to this method does not attempt
+ * to append escape bytes a second time.
+ */
+ if ((dst + dataPtr->finalLen + (state?len:0)) > dstEnd) {
result = TCL_CONVERT_NOSPACE;
} else {
if (state) {
@@ -3092,6 +3102,7 @@
memcpy((VOID *) dst, (VOID *) dataPtr->final,
(size_t) dataPtr->finalLen);
dst += dataPtr->finalLen;
+ state &= ~TCL_ENCODING_END;
}
}
Index: tests/io.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/io.test,v
retrieving revision 1.71
diff -u -r1.71 io.test
--- tests/io.test 21 Mar 2006 11:12:29 -0000 1.71
+++ tests/io.test 3 Jul 2006 02:36:31 -0000
@@ -117,6 +117,66 @@
contents $path(test2)
} " \x1b\$B\$O\x1b(B"
+test io-1.9 {Tcl_WriteChars: WriteChars} {
+ # When closing a channel with an encoding that appends
+ # escape bytes, check for the case where the escape
+ # bytes overflow the current IO buffer. The bytes
+ # should be moved into a new buffer.
+
+ set data "1234567890 [format %c 12399]"
+
+ set sizes [list]
+
+ # With default buffer size
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size equal to the length
+ # of the data, the escape bytes would
+ # go into the next buffer.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 16
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that is large enough
+ # to hold 1 byte of escaped data, but
+ # not all 3. This should not write
+ # the escape bytes to the first buffer
+ # and then again to the second buffer.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 17
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that can hold 2 out of
+ # 3 bytes of escaped data.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 18
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ # With buffer size that can hold all the
+ # data and escape bytes.
+
+ set f [open $path(test2) w]
+ fconfigure $f -encoding iso2022-jp -buffersize 19
+ puts -nonewline $f $data
+ close $f
+ lappend sizes [file size $path(test2)]
+
+ set sizes
+} {19 19 19 19 19}
+
test io-2.1 {WriteBytes} {
# loop until all bytes are written