aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author65432020-11-10 09:00:20 +0100
committerGitHub2020-11-10 08:00:20 +0000
commit8049de82f98274f5efeb9de3d50d9bc98869abbd (patch)
tree6ec359d19c8a53f11ae4383d238fdcf49df002bd
parent797cb38a4a6e702f959dceeb35d8503133879892 (diff)
Prevent panic on git blame by limiting lines to 4096 bytes at most (#13491)
Fix #12440 Closes #13192 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Andrew Thornton <art27@cantab.net>
-rw-r--r--modules/git/blame.go42
1 files changed, 32 insertions, 10 deletions
diff --git a/modules/git/blame.go b/modules/git/blame.go
index 9aa77dc65..c2129c9e1 100644
--- a/modules/git/blame.go
+++ b/modules/git/blame.go
@@ -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
}
@@ -38,23 +38,30 @@ 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)}
@@ -62,12 +69,27 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
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
+ }
}
}
@@ -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