@@ -112,81 +112,91 @@ unset _path_seen
112112
113113set 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