]> git.ipfire.org Git - thirdparty/git.git/commitdiff
git-gui: use -profile tcl8 for file input with Tcl 9
authorMark Levedahl <mlevedahl@gmail.com>
Sat, 31 May 2025 18:52:35 +0000 (14:52 -0400)
committerMark Levedahl <mlevedahl@gmail.com>
Thu, 31 Jul 2025 17:51:03 +0000 (13:51 -0400)
git-gui invokes many git commands expecting output in utf-8 encoding,
but git accepts extended ascii (code page unknown) as utf-8 without
validating, so cannot guarantee valid utf-8 on output.  In particular,
using any extended ascii code page has long been acceptable on git given
that everyone on a project is aware of and uses that same code page to
view all data. utf-8 accepts only 7-bit ascii characters in single
bytes, and any characters outside of that base set require at least two
bytes for representation in unicode.

Tcl is a string based language, and transcodes all input data to an
internal unicode format, and to whatever format is requested on output:
"pure" binary is recoded byte by byte using iso8859-1.  Tcl8.x silently
recodes invalid utf-8 as binary data, so extended ascii characters
maintain their binary value on output but may not display correctly.

Tcl 8.7 added three profiles to control this behaviour: strict (raises
exceptions), replace (replaces each invalid byte with ?), and the
default tcl8 maintaining the old behavior.  Tcl 9 changes the default
profile to strict, meaning any invalid utf-8 raises an exception that
git-gui does not handle.

An example of this in the git repository is commit 7eb93c8965 ("[PATCH]
Simplify git script", 2005-09-07). This includes extended ascii
characters in the author name and commit message.

The tcl8 profile used so far has acceptable behavior given git-gui's
acceptance: this allows git-gui to accept extended ascii though it may
display incorrectly.  Let's continue that behavior by overriding open to
use the tcl8 profile on Tcl9 and later: Tcl 8.6 does not understand
fconfigure -profile, and Tcl 8.7 maintains the tcl8 profile.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
git-gui.sh

index 63c2f48f91ac126120e9f99225c7053534b532b4..2c83ed506680b420a3ba4176a11706776054910d 100755 (executable)
@@ -73,6 +73,19 @@ proc is_Cygwin {} {
        return $_iscygwin
 }
 
+######################################################################
+## Enable Tcl8 profile in Tcl9, allowing consumption of data that has
+## bytes not conforming to the assumed encoding profile.
+
+if {[package vcompare $::tcl_version 9.0] >= 0} {
+       rename open _strict_open
+       proc open args {
+               set f [_strict_open {*}$args]
+               chan configure $f -profile tcl8
+               return $f
+       }
+}
+
 ######################################################################
 ##
 ## PATH lookup. Sanitize $PATH, assure exec/open use only that