Tcl Source Code

Artifact [36e3e5cd42]
Login

Artifact 36e3e5cd424de5539897227b819c1417fc3ed35d:

Attachment "tclIO.diff" to ticket [1399062fff] added by coldstore 2006-01-07 14:20:08.
Index: tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.94
diff -u -r1.94 tclIO.c
--- tclIO.c	26 Aug 2005 22:11:16 -0000	1.94
+++ tclIO.c	27 Sep 2005 04:45:34 -0000
@@ -3715,16 +3715,17 @@
 /*
  *---------------------------------------------------------------------------
  *
- * Tcl_GetsObj --
+ * Tcl_GetsObjLimit --
  *
- *	Accumulate input from the input channel until end-of-line or
- *	end-of-file has been seen.  Bytes read from the input channel are
- *	converted to UTF-8 using the encoding specified by the channel.
+ *	Accumulate length-limited input from the input channel until
+ *	end-of-line or end-of-file has been seen.
+ *	Bytes read from the input channel are converted to UTF-8 using
+ *	the encoding specified by the channel.
  *
  * Results:
  *	Number of characters accumulated in the object or -1 if error,
- *	blocked, or EOF.  If -1, use Tcl_GetErrno() to retrieve the POSIX
- *	error code for the error or condition that occurred.
+ *	blocked, limit exceeded, or EOF.  If -1, use Tcl_GetErrno() to retrieve
+ *	the POSIX error code for the error or condition that occurred.
  *
  * Side effects:
  *	Consumes input from the channel.
@@ -3736,11 +3737,12 @@
  */
 
 int
-Tcl_GetsObj(chan, objPtr)
-    Tcl_Channel chan;		/* Channel from which to read. */
-    Tcl_Obj *objPtr;		/* The line read will be appended to this
-				 * object as UTF-8 characters. */
-{
+Tcl_GetsObjLimit(
+    Tcl_Channel chan,/* Channel from which to read. */
+    Tcl_Obj *objPtr,	/* The line read will be appended to this
+		 * object as UTF-8 characters. */
+    int limit		/* line length limit, 0 if none */
+    ) {
     GetsState gs;
     Channel *chanPtr = (Channel *) chan;
     ChannelState *statePtr = chanPtr->state;	/* state info for channel */
@@ -3749,6 +3751,7 @@
     Tcl_Encoding encoding;
     char *dst, *dstEnd, *eol, *eof;
     Tcl_EncodingState oldState;
+    int limited = 0;
 
     /*
      * This operation should occur at the top of a channel stack.
@@ -3814,6 +3817,19 @@
 		goto restore;
 	    }
 	    dstEnd = dst + gs.bytesWrote;
+
+	    if (limit > 0) {
+		/*
+		 * Remember if limit is exceeded
+		 * but continue to check, as
+		 * EOL might be before the limit
+		 */
+		if ((dstEnd - objPtr->bytes) > limit+1) {
+		    dstEnd = objPtr->bytes + limit+1;
+		    limited = 1;
+		}
+	    }
+
 	}
 
 	/*
@@ -3954,6 +3970,18 @@
 	    statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
 	    statePtr->inputEncodingFlags |= TCL_ENCODING_END;
 	}
+
+	if (limited) {
+	    /* character limit exceeded. */
+	    skip = 0;
+	    eol = dstEnd;
+	    statePtr->flags &= ~CHANNEL_BLOCKED;
+	    Tcl_SetChannelError(
+		chan,
+		Tcl_NewStringObj("{gets -limit exceeded}",-1));
+	    goto restore;
+	}
+
 	if (statePtr->flags & CHANNEL_EOF) {
 	    skip = 0;
 	    eol = dstEnd;
@@ -4047,6 +4075,36 @@
 /*
  *---------------------------------------------------------------------------
  *
+ * Tcl_GetsObj --
+ *
+ *	Accumulate input from the input channel until end-of-line or
+ *	end-of-file has been seen.  Bytes read from the input channel are
+ *	converted to UTF-8 using the encoding specified by the channel.
+ *
+ * Results:
+ *	Number of characters accumulated in the object or -1 if error,
+ *	blocked, limit exceeded, or EOF.  If -1, use Tcl_GetErrno() to retrieve
+ *	the POSIX error code for the error or condition that occurred.
+ *
+ * Side effects:
+ *	Consumes input from the channel.
+ *
+ *	On reading EOF, leave channel pointing at EOF char.  On reading EOL,
+ *	leave channel pointing after EOL, but don't return EOL in dst buffer.
+ *
+ *---------------------------------------------------------------------------
+ */
+int
+Tcl_GetsObj (
+    Tcl_Channel chan,/* Channel from which to read. */
+    Tcl_Obj *objPtr	/* The line read will be appended to this
+		 * object as UTF-8 characters. */
+    ) {
+    return Tcl_GetsObjLimit (chan, objPtr, 0);
+}
+/*
+ *---------------------------------------------------------------------------
+ *
  * FilterInputBytes --
  *
  *	Helper function for Tcl_GetsObj.  Produces UTF-8 characters from raw