Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.428
diff -u -r1.428 tclExecute.c
--- generic/tclExecute.c	25 Feb 2009 14:56:07 -0000	1.428
+++ generic/tclExecute.c	19 Mar 2009 19:54:25 -0000
@@ -2468,16 +2468,16 @@
 	 */
 
 	if (onlyb) {
-	    for (currPtr = &OBJ_AT_DEPTH(opnd-2); currPtr <= &OBJ_AT_TOS;
-		    currPtr++) {
+	    for (currPtr = &OBJ_AT_DEPTH(opnd-2); 
+		    appendLen >= 0 && currPtr <= &OBJ_AT_TOS; currPtr++) {
 		if ((*currPtr)->bytes != tclEmptyStringRep) {
 		    Tcl_GetByteArrayFromObj(*currPtr, &length);
 		    appendLen += length;
 		}
 	    }
 	} else {
-	    for (currPtr = &OBJ_AT_DEPTH(opnd-2); currPtr <= &OBJ_AT_TOS;
-		    currPtr++) {
+	    for (currPtr = &OBJ_AT_DEPTH(opnd-2);
+		    appendLen >= 0 && currPtr <= &OBJ_AT_TOS; currPtr++) {
 		bytes = TclGetStringFromObj(*currPtr, &length);
 		if (bytes != NULL) {
 		    appendLen += length;
@@ -2485,6 +2485,10 @@
 	    }
 	}
 
+	if (appendLen < 0) {
+	    Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+	}
+
 	/*
 	 * If nothing is to be appended, just return the first object by
 	 * dropping all the others from the stack; this saves both the
@@ -2509,6 +2513,10 @@
 	objResultPtr = OBJ_AT_DEPTH(opnd-1);
 	if (!onlyb) {
 	    bytes = TclGetStringFromObj(objResultPtr, &length);
+	    if (length + appendLen < 0) {
+		Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
+			INT_MAX);
+	    }
 #if !TCL_COMPILE_DEBUG
 	    if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
 		TclFreeIntRep(objResultPtr);
@@ -2541,6 +2549,10 @@
 	    *p = '\0';
 	} else {
 	    bytes = (char *) Tcl_GetByteArrayFromObj(objResultPtr, &length);
+	    if (length + appendLen < 0) {
+		Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
+			INT_MAX);
+	    }
 #if !TCL_COMPILE_DEBUG
 	    if (!Tcl_IsShared(objResultPtr)) {
 		bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,
