Skip to content

Commit 38400d6

Browse files
authored
Merge pull request from GHSA-57q7-rxqq-7vgp
Use a safer method to locate the `git` executable (a simpler approach)
2 parents 25d20f9 + deef63c commit 38400d6

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

git/git.go

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ func (oid OID) MarshalJSON() ([]byte, error) {
6161

6262
type Repository struct {
6363
path string
64+
65+
// gitBin is the path of the `git` executable that should be used
66+
// when running commands in this repository.
67+
gitBin string
6468
}
6569

6670
// smartJoin returns the path that can be described as `relPath`
@@ -73,28 +77,36 @@ func smartJoin(path, relPath string) string {
7377
return filepath.Join(path, relPath)
7478
}
7579

80+
// NewRepository creates a new repository object that can be used for
81+
// running `git` commands within that repository.
7682
func NewRepository(path string) (*Repository, error) {
77-
cmd := exec.Command("git", "-C", path, "rev-parse", "--git-dir")
83+
// Find the `git` executable to be used:
84+
gitBin, err := findGitBin()
85+
if err != nil {
86+
return nil, fmt.Errorf(
87+
"could not find 'git' executable (is it in your PATH?): %v", err,
88+
)
89+
}
90+
91+
cmd := exec.Command(gitBin, "-C", path, "rev-parse", "--git-dir")
7892
out, err := cmd.Output()
7993
if err != nil {
8094
switch err := err.(type) {
8195
case *exec.Error:
8296
return nil, fmt.Errorf(
83-
"could not run git (is it in your PATH?): %s",
84-
err.Err,
97+
"could not run '%s': %v", gitBin, err.Err,
8598
)
8699
case *exec.ExitError:
87100
return nil, fmt.Errorf(
88-
"git rev-parse failed: %s",
89-
err.Stderr,
101+
"git rev-parse failed: %s", err.Stderr,
90102
)
91103
default:
92104
return nil, err
93105
}
94106
}
95107
gitDir := smartJoin(path, string(bytes.TrimSpace(out)))
96108

97-
cmd = exec.Command("git", "rev-parse", "--git-path", "shallow")
109+
cmd = exec.Command(gitBin, "rev-parse", "--git-path", "shallow")
98110
cmd.Dir = gitDir
99111
out, err = cmd.Output()
100112
if err != nil {
@@ -108,7 +120,10 @@ func NewRepository(path string) (*Repository, error) {
108120
return nil, errors.New("this appears to be a shallow clone; full clone required")
109121
}
110122

111-
return &Repository{path: gitDir}, nil
123+
return &Repository{
124+
path: gitDir,
125+
gitBin: gitBin,
126+
}, nil
112127
}
113128

114129
func (repo *Repository) gitCommand(callerArgs ...string) *exec.Cmd {
@@ -124,7 +139,7 @@ func (repo *Repository) gitCommand(callerArgs ...string) *exec.Cmd {
124139

125140
args = append(args, callerArgs...)
126141

127-
cmd := exec.Command("git", args...)
142+
cmd := exec.Command(repo.gitBin, args...)
128143

129144
cmd.Env = append(
130145
os.Environ(),

git/git_bin.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package git
2+
3+
import (
4+
"path/filepath"
5+
6+
"github.com/cli/safeexec"
7+
)
8+
9+
// findGitBin finds the `git` binary in PATH that should be used by
10+
// the rest of `git-sizer`. It uses `safeexec` to find the executable,
11+
// because on Windows, `exec.Cmd` looks not only in PATH, but also in
12+
// the current directory. This is a potential risk if the repository
13+
// being scanned is hostile and non-bare because it might possibly
14+
// contain an executable file named `git`.
15+
func findGitBin() (string, error) {
16+
gitBin, err := safeexec.LookPath("git")
17+
if err != nil {
18+
return "", err
19+
}
20+
21+
gitBin, err = filepath.Abs(gitBin)
22+
if err != nil {
23+
return "", err
24+
}
25+
26+
return gitBin, nil
27+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/github/git-sizer
33
go 1.16
44

55
require (
6+
github.com/cli/safeexec v1.0.0
67
github.com/davecgh/go-spew v1.1.1 // indirect
78
github.com/spf13/pflag v1.0.5
89
github.com/stretchr/testify v1.4.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI=
2+
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
13
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
24
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
35
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

0 commit comments

Comments
 (0)