diff options
author | stanton <stanton> | 1998-12-03 04:57:14 (GMT) |
---|---|---|
committer | stanton <stanton> | 1998-12-03 04:57:14 (GMT) |
commit | d201ec56319370f65f4d74489ad7e0955b1489d8 (patch) | |
tree | b576a29ee54b57d2f71ce06495e95fbec709c088 | |
parent | 6e3a2c4e2db756c0205eb020cf1041e6e20efc00 (diff) | |
download | tcl-d201ec56319370f65f4d74489ad7e0955b1489d8.zip tcl-d201ec56319370f65f4d74489ad7e0955b1489d8.tar.gz tcl-d201ec56319370f65f4d74489ad7e0955b1489d8.tar.bz2 |
* generic/tclIO.c (WriteBytes, WriteChars): Fixed so extraneous
flushes do not happen in line mode.
(TranslateOutputEOL): Made translation more efficient in line mode
and fixed a buffer overflow bug in CRLF translation. [Bug: 887]
-rw-r--r-- | generic/tclIO.c | 41 | ||||
-rw-r--r-- | tests/io.test | 44 |
2 files changed, 57 insertions, 28 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index a297b22..65c4704 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.1.2.4 1998/12/02 03:13:30 stanton Exp $ + * RCS: @(#) $Id: tclIO.c,v 1.1.2.5 1998/12/03 04:57:14 stanton Exp $ */ #include "tclInt.h" @@ -2405,6 +2405,7 @@ WriteBytes(chanPtr, src, srcLen) total += dstLen; src += toWrite; srcLen -= toWrite; + sawLF = 0; } return total; } @@ -2561,6 +2562,7 @@ WriteChars(chanPtr, src, srcLen) total += dstWrote; stage += stageRead; stageLen -= stageRead; + sawLF = 0; } } return total; @@ -2621,6 +2623,7 @@ TranslateOutputEOL(chanPtr, dst, src, dstLenPtr, srcLenPtr) * On exit, the number of bytes read from * the source buffer. */ { + char *dstEnd; int srcLen, newlineFound; newlineFound = 0; @@ -2628,28 +2631,23 @@ TranslateOutputEOL(chanPtr, dst, src, dstLenPtr, srcLenPtr) switch (chanPtr->outputTranslation) { case TCL_TRANSLATE_LF: { - memcpy((VOID *) dst, (VOID *) src, (size_t) srcLen); - if (chanPtr->flags & CHANNEL_LINEBUFFERED) { - char *dstEnd; - - for (dstEnd = dst + srcLen; dst < dstEnd; dst++) { - if (*dst == '\n') { - newlineFound = 1; - break; - } + for (dstEnd = dst + srcLen; dst < dstEnd; ) { + if (*src == '\n') { + newlineFound = 1; } + *dst++ = *src++; } *dstLenPtr = srcLen; break; } case TCL_TRANSLATE_CR: { - char *dstEnd; - - memcpy((VOID *) dst, (VOID *) src, (size_t) srcLen); - for (dstEnd = dst + srcLen; dst < dstEnd; dst++) { - if (*dst == '\n') { - *dst = '\r'; + for (dstEnd = dst + srcLen; dst < dstEnd;) { + if (*src == '\n') { + *dst++ = '\r'; newlineFound = 1; + src++; + } else { + *dst++ = *src++; } } *dstLenPtr = srcLen; @@ -2664,7 +2662,7 @@ TranslateOutputEOL(chanPtr, dst, src, dstLenPtr, srcLenPtr) * output buffer. */ - char *dstStart, *dstMax, *dstEnd; + char *dstStart, *dstMax; CONST char *srcStart; dstStart = dst; @@ -2672,7 +2670,12 @@ TranslateOutputEOL(chanPtr, dst, src, dstLenPtr, srcLenPtr) srcStart = src; - for (dstEnd = dst + srcLen; dst < dstEnd; ) { + if (srcLen < *dstLenPtr) { + dstEnd = dst + srcLen; + } else { + dstEnd = dst + *dstLenPtr; + } + while (dst < dstEnd) { if (*src == '\n') { if (dstEnd < dstMax) { dstEnd++; @@ -7597,5 +7600,3 @@ SetBlockMode(interp, chanPtr, mode) } return TCL_OK; } - - diff --git a/tests/io.test b/tests/io.test index 9b532ba..767570c 100644 --- a/tests/io.test +++ b/tests/io.test @@ -11,7 +11,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.1.2.5 1998/12/02 23:46:49 stanton Exp $ +# RCS: @(#) $Id: io.test,v 1.1.2.6 1998/12/03 04:57:15 stanton Exp $ if {[string compare test [info procs test]] == 1} then {source defs} @@ -181,6 +181,15 @@ test io-2.3 {WriteBytes: flush on line} { close $f set x } "\r\n12" +test io-2.4 {WriteBytes: reset sawLF after each buffer} { + set f [open test1 w] + fconfigure $f -encoding binary -buffering line -translation lf \ + -buffersize 16 + puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz" + set x [list [contents test1]] + close $f + lappend x [contents test1] +} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"] test io-3.1 {WriteChars: compatibility with WriteBytes} { # loop until all bytes are written @@ -267,6 +276,15 @@ test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} { close $f lappend x [contents test1] } [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"] +test io-3.8 {WriteChars: reset sawLF after each buffer} { + set f [open test1 w] + fconfigure $f -encoding ascii -buffering line -translation lf \ + -buffersize 16 + puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz" + set x [list [contents test1]] + close $f + lappend x [contents test1] +} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"] test io-4.1 {TranslateOutputEOL: lf} { # search for \n @@ -310,6 +328,15 @@ test io-4.4 {TranslateOutputEOL: crlf} { close $f lappend x [contents test1] } [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"] +test io-4.5 {TranslateOutputEOL: crlf} { + # Check for overflow of the destination buffer + + set f [open test1 w] + fconfigure $f -translation crlf -buffersize 12 + puts -nonewline $f "12345678901\n456789012345678901234" + close $f + set x [contents test1] +} "12345678901\r\n456789012345678901234" test io-5.1 {CheckFlush: not full} { set f [open test1 w] @@ -1063,7 +1090,7 @@ test io-7.4 {FilterInputBytes: recover from split up character} {stdio} { vwait x fconfigure $f -encoding binary -blocking 1 puts $f "\x51\x82\x52" - fconfigure $f -encoding shiftjis -blocking 0 + fconfigure $f -encoding shiftjis vwait x close $f set x @@ -1344,20 +1371,19 @@ test io-12.4 {ReadChars: split-up char} {stdio} { vwait x fconfigure $f -encoding binary -blocking 1 puts -nonewline $f "\x7b" + after 500 ;# Give the cat process time to catch up fconfigure $f -encoding shiftjis -blocking 0 vwait x close $f set x } [list "123456789012345" 1 "\u672c" 0] test io-12.5 {ReadChars: fileevents on partial characters} {stdio} { - set f [open test1 w] - puts $f { + makeFile { fconfigure stdout -encoding binary -buffering none gets stdin; puts -nonewline "\xe7" gets stdin; puts -nonewline "\x89" gets stdin; puts -nonewline "\xa6" - } - close $f + } test1 set f [open "|[list $tcltest test1]" r+] fileevent $f readable { lappend x [read $f] @@ -1459,10 +1485,12 @@ test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio} { set x {} puts -nonewline $f "abcdefghj\r" - vwait x + after 100 {set y ok} + vwait y puts -nonewline $f "\n01234" - vwait x + after 100 {set y ok} + vwait y close $f set x |