1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-03 09:07:19 +00:00

Prevent hang in git cat-file if the repository is not a valid repository (Partial #17991) (#17992)

* Prevent hang in git cat-file if the repository is not a valid repository (Partial #17991)

Unfortunately it appears that if git cat-file is run in an invalid
repository it will hang until stdin is closed. This will result in
deadlocked /pulls pages and dangling git cat-file calls if a broken
repository is tried to be reviewed or pulls exists for a broken
repository.

Signed-off-by: Andrew Thornton <art27@cantab.net>

* placate lint

Signed-off-by: Andrew Thornton <art27@cantab.net>

* fix compilation bug

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Add the missing directories to the testrepos

* fixup! Add the missing directories to the testrepos

* and ensure that all of the other places have the objects directories too

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
zeripath
2021-12-17 02:08:00 +00:00
committed by GitHub
parent 3a77465e4e
commit 3ae4c4898b
10 changed files with 150 additions and 2 deletions

View File

@ -27,6 +27,20 @@ type WriteCloserError interface {
CloseWithError(err error) error
}
// EnsureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository.
// Run before opening git cat-file.
// This is needed otherwise the git cat-file will hang for invalid repositories.
func EnsureValidGitRepository(ctx context.Context, repoPath string) error {
stderr := strings.Builder{}
err := NewCommandContext(ctx, "rev-parse").
SetDescription(fmt.Sprintf("%s rev-parse [repo_path: %s]", GitExecutable, repoPath)).
RunInDirFullPipeline(repoPath, nil, &stderr, nil)
if err != nil {
return ConcatenateError(err, (&stderr).String())
}
return nil
}
// CatFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function
func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
batchStdinReader, batchStdinWriter := io.Pipe()

View File

@ -43,6 +43,11 @@ func OpenRepository(repoPath string) (*Repository, error) {
return nil, errors.New("no such file or directory")
}
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
if err := EnsureValidGitRepository(DefaultContext, repoPath); err != nil {
return nil, err
}
repo := &Repository{
Path: repoPath,
tagCache: newObjectCache(),

View File

@ -38,7 +38,10 @@ func (repo *Repository) ResolveReference(name string) (string, error) {
func (repo *Repository) GetRefCommitID(name string) (string, error) {
wr, rd, cancel := repo.CatFileBatchCheck()
defer cancel()
_, _ = wr.Write([]byte(name + "\n"))
_, err := wr.Write([]byte(name + "\n"))
if err != nil {
return "", err
}
shaBs, _, _, err := ReadBatchLine(rd)
if IsErrNotExist(err) {
return "", ErrNotExist{name, ""}