aboutsummaryrefslogtreecommitdiffstats
path: root/modules/git
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-04-12 11:36:34 +0800
committerGitHub <noreply@github.com>2024-04-12 03:36:34 +0000
commitf9fdac9809335729b2ac3227b2a5f71a62fc64ad (patch)
tree20513b0ae479dcc1f059507f4252ef7629d5f77c /modules/git
parent7af074dbeebc3c863618992b43f84ec9e5ab9657 (diff)
downloadgitea-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.go20
-rw-r--r--modules/git/grep_test.go10
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)