mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-21 22:43:27 +02:00
Remove redundant secureexec package (#2847)
This commit is contained in:
commit
7cfbfb7183
2
.github/workflows/cd.yml
vendored
2
.github/workflows/cd.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.18.x
|
go-version: 1.20.x
|
||||||
- name: Run goreleaser
|
- name: Run goreleaser
|
||||||
uses: goreleaser/goreleaser-action@v1
|
uses: goreleaser/goreleaser-action@v1
|
||||||
with:
|
with:
|
||||||
|
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@ -1,7 +1,7 @@
|
|||||||
name: Continuous Integration
|
name: Continuous Integration
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: 1.18
|
GO_VERSION: 1.20
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -32,7 +32,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.18.x
|
go-version: 1.20.x
|
||||||
- name: Cache build
|
- name: Cache build
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
@ -91,7 +91,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.18.x
|
go-version: 1.20.x
|
||||||
- name: Cache build
|
- name: Cache build
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
@ -117,7 +117,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.18.x
|
go-version: 1.20.x
|
||||||
- name: Cache build
|
- name: Cache build
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
@ -153,7 +153,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.18.x
|
go-version: 1.20.x
|
||||||
- name: Cache build
|
- name: Cache build
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
@ -187,7 +187,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: 1.18.x
|
go-version: 1.20.x
|
||||||
- name: Cache build
|
- name: Cache build
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
|
@ -26,4 +26,4 @@ linters-settings:
|
|||||||
max-func-lines: 0
|
max-func-lines: 0
|
||||||
|
|
||||||
run:
|
run:
|
||||||
go: 1.18
|
go: 1.20
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# docker build -t lazygit .
|
# docker build -t lazygit .
|
||||||
# docker run -it lazygit:latest /bin/sh
|
# docker run -it lazygit:latest /bin/sh
|
||||||
|
|
||||||
FROM golang:1.18 as build
|
FROM golang:1.20 as build
|
||||||
WORKDIR /go/src/github.com/jesseduffield/lazygit/
|
WORKDIR /go/src/github.com/jesseduffield/lazygit/
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
3
go.mod
3
go.mod
@ -1,12 +1,11 @@
|
|||||||
module github.com/jesseduffield/lazygit
|
module github.com/jesseduffield/lazygit
|
||||||
|
|
||||||
go 1.18
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/OpenPeeDeeP/xdg v1.0.0
|
github.com/OpenPeeDeeP/xdg v1.0.0
|
||||||
github.com/atotto/clipboard v0.1.4
|
github.com/atotto/clipboard v0.1.4
|
||||||
github.com/aybabtme/humanlog v0.4.1
|
github.com/aybabtme/humanlog v0.4.1
|
||||||
github.com/cli/safeexec v1.0.0
|
|
||||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||||
github.com/creack/pty v1.1.11
|
github.com/creack/pty v1.1.11
|
||||||
github.com/fsmiamoto/git-todo-parser v0.0.5
|
github.com/fsmiamoto/git-todo-parser v0.0.5
|
||||||
|
2
go.sum
2
go.sum
@ -55,8 +55,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
|||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI=
|
|
||||||
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuijfIjZyjZaHq9xDUh0tNitwXshJpbLkqMOJv4H3do=
|
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuijfIjZyjZaHq9xDUh0tNitwXshJpbLkqMOJv4H3do=
|
||||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc=
|
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc=
|
||||||
|
@ -5,12 +5,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/fsmiamoto/git-todo-parser/todo"
|
"github.com/fsmiamoto/git-todo-parser/todo"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/common"
|
"github.com/jesseduffield/lazygit/pkg/common"
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
@ -92,7 +92,7 @@ func getDaemonKind() DaemonKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getCommentChar() byte {
|
func getCommentChar() byte {
|
||||||
cmd := secureexec.Command("git", "config", "--get", "--null", "core.commentChar")
|
cmd := exec.Command("git", "config", "--get", "--null", "core.commentChar")
|
||||||
if output, err := cmd.Output(); err == nil && len(output) == 2 {
|
if output, err := cmd.Output(); err == nil && len(output) == 2 {
|
||||||
return output[0]
|
return output[0]
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
@ -17,7 +18,6 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/env"
|
"github.com/jesseduffield/lazygit/pkg/env"
|
||||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/logs/tail"
|
"github.com/jesseduffield/lazygit/pkg/logs/tail"
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
@ -280,7 +280,7 @@ func mergeBuildInfo(buildInfo *BuildInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getGitVersionInfo() string {
|
func getGitVersionInfo() string {
|
||||||
cmd := secureexec.Command("git", "--version")
|
cmd := exec.Command("git", "--version")
|
||||||
stdout, _ := cmd.Output()
|
stdout, _ := cmd.Output()
|
||||||
gitVersion := strings.Trim(strings.TrimPrefix(string(stdout), "git version "), " \r\n")
|
gitVersion := strings.Trim(strings.TrimPrefix(string(stdout), "git version "), " \r\n")
|
||||||
return gitVersion
|
return gitVersion
|
||||||
|
@ -7,8 +7,6 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// including license from https://github.com/tcnksm/go-gitconfig because this file is an adaptation of that repo's code
|
// including license from https://github.com/tcnksm/go-gitconfig because this file is an adaptation of that repo's code
|
||||||
@ -55,10 +53,10 @@ func runGitConfigCmd(cmd *exec.Cmd) (string, error) {
|
|||||||
|
|
||||||
func getGitConfigCmd(key string) *exec.Cmd {
|
func getGitConfigCmd(key string) *exec.Cmd {
|
||||||
gitArgs := []string{"config", "--get", "--null", key}
|
gitArgs := []string{"config", "--get", "--null", key}
|
||||||
return secureexec.Command("git", gitArgs...)
|
return exec.Command("git", gitArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGitConfigGeneralCmd(args string) *exec.Cmd {
|
func getGitConfigGeneralCmd(args string) *exec.Cmd {
|
||||||
gitArgs := append([]string{"config"}, strings.Split(args, " ")...)
|
gitArgs := append([]string{"config"}, strings.Split(args, " ")...)
|
||||||
return secureexec.Command("git", gitArgs...)
|
return exec.Command("git", gitArgs...)
|
||||||
}
|
}
|
||||||
|
@ -73,10 +73,6 @@ type ICmdObj interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CmdObj struct {
|
type CmdObj struct {
|
||||||
// the secureexec package will swap out the first arg with the full path to the binary,
|
|
||||||
// so we store these args separately so that ToString() will output the original
|
|
||||||
args []string
|
|
||||||
|
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
|
|
||||||
runner ICmdObjRunner
|
runner ICmdObjRunner
|
||||||
@ -121,7 +117,7 @@ func (self *CmdObj) GetCmd() *exec.Cmd {
|
|||||||
|
|
||||||
func (self *CmdObj) ToString() string {
|
func (self *CmdObj) ToString() string {
|
||||||
// if a given arg contains a space, we need to wrap it in quotes
|
// if a given arg contains a space, we need to wrap it in quotes
|
||||||
quotedArgs := lo.Map(self.args, func(arg string, _ int) string {
|
quotedArgs := lo.Map(self.cmd.Args, func(arg string, _ int) string {
|
||||||
if strings.Contains(arg, " ") {
|
if strings.Contains(arg, " ") {
|
||||||
return `"` + arg + `"`
|
return `"` + arg + `"`
|
||||||
}
|
}
|
||||||
@ -132,7 +128,7 @@ func (self *CmdObj) ToString() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *CmdObj) Args() []string {
|
func (self *CmdObj) Args() []string {
|
||||||
return self.args
|
return self.cmd.Args
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CmdObj) AddEnvVars(vars ...string) ICmdObj {
|
func (self *CmdObj) AddEnvVars(vars ...string) ICmdObj {
|
||||||
|
@ -3,9 +3,9 @@ package oscommands
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
"github.com/mgutz/str"
|
"github.com/mgutz/str"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,11 +27,10 @@ type CmdObjBuilder struct {
|
|||||||
var _ ICmdObjBuilder = &CmdObjBuilder{}
|
var _ ICmdObjBuilder = &CmdObjBuilder{}
|
||||||
|
|
||||||
func (self *CmdObjBuilder) New(args []string) ICmdObj {
|
func (self *CmdObjBuilder) New(args []string) ICmdObj {
|
||||||
cmd := secureexec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
|
|
||||||
return &CmdObj{
|
return &CmdObj{
|
||||||
args: args,
|
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
runner: self.runner,
|
runner: self.runner,
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@ func TestCmdObjToString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, scenario := range scenarios {
|
for _, scenario := range scenarios {
|
||||||
cmdObj := &CmdObj{args: scenario.cmdArgs}
|
cmd := exec.Command(scenario.cmdArgs[0], scenario.cmdArgs[1:]...)
|
||||||
|
cmdObj := &CmdObj{cmd: cmd}
|
||||||
actual := cmdObj.ToString()
|
actual := cmdObj.ToString()
|
||||||
if actual != scenario.expected {
|
if actual != scenario.expected {
|
||||||
t.Errorf("Expected %s, got %s", quote(scenario.expected), quote(actual))
|
t.Errorf("Expected %s, got %s", quote(scenario.expected), quote(actual))
|
||||||
|
@ -3,8 +3,6 @@ package oscommands
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
@ -124,27 +122,7 @@ func (self *FakeCmdObjRunner) ExpectFunc(description string, fn func(cmdObj ICmd
|
|||||||
func (self *FakeCmdObjRunner) ExpectArgs(expectedArgs []string, output string, err error) *FakeCmdObjRunner {
|
func (self *FakeCmdObjRunner) ExpectArgs(expectedArgs []string, output string, err error) *FakeCmdObjRunner {
|
||||||
description := fmt.Sprintf("matches args %s", strings.Join(expectedArgs, " "))
|
description := fmt.Sprintf("matches args %s", strings.Join(expectedArgs, " "))
|
||||||
self.ExpectFunc(description, func(cmdObj ICmdObj) bool {
|
self.ExpectFunc(description, func(cmdObj ICmdObj) bool {
|
||||||
args := cmdObj.GetCmd().Args
|
return slices.Equal(expectedArgs, cmdObj.GetCmd().Args)
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
// thanks to the secureexec package, the first arg is something like
|
|
||||||
// '"C:\\Program Files\\Git\\mingw64\\bin\\<command>.exe"
|
|
||||||
// on windows so we'll just ensure it contains our program
|
|
||||||
if !strings.Contains(args[0], expectedArgs[0]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// first arg is the program name
|
|
||||||
if expectedArgs[0] != args[0] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !slices.Equal(expectedArgs[1:], args[1:]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}, output, err)
|
}, output, err)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -153,18 +131,7 @@ func (self *FakeCmdObjRunner) ExpectArgs(expectedArgs []string, output string, e
|
|||||||
func (self *FakeCmdObjRunner) ExpectGitArgs(expectedArgs []string, output string, err error) *FakeCmdObjRunner {
|
func (self *FakeCmdObjRunner) ExpectGitArgs(expectedArgs []string, output string, err error) *FakeCmdObjRunner {
|
||||||
description := fmt.Sprintf("matches git args %s", strings.Join(expectedArgs, " "))
|
description := fmt.Sprintf("matches git args %s", strings.Join(expectedArgs, " "))
|
||||||
self.ExpectFunc(description, func(cmdObj ICmdObj) bool {
|
self.ExpectFunc(description, func(cmdObj ICmdObj) bool {
|
||||||
// first arg is 'git' on unix and something like '"C:\\Program Files\\Git\\mingw64\\bin\\git.exe" on windows so we'll just ensure it ends in either 'git' or 'git.exe'
|
return slices.Equal(expectedArgs, cmdObj.GetCmd().Args[1:])
|
||||||
re := regexp.MustCompile(`git(\.exe)?$`)
|
|
||||||
args := cmdObj.GetCmd().Args
|
|
||||||
if !re.MatchString(args[0]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !slices.Equal(expectedArgs, args[1:]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}, output, err)
|
}, output, err)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
@ -6,7 +6,6 @@ package oscommands
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cli/safeexec"
|
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -20,13 +19,11 @@ func TestOSCommandOpenFileWindows(t *testing.T) {
|
|||||||
test func(error)
|
test func(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
fullCmdPath, _ := safeexec.LookPath("cmd")
|
|
||||||
|
|
||||||
scenarios := []scenario{
|
scenarios := []scenario{
|
||||||
{
|
{
|
||||||
filename: "test",
|
filename: "test",
|
||||||
runner: NewFakeRunner(t).
|
runner: NewFakeRunner(t).
|
||||||
ExpectArgs([]string{fullCmdPath, "/c", "start", "", "test"}, "", errors.New("error")),
|
ExpectArgs([]string{"cmd", "/c", "start", "", "test"}, "", errors.New("error")),
|
||||||
test: func(err error) {
|
test: func(err error) {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
},
|
},
|
||||||
@ -34,7 +31,7 @@ func TestOSCommandOpenFileWindows(t *testing.T) {
|
|||||||
{
|
{
|
||||||
filename: "test",
|
filename: "test",
|
||||||
runner: NewFakeRunner(t).
|
runner: NewFakeRunner(t).
|
||||||
ExpectArgs([]string{fullCmdPath, "/c", "start", "", "test"}, "", nil),
|
ExpectArgs([]string{"cmd", "/c", "start", "", "test"}, "", nil),
|
||||||
test: func(err error) {
|
test: func(err error) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
},
|
},
|
||||||
@ -42,7 +39,7 @@ func TestOSCommandOpenFileWindows(t *testing.T) {
|
|||||||
{
|
{
|
||||||
filename: "filename with spaces",
|
filename: "filename with spaces",
|
||||||
runner: NewFakeRunner(t).
|
runner: NewFakeRunner(t).
|
||||||
ExpectArgs([]string{fullCmdPath, "/c", "start", "", "filename with spaces"}, "", nil),
|
ExpectArgs([]string{"cmd", "/c", "start", "", "filename with spaces"}, "", nil),
|
||||||
test: func(err error) {
|
test: func(err error) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
},
|
},
|
||||||
@ -50,7 +47,7 @@ func TestOSCommandOpenFileWindows(t *testing.T) {
|
|||||||
{
|
{
|
||||||
filename: "let's_test_with_single_quote",
|
filename: "let's_test_with_single_quote",
|
||||||
runner: NewFakeRunner(t).
|
runner: NewFakeRunner(t).
|
||||||
ExpectArgs([]string{fullCmdPath, "/c", "start", "", "let's_test_with_single_quote"}, "", nil),
|
ExpectArgs([]string{"cmd", "/c", "start", "", "let's_test_with_single_quote"}, "", nil),
|
||||||
test: func(err error) {
|
test: func(err error) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
},
|
},
|
||||||
@ -58,7 +55,7 @@ func TestOSCommandOpenFileWindows(t *testing.T) {
|
|||||||
{
|
{
|
||||||
filename: "$USER.txt",
|
filename: "$USER.txt",
|
||||||
runner: NewFakeRunner(t).
|
runner: NewFakeRunner(t).
|
||||||
ExpectArgs([]string{fullCmdPath, "/c", "start", "", "$USER.txt"}, "", nil),
|
ExpectArgs([]string{"cmd", "/c", "start", "", "$USER.txt"}, "", nil),
|
||||||
test: func(err error) {
|
test: func(err error) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
},
|
},
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -13,7 +14,6 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
"github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
"github.com/jesseduffield/lazygit/pkg/integration/tests"
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ func RunTUI() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("code -r pkg/integration/tests/%s.go", currentTest.Name()))
|
cmd := exec.Command("sh", "-c", fmt.Sprintf("code -r pkg/integration/tests/%s.go", currentTest.Name()))
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ func RunTUI() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := secureexec.Command("sh", "-c", fmt.Sprintf("code test/results/%s", currentTest.Name()))
|
cmd := exec.Command("sh", "-c", fmt.Sprintf("code test/results/%s", currentTest.Name()))
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// this is for running shell commands, mostly for the sake of setting up the repo
|
// this is for running shell commands, mostly for the sake of setting up the repo
|
||||||
@ -44,7 +43,7 @@ func (self *Shell) RunCommandExpectError(args []string) *Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Shell) runCommandWithOutput(args []string) (string, error) {
|
func (self *Shell) runCommandWithOutput(args []string) (string, error) {
|
||||||
cmd := secureexec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
cmd.Dir = self.dir
|
cmd.Dir = self.dir
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ func (self *Shell) RunShellCommand(cmdStr string) *Shell {
|
|||||||
shellArg = "/C"
|
shellArg = "/C"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := secureexec.Command(shell, shellArg, cmdStr)
|
cmd := exec.Command(shell, shellArg, cmdStr)
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
cmd.Dir = self.dir
|
cmd.Dir = self.dir
|
||||||
|
|
||||||
|
@ -6,13 +6,13 @@ package tail
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
"github.com/aybabtme/humanlog"
|
"github.com/aybabtme/humanlog"
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func tailLogsForPlatform(logFilePath string, opts *humanlog.HandlerOptions) {
|
func tailLogsForPlatform(logFilePath string, opts *humanlog.HandlerOptions) {
|
||||||
cmd := secureexec.Command("tail", "-f", logFilePath)
|
cmd := exec.Command("tail", "-f", logFilePath)
|
||||||
|
|
||||||
stdout, _ := cmd.StdoutPipe()
|
stdout, _ := cmd.StdoutPipe()
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package secureexec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Command(name string, args ...string) *exec.Cmd {
|
|
||||||
return exec.Command(name, args...)
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package secureexec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/cli/safeexec"
|
|
||||||
)
|
|
||||||
|
|
||||||
// calling exec.Command directly on a windows machine poses a security risk due to
|
|
||||||
// the current directory being searched first before any directories in the PATH
|
|
||||||
// variable, meaning you might clone a repo that contains a program called 'git'
|
|
||||||
// which does something malicious when executed.
|
|
||||||
|
|
||||||
// see https://github.com/golang/go/issues/38736 for more context. We'll likely
|
|
||||||
// be able to just throw out this code and switch to the official solution when it exists.
|
|
||||||
|
|
||||||
// I consider this a minor security concern because you're just as vulnerable if
|
|
||||||
// you call `git status` from the command line directly but no harm in playing it
|
|
||||||
// safe.
|
|
||||||
|
|
||||||
var pathCache = map[string]string{}
|
|
||||||
|
|
||||||
func Command(name string, args ...string) *exec.Cmd {
|
|
||||||
path := getPath(name)
|
|
||||||
|
|
||||||
return exec.Command(path, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPath(name string) string {
|
|
||||||
if path, ok := pathCache[name]; ok {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
path, err := safeexec.LookPath(name)
|
|
||||||
if err != nil {
|
|
||||||
pathCache[name] = name
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
pathCache[name] = path
|
|
||||||
return path
|
|
||||||
}
|
|
@ -11,7 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ func TestNewCmdTaskInstantStop(t *testing.T) {
|
|||||||
reader := bytes.NewBufferString("test")
|
reader := bytes.NewBufferString("test")
|
||||||
start := func() (*exec.Cmd, io.Reader) {
|
start := func() (*exec.Cmd, io.Reader) {
|
||||||
// not actually starting this because it's not necessary
|
// not actually starting this because it's not necessary
|
||||||
cmd := secureexec.Command("blah blah")
|
cmd := exec.Command("blah")
|
||||||
|
|
||||||
close(stop)
|
close(stop)
|
||||||
|
|
||||||
@ -111,7 +110,7 @@ func TestNewCmdTask(t *testing.T) {
|
|||||||
reader := bytes.NewBufferString("test")
|
reader := bytes.NewBufferString("test")
|
||||||
start := func() (*exec.Cmd, io.Reader) {
|
start := func() (*exec.Cmd, io.Reader) {
|
||||||
// not actually starting this because it's not necessary
|
// not actually starting this because it's not necessary
|
||||||
cmd := secureexec.Command("blah blah")
|
cmd := exec.Command("blah")
|
||||||
|
|
||||||
return cmd, reader
|
return cmd, reader
|
||||||
}
|
}
|
||||||
@ -246,7 +245,7 @@ func TestNewCmdTaskRefresh(t *testing.T) {
|
|||||||
reader := BlankLineReader{totalLinesToYield: s.totalTaskLines}
|
reader := BlankLineReader{totalLinesToYield: s.totalTaskLines}
|
||||||
start := func() (*exec.Cmd, io.Reader) {
|
start := func() (*exec.Cmd, io.Reader) {
|
||||||
// not actually starting this because it's not necessary
|
// not actually starting this because it's not necessary
|
||||||
cmd := secureexec.Command("blah blah")
|
cmd := exec.Command("blah")
|
||||||
|
|
||||||
return cmd, &reader
|
return cmd, &reader
|
||||||
}
|
}
|
||||||
|
25
vendor/github.com/cli/safeexec/LICENSE
generated
vendored
25
vendor/github.com/cli/safeexec/LICENSE
generated
vendored
@ -1,25 +0,0 @@
|
|||||||
BSD 2-Clause License
|
|
||||||
|
|
||||||
Copyright (c) 2020, GitHub Inc.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
40
vendor/github.com/cli/safeexec/README.md
generated
vendored
40
vendor/github.com/cli/safeexec/README.md
generated
vendored
@ -1,40 +0,0 @@
|
|||||||
# safeexec
|
|
||||||
|
|
||||||
A Go module that provides a safer alternative to `exec.LookPath()` on Windows.
|
|
||||||
|
|
||||||
The following, relatively common approach to running external commands has a subtle vulnerability on Windows:
|
|
||||||
```go
|
|
||||||
import "os/exec"
|
|
||||||
|
|
||||||
func gitStatus() error {
|
|
||||||
// On Windows, this will result in `.\git.exe` or `.\git.bat` being executed
|
|
||||||
// if either were found in the current working directory.
|
|
||||||
cmd := exec.Command("git", "status")
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Searching the current directory (surprising behavior) before searching folders listed in the PATH environment variable (expected behavior) seems to be intended in Go and unlikely to be changed: https://github.com/golang/go/issues/38736
|
|
||||||
|
|
||||||
Since Go does not provide a version of [`exec.LookPath()`](https://golang.org/pkg/os/exec/#LookPath) that only searches PATH and does not search the current working directory, this module provides a `LookPath` function that works consistently across platforms.
|
|
||||||
|
|
||||||
Example use:
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"github.com/cli/safeexec"
|
|
||||||
)
|
|
||||||
|
|
||||||
func gitStatus() error {
|
|
||||||
gitBin, err := safeexec.LookPath("git")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cmd := exec.Command(gitBin, "status")
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
Ideally, this module would also provide `exec.Command()` and `exec.CommandContext()` equivalents that delegate to the patched version of `LookPath`. However, this doesn't seem possible since `LookPath` may return an error, while `exec.Command/CommandContext()` themselves do not return an error. In the standard library, the resulting `exec.Cmd` struct stores the LookPath error in a private field, but that functionality isn't available to us.
|
|
9
vendor/github.com/cli/safeexec/lookpath.go
generated
vendored
9
vendor/github.com/cli/safeexec/lookpath.go
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package safeexec
|
|
||||||
|
|
||||||
import "os/exec"
|
|
||||||
|
|
||||||
func LookPath(file string) (string, error) {
|
|
||||||
return exec.LookPath(file)
|
|
||||||
}
|
|
120
vendor/github.com/cli/safeexec/lookpath_windows.go
generated
vendored
120
vendor/github.com/cli/safeexec/lookpath_windows.go
generated
vendored
@ -1,120 +0,0 @@
|
|||||||
// Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
// Package safeexec provides alternatives for exec package functions to avoid
|
|
||||||
// accidentally executing binaries found in the current working directory on
|
|
||||||
// Windows.
|
|
||||||
package safeexec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func chkStat(file string) error {
|
|
||||||
d, err := os.Stat(file)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if d.IsDir() {
|
|
||||||
return os.ErrPermission
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasExt(file string) bool {
|
|
||||||
i := strings.LastIndex(file, ".")
|
|
||||||
if i < 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return strings.LastIndexAny(file, `:\/`) < i
|
|
||||||
}
|
|
||||||
|
|
||||||
func findExecutable(file string, exts []string) (string, error) {
|
|
||||||
if len(exts) == 0 {
|
|
||||||
return file, chkStat(file)
|
|
||||||
}
|
|
||||||
if hasExt(file) {
|
|
||||||
if chkStat(file) == nil {
|
|
||||||
return file, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, e := range exts {
|
|
||||||
if f := file + e; chkStat(f) == nil {
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", os.ErrNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookPath searches for an executable named file in the
|
|
||||||
// directories named by the PATH environment variable.
|
|
||||||
// If file contains a slash, it is tried directly and the PATH is not consulted.
|
|
||||||
// LookPath also uses PATHEXT environment variable to match
|
|
||||||
// a suitable candidate.
|
|
||||||
// The result may be an absolute path or a path relative to the current directory.
|
|
||||||
func LookPath(file string) (string, error) {
|
|
||||||
var exts []string
|
|
||||||
x := os.Getenv(`PATHEXT`)
|
|
||||||
if x != "" {
|
|
||||||
for _, e := range strings.Split(strings.ToLower(x), `;`) {
|
|
||||||
if e == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if e[0] != '.' {
|
|
||||||
e = "." + e
|
|
||||||
}
|
|
||||||
exts = append(exts, e)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
exts = []string{".com", ".exe", ".bat", ".cmd"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.ContainsAny(file, `:\/`) {
|
|
||||||
if f, err := findExecutable(file, exts); err == nil {
|
|
||||||
return f, nil
|
|
||||||
} else {
|
|
||||||
return "", &exec.Error{file, err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/golang/go/issues/38736
|
|
||||||
// if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
|
|
||||||
// return f, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
path := os.Getenv("path")
|
|
||||||
for _, dir := range filepath.SplitList(path) {
|
|
||||||
if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", &exec.Error{file, exec.ErrNotFound}
|
|
||||||
}
|
|
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@ -7,9 +7,6 @@ github.com/atotto/clipboard
|
|||||||
# github.com/aybabtme/humanlog v0.4.1
|
# github.com/aybabtme/humanlog v0.4.1
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/aybabtme/humanlog
|
github.com/aybabtme/humanlog
|
||||||
# github.com/cli/safeexec v1.0.0
|
|
||||||
## explicit; go 1.15
|
|
||||||
github.com/cli/safeexec
|
|
||||||
# github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
# github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||||
## explicit
|
## explicit
|
||||||
github.com/cloudfoundry/jibber_jabber
|
github.com/cloudfoundry/jibber_jabber
|
||||||
|
Loading…
x
Reference in New Issue
Block a user