aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2024-02-22 04:48:19 +0100
committerGitHub <noreply@github.com>2024-02-22 03:48:19 +0000
commitd6811baf88ca6d58b92d4dc12b1f2a292198751f (patch)
tree95e35c3e2da9b468b10f2ca265d75c609f4929c7 /modules
parentc236e64aca42b9ab0743431bc505033a0cb78b93 (diff)
downloadgitea-d6811baf88ca6d58b92d4dc12b1f2a292198751f.tar.gz
gitea-d6811baf88ca6d58b92d4dc12b1f2a292198751f.zip
Discard unread data of `git cat-file` (#29297)
Fixes #29101 Related #29298 Discard all read data to prevent misinterpreting existing data. Some discard calls were missing in error cases. --------- Co-authored-by: yp05327 <576951401@qq.com>
Diffstat (limited to 'modules')
-rw-r--r--modules/git/batch_reader.go40
-rw-r--r--modules/git/blob_nogogit.go24
-rw-r--r--modules/git/commit_info_nogogit.go3
-rw-r--r--modules/git/pipeline/lfs_nogogit.go4
-rw-r--r--modules/git/repo_commit_nogogit.go3
-rw-r--r--modules/git/repo_language_stats_nogogit.go23
-rw-r--r--modules/git/repo_tag_nogogit.go3
-rw-r--r--modules/git/repo_tree_nogogit.go3
-rw-r--r--modules/git/tree_nogogit.go16
-rw-r--r--modules/git/tree_test.go27
10 files changed, 66 insertions, 80 deletions
diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go
index 53a9393d5f..043dbb44bd 100644
--- a/modules/git/batch_reader.go
+++ b/modules/git/batch_reader.go
@@ -203,16 +203,7 @@ headerLoop:
}
// Discard the rest of the tag
- 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
+ return id, DiscardFull(rd, size-n+1)
}
// ReadTreeID reads a tree ID from a cat-file --batch stream, throwing away the rest of the stream.
@@ -238,16 +229,7 @@ headerLoop:
}
// Discard the rest of the commit
- 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
+ return id, DiscardFull(rd, size-n+1)
}
// git tree files are a list:
@@ -345,3 +327,21 @@ 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 6e8a48b1db..9e1c2a0376 100644
--- a/modules/git/blob_nogogit.go
+++ b/modules/git/blob_nogogit.go
@@ -9,7 +9,6 @@ import (
"bufio"
"bytes"
"io"
- "math"
"code.gitea.io/gitea/modules/log"
)
@@ -104,25 +103,6 @@ func (b *blobReader) Read(p []byte) (n int, err error) {
// Close implements io.Closer
func (b *blobReader) Close() error {
defer b.cancel()
- 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
+
+ return DiscardFull(b.rd, b.n+1)
}
diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go
index e469d2cab6..a5d18694f7 100644
--- a/modules/git/commit_info_nogogit.go
+++ b/modules/git/commit_info_nogogit.go
@@ -151,6 +151,9 @@ 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 a725f4799d..4c65249089 100644
--- a/modules/git/pipeline/lfs_nogogit.go
+++ b/modules/git/pipeline/lfs_nogogit.go
@@ -169,6 +169,10 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
} 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 f0214e1ff8..a7031184e2 100644
--- a/modules/git/repo_commit_nogogit.go
+++ b/modules/git/repo_commit_nogogit.go
@@ -121,8 +121,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID)
return commit, nil
default:
log.Debug("Unknown typ: %s", typ)
- _, err = rd.Discard(int(size) + 1)
- if err != nil {
+ if err := DiscardFull(rd, size+1); 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 1d94ad6c00..d68d7d210a 100644
--- a/modules/git/repo_language_stats_nogogit.go
+++ b/modules/git/repo_language_stats_nogogit.go
@@ -6,10 +6,8 @@
package git
import (
- "bufio"
"bytes"
"io"
- "math"
"strings"
"code.gitea.io/gitea/modules/analyze"
@@ -168,8 +166,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err
return nil, err
}
content = contentBuf.Bytes()
- err = discardFull(batchReader, discard)
- if err != nil {
+ if err := DiscardFull(batchReader, discard); err != nil {
return nil, err
}
}
@@ -212,21 +209,3 @@ 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 5d98fadd54..cbab39f8c5 100644
--- a/modules/git/repo_tag_nogogit.go
+++ b/modules/git/repo_tag_nogogit.go
@@ -103,6 +103,9 @@ func (repo *Repository) getTag(tagID ObjectID, 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 20c92a79ed..582247b4a4 100644
--- a/modules/git/repo_tree_nogogit.go
+++ b/modules/git/repo_tree_nogogit.go
@@ -58,6 +58,9 @@ func (repo *Repository) getTree(id ObjectID) (*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 89d3aebbc0..28d02c7e81 100644
--- a/modules/git/tree_nogogit.go
+++ b/modules/git/tree_nogogit.go
@@ -7,7 +7,6 @@ package git
import (
"io"
- "math"
"strings"
)
@@ -63,19 +62,8 @@ func (t *Tree) ListEntries() (Entries, error) {
}
// Not a tree just use ls-tree instead
- 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
- }
+ if err := DiscardFull(rd, sz+1); err != nil {
+ return nil, err
}
}
diff --git a/modules/git/tree_test.go b/modules/git/tree_test.go
new file mode 100644
index 0000000000..6d2b5c84d5
--- /dev/null
+++ b/modules/git/tree_test.go
@@ -0,0 +1,27 @@
+// 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))
+ }
+}