Skip to content

Commit

Permalink
Prevent panic on git blame by limiting lines to 4096 bytes at most (#…
Browse files Browse the repository at this point in the history
…13492)

Fix #12440
Closes #13192

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Andrew Thornton <art27@cantab.net>
  • Loading branch information
6543 and zeripath authored Nov 10, 2020
1 parent 0f2ee77 commit 4a71d4d
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions modules/git/blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type BlameReader struct {
cmd *exec.Cmd
pid int64
output io.ReadCloser
scanner *bufio.Scanner
reader *bufio.Reader
lastSha *string
cancel context.CancelFunc
}
Expand All @@ -38,36 +38,58 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
func (r *BlameReader) NextPart() (*BlamePart, error) {
var blamePart *BlamePart

scanner := r.scanner
reader := r.reader

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

for scanner.Scan() {
line := scanner.Text()
var line []byte
var isPrefix bool
var err error

for err != io.EOF {
line, isPrefix, err = reader.ReadLine()
if err != nil && err != io.EOF {
return blamePart, err
}

// Skip empty lines
if len(line) == 0 {
// isPrefix will be false
continue
}

lines := shaLineRegex.FindStringSubmatch(line)
lines := shaLineRegex.FindSubmatch(line)
if lines != nil {
sha1 := lines[1]
sha1 := string(lines[1])

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

if blamePart.Sha != sha1 {
r.lastSha = &sha1
// need to munch to end of line...
for isPrefix {
_, isPrefix, err = reader.ReadLine()
if err != nil && err != io.EOF {
return blamePart, err
}
}
return blamePart, nil
}
} else if line[0] == '\t' {
code := line[1:]

blamePart.Lines = append(blamePart.Lines, code)
blamePart.Lines = append(blamePart.Lines, string(code))
}

// need to munch to end of line...
for isPrefix {
_, isPrefix, err = reader.ReadLine()
if err != nil && err != io.EOF {
return blamePart, err
}
}
}

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

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

scanner := bufio.NewScanner(stdout)
reader := bufio.NewReader(stdout)

return &BlameReader{
cmd,
pid,
stdout,
scanner,
reader,
nil,
cancel,
}, nil
Expand Down

0 comments on commit 4a71d4d

Please sign in to comment.