From 459a5494e274847d966e5e67b89ab6a2d73e786b Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 6 Jun 2011 21:36:30 +0000 Subject: Second draft of fix for 2546087. This one is better since it avoids even the appearance that the "identity" encoding is something useful. :) Both fixes are fragile to [chan configure]s that set the stdout/err encoding to something incompatible. This is a fragility inherent in the design of Tcl_Channels (see RFE 3312630) --- generic/tkConsole.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/generic/tkConsole.c b/generic/tkConsole.c index ae8e1a9..f996361 100644 --- a/generic/tkConsole.c +++ b/generic/tkConsole.c @@ -298,7 +298,7 @@ Tk_InitConsoleChannels( Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); Tcl_SetChannelOption(NULL, consoleChannel, - "-encoding", "identity"); + "-encoding", "utf-8"); } Tcl_SetStdChannel(consoleChannel, TCL_STDOUT); Tcl_RegisterChannel(NULL, consoleChannel); @@ -317,7 +317,7 @@ Tk_InitConsoleChannels( Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); Tcl_SetChannelOption(NULL, consoleChannel, - "-encoding", "identity"); + "-encoding", "utf-8"); } Tcl_SetStdChannel(consoleChannel, TCL_STDERR); Tcl_RegisterChannel(NULL, consoleChannel); @@ -509,7 +509,22 @@ ConsoleOutput( Tcl_Interp *consoleInterp = info->consoleInterp; if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) { + Tcl_DString ds; + Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8"); + + /* + * Not checking for utf8 == NULL. Did not check for TCL_ERROR + * from Tcl_SetChannelOption() in Tk_InitConsoleChannels() either. + * Assumption is utf-8 Tcl_Encoding is reliably present. + */ + + CONST char *bytes + = Tcl_ExternalToUtfDString(utf8, buf, toWrite, &ds); + int numBytes = Tcl_DStringLength(&ds); Tcl_Obj *cmd = Tcl_NewStringObj("tk::ConsoleOutput", -1); + + Tcl_FreeEncoding(utf8); + if (data->type == TCL_STDERR) { Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("stderr", -1)); @@ -517,7 +532,10 @@ ConsoleOutput( Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("stdout", -1)); } - Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj(buf, toWrite)); + Tcl_ListObjAppendElement(NULL, cmd, + Tcl_NewStringObj(bytes, numBytes)); + + Tcl_DStringFree(&ds); Tcl_IncrRefCount(cmd); Tcl_GlobalEvalObj(consoleInterp, cmd); Tcl_DecrRefCount(cmd); -- cgit v0.12