Skip to content

Commit a1ccd25

Browse files
mark987ttaylorr
authored andcommitted
git-gui: override exec and open only on Windows
Since aae9560 (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 <[email protected]> Signed-off-by: Johannes Sixt <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 384b140 commit a1ccd25

File tree

1 file changed

+65
-55
lines changed

1 file changed

+65
-55
lines changed

git-gui.sh

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -112,81 +112,91 @@ unset _path_seen
112112
113113
set env(PATH) [join $_search_path $_path_sep]
114114
115-
proc _which {what args} {
116-
global _search_exe _search_path
117-
118-
if {[is_Windows] && [lsearch -exact $args -script] >= 0} {
119-
set suffix {}
120-
} elseif {[is_Windows] && [string match *$_search_exe [string tolower $what]]} {
121-
# The search string already has the file extension
122-
set suffix {}
123-
} else {
124-
set suffix $_search_exe
125-
}
115+
if {[is_Windows]} {
116+
proc _which {what args} {
117+
global _search_exe _search_path
118+
119+
if {[lsearch -exact $args -script] >= 0} {
120+
set suffix {}
121+
} elseif {[string match *$_search_exe [string tolower $what]]} {
122+
# The search string already has the file extension
123+
set suffix {}
124+
} else {
125+
set suffix $_search_exe
126+
}
126127
127-
foreach p $_search_path {
128-
set p [file join $p $what$suffix]
129-
if {[file exists $p]} {
130-
return [file normalize $p]
128+
foreach p $_search_path {
129+
set p [file join $p $what$suffix]
130+
if {[file exists $p]} {
131+
return [file normalize $p]
132+
}
131133
}
134+
return {}
132135
}
133-
return {}
134-
}
135136
136-
proc sanitize_command_line {command_line from_index} {
137-
set i $from_index
138-
while {$i < [llength $command_line]} {
139-
set cmd [lindex $command_line $i]
140-
if {[llength [file split $cmd]] < 2} {
141-
set fullpath [_which $cmd]
142-
if {$fullpath eq ""} {
143-
throw {NOT-FOUND} "$cmd not found in PATH"
137+
proc sanitize_command_line {command_line from_index} {
138+
set i $from_index
139+
while {$i < [llength $command_line]} {
140+
set cmd [lindex $command_line $i]
141+
if {[llength [file split $cmd]] < 2} {
142+
set fullpath [_which $cmd]
143+
if {$fullpath eq ""} {
144+
throw {NOT-FOUND} "$cmd not found in PATH"
145+
}
146+
lset command_line $i $fullpath
147+
}
148+
149+
# handle piped commands, e.g. `exec A | B`
150+
for {incr i} {$i < [llength $command_line]} {incr i} {
151+
if {[lindex $command_line $i] eq "|"} {
152+
incr i
153+
break
154+
}
144155
}
145-
lset command_line $i $fullpath
146156
}
157+
return $command_line
158+
}
159+
160+
# Override `exec` to avoid unsafe PATH lookup
161+
162+
rename exec real_exec
147163
148-
# handle piped commands, e.g. `exec A | B`
149-
for {incr i} {$i < [llength $command_line]} {incr i} {
150-
if {[lindex $command_line $i] eq "|"} {
164+
proc exec {args} {
165+
# skip options
166+
for {set i 0} {$i < [llength $args]} {incr i} {
167+
set arg [lindex $args $i]
168+
if {$arg eq "--"} {
151169
incr i
152170
break
153171
}
172+
if {[string range $arg 0 0] ne "-"} {
173+
break
174+
}
154175
}
176+
set args [sanitize_command_line $args $i]
177+
uplevel 1 real_exec $args
155178
}
156-
return $command_line
157-
}
158179
159-
# Override `exec` to avoid unsafe PATH lookup
180+
# Override `open` to avoid unsafe PATH lookup
160181
161-
rename exec real_exec
182+
rename open real_open
162183
163-
proc exec {args} {
164-
# skip options
165-
for {set i 0} {$i < [llength $args]} {incr i} {
166-
set arg [lindex $args $i]
167-
if {$arg eq "--"} {
168-
incr i
169-
break
170-
}
171-
if {[string range $arg 0 0] ne "-"} {
172-
break
184+
proc open {args} {
185+
set arg0 [lindex $args 0]
186+
if {[string range $arg0 0 0] eq "|"} {
187+
set command_line [string trim [string range $arg0 1 end]]
188+
lset args 0 "| [sanitize_command_line $command_line 0]"
173189
}
190+
uplevel 1 real_open $args
174191
}
175-
set args [sanitize_command_line $args $i]
176-
uplevel 1 real_exec $args
177-
}
178-
179-
# Override `open` to avoid unsafe PATH lookup
180192
181-
rename open real_open
193+
} else {
194+
# On non-Windows platforms, auto_execok, exec, and open are safe, and will
195+
# use the sanitized search path. But, we need _which for these.
182196
183-
proc open {args} {
184-
set arg0 [lindex $args 0]
185-
if {[string range $arg0 0 0] eq "|"} {
186-
set command_line [string trim [string range $arg0 1 end]]
187-
lset args 0 "| [sanitize_command_line $command_line 0]"
197+
proc _which {what args} {
198+
return [lindex [auto_execok $what] 0]
188199
}
189-
uplevel 1 real_open $args
190200
}
191201
192202
######################################################################

0 commit comments

Comments
 (0)