summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2003-07-18 23:35:37 (GMT)
committerdgp <dgp@users.sourceforge.net>2003-07-18 23:35:37 (GMT)
commitb48c6ea6c1f6c8a6cf870c15799cf33cb88d0b7d (patch)
tree0580485f72aa65d80f29849145a21e23f8252d07 /generic/tclBasic.c
parent7265d5487c6af7a62eb6a02dbb439f996b49e826 (diff)
downloadtcl-b48c6ea6c1f6c8a6cf870c15799cf33cb88d0b7d.zip
tcl-b48c6ea6c1f6c8a6cf870c15799cf33cb88d0b7d.tar.gz
tcl-b48c6ea6c1f6c8a6cf870c15799cf33cb88d0b7d.tar.bz2
* generic/tclBasic.c: Corrected several instances of unsafe
* generic/tclCompile.c: truncation of UTF-8 strings that might * generic/tclProc.c: break apart a multi-byte character. * library/init.tcl: [Bug 760872] * tests/init.test:
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 80f5bda..629293f 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBasic.c,v 1.75.2.4 2003/06/10 19:58:34 msofer Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.75.2.5 2003/07/18 23:35:38 dgp Exp $
*/
#include "tclInt.h"
@@ -3304,6 +3304,14 @@ Tcl_LogCommandInfo(interp, script, command, length)
length = 150;
ellipsis = "...";
}
+ while ( (command[length] & 0xC0) == 0x80 ) {
+ /*
+ * Back up truncation point so that we don't truncate in the
+ * middle of a multi-byte character (in UTF-8)
+ */
+ length--;
+ ellipsis = "...";
+ }
if (!(iPtr->flags & ERR_IN_PROGRESS)) {
sprintf(buffer, "\n while executing\n\"%.*s%s\"",
length, command, ellipsis);
@@ -4562,8 +4570,7 @@ TclObjInvoke(interp, objc, objv, flags)
int localObjc; /* Used to invoke "unknown" if the */
Tcl_Obj **localObjv = NULL; /* command is not found. */
register int i;
- int length, result;
- char *bytes;
+ int result;
if (interp == (Tcl_Interp *) NULL) {
return TCL_ERROR;
@@ -4656,29 +4663,41 @@ TclObjInvoke(interp, objc, objv, flags)
if ((result == TCL_ERROR)
&& ((flags & TCL_INVOKE_NO_TRACEBACK) == 0)
&& ((iPtr->flags & ERR_ALREADY_LOGGED) == 0)) {
- Tcl_DString ds;
+ Tcl_Obj *msg;
- Tcl_DStringInit(&ds);
if (!(iPtr->flags & ERR_IN_PROGRESS)) {
- Tcl_DStringAppend(&ds, "\n while invoking\n\"", -1);
+ msg = Tcl_NewStringObj("\n while invoking\n\"", -1);
} else {
- Tcl_DStringAppend(&ds, "\n invoked from within\n\"", -1);
+ msg = Tcl_NewStringObj("\n invoked from within\n\"", -1);
}
+ Tcl_IncrRefCount(msg);
for (i = 0; i < objc; i++) {
- bytes = Tcl_GetStringFromObj(objv[i], &length);
- Tcl_DStringAppend(&ds, bytes, length);
- if (i < (objc - 1)) {
- Tcl_DStringAppend(&ds, " ", -1);
- } else if (Tcl_DStringLength(&ds) > 100) {
- Tcl_DStringSetLength(&ds, 100);
- Tcl_DStringAppend(&ds, "...", -1);
- break;
- }
+ CONST char *bytes;
+ int length;
+
+ Tcl_AppendObjToObj(msg, objv[i]);
+ bytes = Tcl_GetStringFromObj(msg, &length);
+ if (length > 100) {
+ /*
+ * Back up truncation point so that we don't truncate
+ * in the middle of a multi-byte character.
+ */
+ length = 100;
+ while ( (bytes[length] & 0xC0) == 0x80 ) {
+ length--;
+ }
+ Tcl_SetObjLength(msg, length);
+ Tcl_AppendToObj(msg, "...", -1);
+ break;
+ }
+ if (i != (objc - 1)) {
+ Tcl_AppendToObj(msg, " ", -1);
+ }
}
-
- Tcl_DStringAppend(&ds, "\"", -1);
- Tcl_AddObjErrorInfo(interp, Tcl_DStringValue(&ds), -1);
- Tcl_DStringFree(&ds);
+
+ Tcl_AppendToObj(msg, "\"", -1);
+ Tcl_AddObjErrorInfo(interp, Tcl_GetString(msg), -1);
+ Tcl_DecrRefCount(msg);
iPtr->flags &= ~ERR_ALREADY_LOGGED;
}