]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ml/replace-auto-execok' into js/fix-open-exec
authorTaylor Blau <me@ttaylorr.com>
Fri, 23 May 2025 21:04:27 +0000 (17:04 -0400)
committerTaylor Blau <me@ttaylorr.com>
Fri, 23 May 2025 21:04:27 +0000 (17:04 -0400)
Signed-off-by: Taylor Blau <me@ttaylorr.com>
1  2 
git-gui.sh
lib/shortcut.tcl
lib/sshkey.tcl
lib/tools.tcl

diff --cc git-gui.sh
index 9ad172ac6602e233af366fb2c51a6a47fa766241,21c3858d2e9af136578deaab8746acee77cdb60f..0355c0c83650477a108a15940a3e043c01ad9b42
@@@ -132,94 -169,36 +169,86 @@@ if {[is_Windows]} 
                                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
  }
  
 +# Wrap exec/open to sanitize arguments
 +
 +# unsafe arguments begin with redirections or the pipe or background operators
 +proc is_arg_unsafe {arg} {
 +      regexp {^([<|>&]|2>)} $arg
 +}
 +
 +proc make_arg_safe {arg} {
 +      if {[is_arg_unsafe $arg]} {
 +              set arg [file join . $arg]
 +      }
 +      return $arg
 +}
 +
 +proc make_arglist_safe {arglist} {
 +      set res {}
 +      foreach arg $arglist {
 +              lappend res [make_arg_safe $arg]
 +      }
 +      return $res
 +}
 +
 +# executes one command
 +# no redirections or pipelines are possible
 +# cmd is a list that specifies the command and its arguments
 +# calls `exec` and returns its value
 +proc safe_exec {cmd} {
 +      eval exec [make_arglist_safe $cmd]
 +}
 +
 +# executes one command in the background
 +# no redirections or pipelines are possible
 +# cmd is a list that specifies the command and its arguments
 +# calls `exec` and returns its value
 +proc safe_exec_bg {cmd} {
 +      eval exec [make_arglist_safe $cmd] &
 +}
 +
 +proc safe_open_file {filename flags} {
 +      # a file name starting with "|" would attempt to run a process
 +      # but such a file name must be treated as a relative path
 +      # hide the "|" behind "./"
 +      if {[string index $filename 0] eq "|"} {
 +              set filename [file join . $filename]
 +      }
 +      open $filename $flags
 +}
 +
 +# End exec/open wrappers
 +
  ######################################################################
  ##
  ## locate our library
@@@ -574,33 -575,13 +625,14 @@@ proc _git_cmd {name} 
        return $v
  }
  
- # Test a file for a hashbang to identify executable scripts on Windows.
- proc is_shellscript {filename} {
-       if {![file exists $filename]} {return 0}
-       set f [safe_open_file $filename r]
-       fconfigure $f -encoding binary
-       set magic [read $f 2]
-       close $f
-       return [expr {$magic eq "#!"}]
- }
- # Run a command connected via pipes on stdout.
+ # Run a shell command connected via pipes on stdout.
  # This is for use with textconv filters and uses sh -c "..." to allow it to
- # contain a command with arguments. On windows we must check for shell
- # scripts specifically otherwise just call the filter command.
+ # contain a command with arguments. We presume this
+ # to be a shellscript that the configured shell (/bin/sh by default) knows
+ # how to run.
  proc open_cmd_pipe {cmd path} {
-       global env
-       if {![file executable [shellpath]]} {
-               set exe [auto_execok [lindex $cmd 0]]
-               if {[is_shellscript [lindex $exe 0]]} {
-                       set run [linsert [auto_execok sh] end -c "$cmd \"\$0\"" $path]
-               } else {
-                       set run [concat $exe [lrange $cmd 1 end] $path]
-               }
-       } else {
-               set run [list [shellpath] -c "$cmd \"\$0\"" $path]
-       }
+       set run [list [shellpath] -c "$cmd \"\$0\"" $path]
 +      set run [make_arglist_safe $run]
        return [open |$run r]
  }
  
@@@ -2746,17 -2785,16 +2778,16 @@@ if {![is_bare]} 
  
  if {[is_Windows]} {
        # Use /git-bash.exe if available
-       set normalized [file normalize $::argv0]
-       regsub "/mingw../libexec/git-core/git-gui$" \
-               $normalized "/git-bash.exe" cmdLine
-       if {$cmdLine != $normalized && [file exists $cmdLine]} {
-               set cmdLine [list "Git Bash" $cmdLine]
+       set _git_bash [exec cygpath -m /git-bash.exe]
+       if {[file executable $_git_bash]} {
 -              set _bash_cmdline [list "Git Bash" $_git_bash &]
++              set _bash_cmdline [list "Git Bash" $_git_bash]
        } else {
-               set cmdLine [list "Git Bash" bash --login -l]
 -              set _bash_cmdline [list "Git Bash" bash --login -l &]
++              set _bash_cmdline [list "Git Bash" bash --login -l]
        }
        .mbar.repository add command \
                -label [mc "Git Bash"] \
-               -command {safe_exec_bg [concat [list [auto_execok start]] $cmdLine]}
 -              -command {eval exec [list [_which cmd] /c start] $_bash_cmdline}
++              -command {safe_exec_bg [concat [list [_which cmd] /c start] $_bash_cmdline]}
+       unset _git_bash
  }
  
  if {[is_Windows] || ![is_bare]} {
Simple merge
diff --cc lib/sshkey.tcl
index b32bdd06e95d707f22b5fbe5a31a5e526bb99399,c0c5d1dad8252d927d10482911d2dc656b74b637..c3e681b899064cc2b412dfffddb3d64a67aa9f33
@@@ -83,9 -83,10 +83,10 @@@ proc make_ssh_key {w} 
        set sshkey_title [mc "Generating..."]
        $w.header.gen configure -state disabled
  
-       set cmdline [list sh -c {echo | ssh-keygen -q -t rsa -f ~/.ssh/id_rsa 2>&1}]
+       set cmdline [list [shellpath] -c \
+               {echo | ssh-keygen -q -t rsa -f ~/.ssh/id_rsa 2>&1}]
  
 -      if {[catch { set sshkey_fd [_open_stdout_stderr $cmdline] } err]} {
 +      if {[catch { set sshkey_fd [safe_open_command $cmdline] } err]} {
                error_popup [mc "Could not start ssh-keygen:\n\n%s" $err]
                return
        }
diff --cc lib/tools.tcl
Simple merge