mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Prevent panic on git blame by limiting lines to 4096 bytes at most (#13470)
Fix #12440 Closes #13192 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user