git-gui: sanitize $PATH on all platforms

Since 8f23432b38d9 (windows: ignore empty `PATH` elements, 2022-11-23), git-gui removes empty elements from $PATH, and a prior commit made this remove all non-absolute elements from $PATH. But, this happens only on Windows. Unsafe $PATH elements in $PATH are possible on all platforms. Let's sanitize $PATH on all platforms to have consistent behavior. If a user really wants the current repository on $PATH, they can add its absolute name to $PATH. Signed-off-by: Mark Levedahl <mlevedahl@gmail.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Taylor Blau <me@ttaylorr.com>

Mark Levedahl committed Apr 11, 2025 at 10:47 UTC 384b1409e8ba05bb908979a3f6aaa45bf93ac3c9
1 file changed +34 -30
git-gui.sh
+34 -30
@@ -77,39 +77,43 @@ proc is_Cygwin {} {
77
78 ######################################################################
79 ##
80 -## PATH lookup
80 +## PATH lookup. Sanitize $PATH, assure exec/open use only that
81
82 -set _search_path {}
83 -proc _which {what args} {
84 - global env _search_exe _search_path
82 +if {[is_Windows]} {
83 + set _path_sep {;}
84 + set _search_exe .exe
85 +} else {
86 + set _path_sep {:}
87 + set _search_exe {}
88 +}
89
86 - if {$_search_path eq {}} {
87 - if {[is_Windows]} {
88 - set gitguidir [file dirname [info script]]
89 - regsub -all ";" $gitguidir "\\;" gitguidir
90 - set env(PATH) "$gitguidir;$env(PATH)"
91 -
92 - set _path_seen [dict create]
93 - foreach p [split $env(PATH) {;}] {
94 - # Keep only absolute paths, getting rid of ., empty, etc.
95 - if {[file pathtype $p] ne {absolute}} {
96 - continue
97 - }
98 - # Keep only the first occurence of any duplicates.
99 - set norm_p [file normalize $p]
100 - if {[dict exists $_path_seen $norm_p]} {
101 - continue
102 - }
103 - dict set _path_seen $norm_p 1
104 - lappend _search_path $norm_p
105 - }
106 - unset _path_seen
107 - set _search_exe .exe
108 - } else {
109 - set _search_path [split $env(PATH) :]
110 - set _search_exe {}
111 - }
90 +if {[is_Windows]} {
91 + set gitguidir [file dirname [info script]]
92 + regsub -all ";" $gitguidir "\\;" gitguidir
93 + set env(PATH) "$gitguidir;$env(PATH)"
94 +}
95 +
96 +set _search_path {}
97 +set _path_seen [dict create]
98 +foreach p [split $env(PATH) $_path_sep] {
99 + # Keep only absolute paths, getting rid of ., empty, etc.
100 + if {[file pathtype $p] ne {absolute}} {
101 + continue
102 }
103 + # Keep only the first occurence of any duplicates.
104 + set norm_p [file normalize $p]
105 + if {[dict exists $_path_seen $norm_p]} {
106 + continue
107 + }
108 + dict set _path_seen $norm_p 1
109 + lappend _search_path $norm_p
110 +}
111 +unset _path_seen
112 +
113 +set env(PATH) [join $_search_path $_path_sep]
114 +
115 +proc _which {what args} {
116 + global _search_exe _search_path
117
118 if {[is_Windows] && [lsearch -exact $args -script] >= 0} {
119 set suffix {}