Prevent panic on git blame by limiting lines to 4096 bytes at most (#13492)
Fix #12440 Closes #13192 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
0f2ee77968
commit
4a71d4de68
1 changed files with 32 additions and 10 deletions
|
@ -27,7 +27,7 @@ type BlameReader struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
pid int64
|
pid int64
|
||||||
output io.ReadCloser
|
output io.ReadCloser
|
||||||
scanner *bufio.Scanner
|
reader *bufio.Reader
|
||||||
lastSha *string
|
lastSha *string
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
}
|
}
|
||||||
|
@ -38,23 +38,30 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
|
||||||
func (r *BlameReader) NextPart() (*BlamePart, error) {
|
func (r *BlameReader) NextPart() (*BlamePart, error) {
|
||||||
var blamePart *BlamePart
|
var blamePart *BlamePart
|
||||||
|
|
||||||
scanner := r.scanner
|
reader := r.reader
|
||||||
|
|
||||||
if r.lastSha != nil {
|
if r.lastSha != nil {
|
||||||
blamePart = &BlamePart{*r.lastSha, make([]string, 0)}
|
blamePart = &BlamePart{*r.lastSha, make([]string, 0)}
|
||||||
}
|
}
|
||||||
|
|
||||||
for scanner.Scan() {
|
var line []byte
|
||||||
line := scanner.Text()
|
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 {
|
if len(line) == 0 {
|
||||||
|
// isPrefix will be false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := shaLineRegex.FindStringSubmatch(line)
|
lines := shaLineRegex.FindSubmatch(line)
|
||||||
if lines != nil {
|
if lines != nil {
|
||||||
sha1 := lines[1]
|
sha1 := string(lines[1])
|
||||||
|
|
||||||
if blamePart == nil {
|
if blamePart == nil {
|
||||||
blamePart = &BlamePart{sha1, make([]string, 0)}
|
blamePart = &BlamePart{sha1, make([]string, 0)}
|
||||||
|
@ -62,12 +69,27 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
|
||||||
|
|
||||||
if blamePart.Sha != sha1 {
|
if blamePart.Sha != sha1 {
|
||||||
r.lastSha = &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
|
return blamePart, nil
|
||||||
}
|
}
|
||||||
} else if line[0] == '\t' {
|
} else if line[0] == '\t' {
|
||||||
code := line[1:]
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cancel)
|
||||||
|
|
||||||
scanner := bufio.NewScanner(stdout)
|
reader := bufio.NewReader(stdout)
|
||||||
|
|
||||||
return &BlameReader{
|
return &BlameReader{
|
||||||
cmd,
|
cmd,
|
||||||
pid,
|
pid,
|
||||||
stdout,
|
stdout,
|
||||||
scanner,
|
reader,
|
||||||
nil,
|
nil,
|
||||||
cancel,
|
cancel,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
Reference in a new issue