diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index d8f4886d0625f..7a44e6295c4e2 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -203,7 +203,16 @@ headerLoop: } // Discard the rest of the tag - return id, DiscardFull(rd, size-n+1) + discard := size - n + 1 + for discard > math.MaxInt32 { + _, err := rd.Discard(math.MaxInt32) + if err != nil { + return id, err + } + discard -= math.MaxInt32 + } + _, err := rd.Discard(int(discard)) + return id, err } // ReadTreeID reads a tree ID from a cat-file --batch stream, throwing away the rest of the stream. @@ -229,7 +238,16 @@ headerLoop: } // Discard the rest of the commit - return id, DiscardFull(rd, size-n+1) + discard := size - n + 1 + for discard > math.MaxInt32 { + _, err := rd.Discard(math.MaxInt32) + if err != nil { + return id, err + } + discard -= math.MaxInt32 + } + _, err := rd.Discard(int(discard)) + return id, err } // git tree files are a list: @@ -327,21 +345,3 @@ func init() { _, filename, _, _ := runtime.Caller(0) callerPrefix = strings.TrimSuffix(filename, "modules/git/batch_reader.go") } - -func DiscardFull(rd *bufio.Reader, discard int64) error { - if discard > math.MaxInt32 { - n, err := rd.Discard(math.MaxInt32) - discard -= int64(n) - if err != nil { - return err - } - } - for discard > 0 { - n, err := rd.Discard(int(discard)) - discard -= int64(n) - if err != nil { - return err - } - } - return nil -} diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go index 6a6edaf5b667d..511332eb50641 100644 --- a/modules/git/blob_nogogit.go +++ b/modules/git/blob_nogogit.go @@ -9,6 +9,7 @@ import ( "bufio" "bytes" "io" + "math" "code.gitea.io/gitea/modules/log" ) @@ -103,6 +104,25 @@ func (b *blobReader) Read(p []byte) (n int, err error) { // Close implements io.Closer func (b *blobReader) Close() error { defer b.cancel() - - return DiscardFull(b.rd, b.n+1) + if b.n > 0 { + for b.n > math.MaxInt32 { + n, err := b.rd.Discard(math.MaxInt32) + b.n -= int64(n) + if err != nil { + return err + } + b.n -= math.MaxInt32 + } + n, err := b.rd.Discard(int(b.n)) + b.n -= int64(n) + if err != nil { + return err + } + } + if b.n == 0 { + _, err := b.rd.Discard(1) + b.n-- + return err + } + return nil } diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index a5d18694f7384..e469d2cab6374 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -151,9 +151,6 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, return nil, err } if typ != "commit" { - if err := DiscardFull(batchReader, size+1); err != nil { - return nil, err - } return nil, fmt.Errorf("unexpected type: %s for commit id: %s", typ, commitID) } c, err = CommitFromReader(commit.repo, MustIDFromString(commitID), io.LimitReader(batchReader, size)) diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index 2ec6031540a85..49390f7c00c66 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -170,10 +170,6 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { } else { break commitReadingLoop } - default: - if err := git.DiscardFull(batchReader, size+1); err != nil { - return nil, err - } } } } diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index 73e441b7d9ecb..d5eb723100a73 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -121,7 +121,8 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co return commit, nil default: log.Debug("Unknown typ: %s", typ) - if err := DiscardFull(rd, size+1); err != nil { + _, err = rd.Discard(int(size) + 1) + if err != nil { return nil, err } return nil, ErrNotExist{ diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go index d68d7d210a38d..1d94ad6c00f4b 100644 --- a/modules/git/repo_language_stats_nogogit.go +++ b/modules/git/repo_language_stats_nogogit.go @@ -6,8 +6,10 @@ package git import ( + "bufio" "bytes" "io" + "math" "strings" "code.gitea.io/gitea/modules/analyze" @@ -166,7 +168,8 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err return nil, err } content = contentBuf.Bytes() - if err := DiscardFull(batchReader, discard); err != nil { + err = discardFull(batchReader, discard) + if err != nil { return nil, err } } @@ -209,3 +212,21 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err return mergeLanguageStats(sizes), nil } + +func discardFull(rd *bufio.Reader, discard int64) error { + if discard > math.MaxInt32 { + n, err := rd.Discard(math.MaxInt32) + discard -= int64(n) + if err != nil { + return err + } + } + for discard > 0 { + n, err := rd.Discard(int(discard)) + discard -= int64(n) + if err != nil { + return err + } + } + return nil +} diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index 19023741e30d1..9080ffcfd7820 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -103,9 +103,6 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { return nil, err } if typ != "tag" { - if err := DiscardFull(rd, size+1); err != nil { - return nil, err - } return nil, ErrNotExist{ID: tagID.String()} } diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index 3ec6fcae9208e..4fd77df2b8249 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -58,9 +58,6 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { tree.entriesParsed = true return tree, nil default: - if err := DiscardFull(rd, size+1); err != nil { - return nil, err - } return nil, ErrNotExist{ ID: id.String(), } diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go index a1b0acdafadd3..ef598d7e91327 100644 --- a/modules/git/tree_nogogit.go +++ b/modules/git/tree_nogogit.go @@ -7,6 +7,7 @@ package git import ( "io" + "math" "strings" ) @@ -62,8 +63,19 @@ func (t *Tree) ListEntries() (Entries, error) { } // Not a tree just use ls-tree instead - if err := DiscardFull(rd, sz+1); err != nil { - return nil, err + for sz > math.MaxInt32 { + discarded, err := rd.Discard(math.MaxInt32) + sz -= int64(discarded) + if err != nil { + return nil, err + } + } + for sz > 0 { + discarded, err := rd.Discard(int(sz)) + sz -= int64(discarded) + if err != nil { + return nil, err + } } } diff --git a/modules/git/tree_test.go b/modules/git/tree_test.go deleted file mode 100644 index 6d2b5c84d5069..0000000000000 --- a/modules/git/tree_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package git - -import ( - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSubTree_Issue29101(t *testing.T) { - repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) - assert.NoError(t, err) - defer repo.Close() - - commit, err := repo.GetCommit("ce064814f4a0d337b333e646ece456cd39fab612") - assert.NoError(t, err) - - // old code could produce a different error if called multiple times - for i := 0; i < 10; i++ { - _, err = commit.SubTree("file1.txt") - assert.Error(t, err) - assert.True(t, IsErrNotExist(err)) - } -}