diff options
author | Michael Muré <batolettre@gmail.com> | 2023-03-04 13:10:38 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2023-03-04 13:20:09 +0100 |
commit | 27c96a4044f05a338d6ac6187135e6b9ac487e9f (patch) | |
tree | f50c44dde7e68722ec8001e9a974d3901e78fda7 /repository/gogit.go | |
parent | d9ac658392cc09d42928f68a60b0e337f7dc7d04 (diff) | |
download | git-bug-27c96a4044f05a338d6ac6187135e6b9ac487e9f.tar.gz |
repo: improve support for gitdir indirection
- add a limited reader to avoid abuse
- support recusive indirection (up to depth 10)
- check that the pointed to repo does exist
Diffstat (limited to 'repository/gogit.go')
-rw-r--r-- | repository/gogit.go | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/repository/gogit.go b/repository/gogit.go index 01eace6d..96d62665 100644 --- a/repository/gogit.go +++ b/repository/gogit.go @@ -5,6 +5,7 @@ import ( "bytes" "errors" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -56,7 +57,7 @@ type GoGitRepo struct { // of "~/myrepo" and a namespace of "git-bug", local storage for the // GoGitRepo will be configured at "~/myrepo/.git/git-bug". func OpenGoGitRepo(path, namespace string, clockLoaders []ClockLoader) (*GoGitRepo, error) { - path, err := detectGitPath(path) + path, err := detectGitPath(path, 0) if err != nil { return nil, err } @@ -160,7 +161,11 @@ func InitBareGoGitRepo(path, namespace string) (*GoGitRepo, error) { }, nil } -func detectGitPath(path string) (string, error) { +func detectGitPath(path string, depth int) (string, error) { + if depth >= 10 { + return "", fmt.Errorf("gitdir loop detected") + } + // normalize the path path, err := filepath.Abs(path) if err != nil { @@ -179,18 +184,22 @@ func detectGitPath(path string) (string, error) { } // We aren't going to defer the dotfile.Close, because we might keep looping, so we have to be sure to // clean up before returning an error - reader := bufio.NewReader(dotfile) + reader := bufio.NewReader(io.LimitReader(dotfile, 2048)) line, _, err := reader.ReadLine() _ = dotfile.Close() if err != nil { - return "", fmt.Errorf(".git exists but is not a direcctory and cannot be read: %w", err) + return "", fmt.Errorf(".git exists but is not a directory and cannot be read: %w", err) } dotContent := string(line) if strings.HasPrefix(dotContent, "gitdir:") { // This is a submodule parent path link. Strip the prefix, clean the string of whitespace just to // be safe, and return dotContent = strings.TrimSpace(strings.TrimPrefix(dotContent, "gitdir: ")) - return dotContent, nil + p, err := detectGitPath(dotContent, depth+1) + if err != nil { + return "", fmt.Errorf(".git gitdir error: %w", err) + } + return p, nil } return "", fmt.Errorf(".git exist but is not a directory or module/workspace file") } |