aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Levedahl <mlevedahl@gmail.com>2025-04-11 10:58:20 -0400
committerTaylor Blau <me@ttaylorr.com>2025-05-23 17:04:23 -0400
commita1ccd2512072cf52835050f4c97a4fba9f0ec8f9 (patch)
tree30a638941098c1ed3ccc67e2abaf5fbebad7f65e
parentgit-gui: sanitize $PATH on all platforms (diff)
downloadgit-a1ccd2512072cf52835050f4c97a4fba9f0ec8f9.tar.gz
git-a1ccd2512072cf52835050f4c97a4fba9f0ec8f9.zip
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 <mlevedahl@gmail.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Taylor Blau <me@ttaylorr.com>
-rwxr-xr-xgit-gui.sh120
1 files changed, 65 insertions, 55 deletions
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
}
######################################################################