Skip to content

Commit 4a71d4d

Browse files
6543zeripath
andauthored
Prevent panic on git blame by limiting lines to 4096 bytes at most (go-gitea#13492)
Fix go-gitea#12440 Closes go-gitea#13192 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Andrew Thornton <art27@cantab.net>
1 parent 0f2ee77 commit 4a71d4d

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

modules/git/blame.go

+32-10
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type BlameReader struct {
2727
cmd *exec.Cmd
2828
pid int64
2929
output io.ReadCloser
30-
scanner *bufio.Scanner
30+
reader *bufio.Reader
3131
lastSha *string
3232
cancel context.CancelFunc
3333
}
@@ -38,36 +38,58 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
3838
func (r *BlameReader) NextPart() (*BlamePart, error) {
3939
var blamePart *BlamePart
4040

41-
scanner := r.scanner
41+
reader := r.reader
4242

4343
if r.lastSha != nil {
4444
blamePart = &BlamePart{*r.lastSha, make([]string, 0)}
4545
}
4646

47-
for scanner.Scan() {
48-
line := scanner.Text()
47+
var line []byte
48+
var isPrefix bool
49+
var err error
50+
51+
for err != io.EOF {
52+
line, isPrefix, err = reader.ReadLine()
53+
if err != nil && err != io.EOF {
54+
return blamePart, err
55+
}
4956

50-
// Skip empty lines
5157
if len(line) == 0 {
58+
// isPrefix will be false
5259
continue
5360
}
5461

55-
lines := shaLineRegex.FindStringSubmatch(line)
62+
lines := shaLineRegex.FindSubmatch(line)
5663
if lines != nil {
57-
sha1 := lines[1]
64+
sha1 := string(lines[1])
5865

5966
if blamePart == nil {
6067
blamePart = &BlamePart{sha1, make([]string, 0)}
6168
}
6269

6370
if blamePart.Sha != sha1 {
6471
r.lastSha = &sha1
72+
// need to munch to end of line...
73+
for isPrefix {
74+
_, isPrefix, err = reader.ReadLine()
75+
if err != nil && err != io.EOF {
76+
return blamePart, err
77+
}
78+
}
6579
return blamePart, nil
6680
}
6781
} else if line[0] == '\t' {
6882
code := line[1:]
6983

70-
blamePart.Lines = append(blamePart.Lines, code)
84+
blamePart.Lines = append(blamePart.Lines, string(code))
85+
}
86+
87+
// need to munch to end of line...
88+
for isPrefix {
89+
_, isPrefix, err = reader.ReadLine()
90+
if err != nil && err != io.EOF {
91+
return blamePart, err
92+
}
7193
}
7294
}
7395

@@ -121,13 +143,13 @@ func createBlameReader(ctx context.Context, dir string, command ...string) (*Bla
121143

122144
pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cancel)
123145

124-
scanner := bufio.NewScanner(stdout)
146+
reader := bufio.NewReader(stdout)
125147

126148
return &BlameReader{
127149
cmd,
128150
pid,
129151
stdout,
130-
scanner,
152+
reader,
131153
nil,
132154
cancel,
133155
}, nil

0 commit comments

Comments
 (0)