2003-02-28  Mo DeJong  <mdejong@users.sourceforge.net>

	* generic/tclIO.c (ReadBytes, ReadChars):
	Handle the case of en empty input buffer explicitly.
	This can happen when a cr appears at the end of an
	input buffer that is in crlf or auto mode. A flag
	is set to indicate that a lf at the start of the
	next buffer means that a single lf should be added.
	The problem in ReadBytes and ReadChars is that
	they assume that the buffer will be non-empty.
	It appears as though ReadBytes and ReadChars
	still function properly in this case, so the
	additional checks added here serve to make handling
	of this case more clear.

Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.61
diff -u -r1.61 tclIO.c
--- generic/tclIO.c	19 Feb 2003 01:04:57 -0000	1.61
+++ generic/tclIO.c	1 Mar 2003 02:36:09 -0000
@@ -4531,6 +4538,7 @@
     srcLen = bufPtr->nextAdded - bufPtr->nextRemoved;
 
     toRead = bytesToRead;
+
     if ((unsigned) toRead > (unsigned) srcLen) {
 	toRead = srcLen;
     }
@@ -4564,6 +4572,15 @@
 	toRead--;
     }
 
+    /*
+     * No need to go any farther when processing an empty buffer
+     * since a CR at the end of a previous buffer was handled above.
+     */
+
+    if (srcLen == 0) {
+	return -1;
+    }
+
     srcRead = srcLen;
     dstWrote = toRead;
     if (TranslateInputEOL(statePtr, dst, src, &dstWrote, &srcRead) != 0) {
@@ -4689,10 +4706,12 @@
 	 */
 
 	statePtr->flags &= ~INPUT_NEED_NL;
-	Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
-		statePtr->inputEncodingFlags, &statePtr->inputEncodingState,
-		dst, TCL_UTF_MAX + 1, &srcRead, &dstWrote, &numChars);
-	if ((dstWrote > 0) && (*dst == '\n')) {
+	if (srcLen > 0) {
+	    Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
+		    statePtr->inputEncodingFlags, &statePtr->inputEncodingState,
+		    dst, TCL_UTF_MAX + 1, &srcRead, &dstWrote, &numChars);
+	}
+	if ((srcLen > 0) && (dstWrote > 0) && (*dst == '\n')) {
 	    /*
 	     * The next char was a '\n'.  Consume it and produce a '\n'.
 	     */
@@ -4710,6 +4729,15 @@
         return 1;
     }
 
+    /*
+     * No need to go any farther when processing an empty buffer
+     * since a CR at the end of a previous buffer was handled above.
+     */
+
+    if (srcLen == 0) {
+	return -1;
+    }
+
     Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen,
 	    statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst,
 	    dstNeeded + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
@@ -4724,23 +4752,15 @@
 	
 	nextPtr = bufPtr->nextPtr;
 	if (nextPtr == NULL) {
-	    if (srcLen > 0) {
-	        /*
-		 * There isn't enough data in the buffers to complete the next
-		 * character, so we need to wait for more data before the next
-		 * file event can be delivered.
-		 *
-		 * SF #478856.
-		 *
-		 * The exception to this is if the input buffer was
-		 * completely empty before we tried to convert its
-		 * contents. Nothing in, nothing out, and no incomplete
-		 * character data. The conversion before the current one
-		 * was complete.
-		 */
+	    /*
+	     * There isn't enough data in the buffers to complete the next
+	     * character, so we need to wait for more data before the next
+	     * file event can be delivered.
+	     *
+	     * SF #478856.
+	     */
 
-	        statePtr->flags |= CHANNEL_NEED_MORE_DATA;
-	    }
+	    statePtr->flags |= CHANNEL_NEED_MORE_DATA;
 	    return -1;
 	}
 	nextPtr->nextRemoved -= srcLen;
