]> git.ipfire.org Git - thirdparty/git.git/commitdiff
git-gui: override exec and open only on Windows
authorMark Levedahl <mlevedahl@gmail.com>
Fri, 11 Apr 2025 14:58:20 +0000 (10:58 -0400)
committerTaylor Blau <me@ttaylorr.com>
Fri, 23 May 2025 21:04:23 +0000 (17:04 -0400)
Since aae9560a355d (Work around Tcl's default `PATH` lookup,
2022-11-23), git-gui overrides exec and open on all platforms. But,
this was done in response to Tcl adding elements to $PATH on Windows,
while exec, open, and auto_execok honor $PATH as given on all other
platforms.

Let's do the override only on Windows, restoring others to using their
native exec and open. These honor the sanitized $PATH as that is written
out to env(PATH) in a previous commit. auto_execok is also safe on these
platforms, so can be used for _which.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
git-gui.sh

index 217aeb9ce3a7b5e35a777cc21dcbf0b9e0ca344b..21c3858d2e9af136578deaab8746acee77cdb60f 100755 (executable)
@@ -112,81 +112,91 @@ unset _path_seen
 
 set env(PATH) [join $_search_path $_path_sep]
 
-proc _which {what args} {
-       global _search_exe _search_path
-
-       if {[is_Windows] && [lsearch -exact $args -script] >= 0} {
-               set suffix {}
-       } elseif {[is_Windows] && [string match *$_search_exe [string tolower $what]]} {
-               # The search string already has the file extension
-               set suffix {}
-       } else {
-               set suffix $_search_exe
-       }
+if {[is_Windows]} {
+       proc _which {what args} {
+               global _search_exe _search_path
+
+               if {[lsearch -exact $args -script] >= 0} {
+                       set suffix {}
+               } elseif {[string match *$_search_exe [string tolower $what]]} {
+                       # The search string already has the file extension
+                       set suffix {}
+               } else {
+                       set suffix $_search_exe
+               }
 
-       foreach p $_search_path {
-               set p [file join $p $what$suffix]
-               if {[file exists $p]} {
-                       return [file normalize $p]
+               foreach p $_search_path {
+                       set p [file join $p $what$suffix]
+                       if {[file exists $p]} {
+                               return [file normalize $p]
+                       }
                }
+               return {}
        }
-       return {}
-}
 
-proc sanitize_command_line {command_line from_index} {
-       set i $from_index
-       while {$i < [llength $command_line]} {
-               set cmd [lindex $command_line $i]
-               if {[llength [file split $cmd]] < 2} {
-                       set fullpath [_which $cmd]
-                       if {$fullpath eq ""} {
-                               throw {NOT-FOUND} "$cmd not found in PATH"
+       proc sanitize_command_line {command_line from_index} {
+               set i $from_index
+               while {$i < [llength $command_line]} {
+                       set cmd [lindex $command_line $i]
+                       if {[llength [file split $cmd]] < 2} {
+                               set fullpath [_which $cmd]
+                               if {$fullpath eq ""} {
+                                       throw {NOT-FOUND} "$cmd not found in PATH"
+                               }
+                               lset command_line $i $fullpath
+                       }
+
+                       # handle piped commands, e.g. `exec A | B`
+                       for {incr i} {$i < [llength $command_line]} {incr i} {
+                               if {[lindex $command_line $i] eq "|"} {
+                                       incr i
+                                       break
+                               }
                        }
-                       lset command_line $i $fullpath
                }
+               return $command_line
+       }
+
+       # Override `exec` to avoid unsafe PATH lookup
+
+       rename exec real_exec
 
-               # handle piped commands, e.g. `exec A | B`
-               for {incr i} {$i < [llength $command_line]} {incr i} {
-                       if {[lindex $command_line $i] eq "|"} {
+       proc exec {args} {
+               # skip options
+               for {set i 0} {$i < [llength $args]} {incr i} {
+                       set arg [lindex $args $i]
+                       if {$arg eq "--"} {
                                incr i
                                break
                        }
+                       if {[string range $arg 0 0] ne "-"} {
+                               break
+                       }
                }
+               set args [sanitize_command_line $args $i]
+               uplevel 1 real_exec $args
        }
-       return $command_line
-}
 
-# Override `exec` to avoid unsafe PATH lookup
+       # Override `open` to avoid unsafe PATH lookup
 
-rename exec real_exec
+       rename open real_open
 
-proc exec {args} {
-       # skip options
-       for {set i 0} {$i < [llength $args]} {incr i} {
-               set arg [lindex $args $i]
-               if {$arg eq "--"} {
-                       incr i
-                       break
-               }
-               if {[string range $arg 0 0] ne "-"} {
-                       break
+       proc open {args} {
+               set arg0 [lindex $args 0]
+               if {[string range $arg0 0 0] eq "|"} {
+                       set command_line [string trim [string range $arg0 1 end]]
+                       lset args 0 "| [sanitize_command_line $command_line 0]"
                }
+               uplevel 1 real_open $args
        }
-       set args [sanitize_command_line $args $i]
-       uplevel 1 real_exec $args
-}
-
-# Override `open` to avoid unsafe PATH lookup
 
-rename open real_open
+} else {
+       # On non-Windows platforms, auto_execok, exec, and open are safe, and will
+       # use the sanitized search path. But, we need _which for these.
 
-proc open {args} {
-       set arg0 [lindex $args 0]
-       if {[string range $arg0 0 0] eq "|"} {
-               set command_line [string trim [string range $arg0 1 end]]
-               lset args 0 "| [sanitize_command_line $command_line 0]"
+       proc _which {what args} {
+               return [lindex [auto_execok $what] 0]
        }
-       uplevel 1 real_open $args
 }
 
 ######################################################################