From: Mark Levedahl Date: Fri, 11 Apr 2025 14:58:20 +0000 (-0400) Subject: git-gui: override exec and open only on Windows X-Git-Tag: v2.43.7~4^2~1^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a1ccd2512072cf52835050f4c97a4fba9f0ec8f9;p=thirdparty%2Fgit.git git-gui: override exec and open only on Windows 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 Signed-off-by: Johannes Sixt Signed-off-by: Taylor Blau --- diff --git a/git-gui.sh b/git-gui.sh index 217aeb9ce3..21c3858d2e 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -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 } ######################################################################