diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2024-04-12 11:36:34 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-12 03:36:34 +0000 |
commit | f9fdac9809335729b2ac3227b2a5f71a62fc64ad (patch) | |
tree | 20513b0ae479dcc1f059507f4252ef7629d5f77c /modules/git | |
parent | 7af074dbeebc3c863618992b43f84ec9e5ab9657 (diff) | |
download | gitea-f9fdac9809335729b2ac3227b2a5f71a62fc64ad.tar.gz gitea-f9fdac9809335729b2ac3227b2a5f71a62fc64ad.zip |
Limit the max line length when parsing git grep output (#30418)
Diffstat (limited to 'modules/git')
-rw-r--r-- | modules/git/grep.go | 20 | ||||
-rw-r--r-- | modules/git/grep_test.go | 10 |
2 files changed, 26 insertions, 4 deletions
diff --git a/modules/git/grep.go b/modules/git/grep.go index a6c486112a..e7d238e586 100644 --- a/modules/git/grep.go +++ b/modules/git/grep.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "os" + "slices" "strconv" "strings" @@ -27,6 +28,7 @@ type GrepOptions struct { MaxResultLimit int ContextLineNumber int IsFuzzy bool + MaxLineLength int // the maximum length of a line to parse, exceeding chars will be truncated } func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) { @@ -71,10 +73,20 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO defer stdoutReader.Close() isInBlock := false - scanner := bufio.NewScanner(stdoutReader) + rd := bufio.NewReaderSize(stdoutReader, util.IfZero(opts.MaxLineLength, 16*1024)) var res *GrepResult - for scanner.Scan() { - line := scanner.Text() + for { + lineBytes, isPrefix, err := rd.ReadLine() + if isPrefix { + lineBytes = slices.Clone(lineBytes) + for isPrefix && err == nil { + _, isPrefix, err = rd.ReadLine() + } + } + if len(lineBytes) == 0 && err != nil { + break + } + line := string(lineBytes) // the memory of lineBytes is mutable if !isInBlock { if _ /* ref */, filename, ok := strings.Cut(line, ":"); ok { isInBlock = true @@ -100,7 +112,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO res.LineCodes = append(res.LineCodes, lineCode) } } - return scanner.Err() + return nil }, }) // git grep exits by cancel (killed), usually it is caused by the limit of results diff --git a/modules/git/grep_test.go b/modules/git/grep_test.go index b5fa437c53..7f4ded478f 100644 --- a/modules/git/grep_test.go +++ b/modules/git/grep_test.go @@ -41,6 +41,16 @@ func TestGrepSearch(t *testing.T) { }, }, res) + res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{MaxResultLimit: 1, MaxLineLength: 39}) + assert.NoError(t, err) + assert.Equal(t, []*GrepResult{ + { + Filename: "java-hello/main.java", + LineNumbers: []int{3}, + LineCodes: []string{" public static void main(String[] arg"}, + }, + }, res) + res, err = GrepSearch(context.Background(), repo, "no-such-content", GrepOptions{}) assert.NoError(t, err) assert.Len(t, res, 0) |