summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstanton <stanton>1998-12-03 04:57:14 (GMT)
committerstanton <stanton>1998-12-03 04:57:14 (GMT)
commitd201ec56319370f65f4d74489ad7e0955b1489d8 (patch)
treeb576a29ee54b57d2f71ce06495e95fbec709c088
parent6e3a2c4e2db756c0205eb020cf1041e6e20efc00 (diff)
downloadtcl-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.c41
-rw-r--r--tests/io.test44
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