| // Copyright 2017 syzkaller project authors. All rights reserved. |
| // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| package email |
| |
| import ( |
| "bufio" |
| "fmt" |
| "strings" |
| ) |
| |
| func ParsePatch(text string) (title string, diff string, err error) { |
| s := bufio.NewScanner(strings.NewReader(text)) |
| parsingDiff := false |
| diffStarted := false |
| lastLine := "" |
| for s.Scan() { |
| ln := s.Text() |
| if strings.HasPrefix(ln, "--- a/") || strings.HasPrefix(ln, "--- /dev/null") { |
| parsingDiff = true |
| if title == "" { |
| title = lastLine |
| } |
| } |
| if parsingDiff { |
| if ln == "" || ln == "--" || ln == "-- " || ln[0] == '>' || |
| ln[0] >= 'A' && ln[0] <= 'Z' { |
| break |
| } |
| diff += ln + "\n" |
| continue |
| } |
| if strings.HasPrefix(ln, "diff --git") { |
| diffStarted = true |
| continue |
| } |
| if strings.HasPrefix(ln, "Subject: ") { |
| title = ln[len("Subject: "):] |
| continue |
| } |
| if ln == "" || title != "" || diffStarted { |
| continue |
| } |
| lastLine = ln |
| if strings.HasPrefix(ln, " ") { |
| title = ln[4:] |
| } |
| } |
| if err = s.Err(); err != nil { |
| return |
| } |
| if strings.Contains(strings.ToLower(title), "[patch") { |
| pos := strings.IndexByte(title, ']') |
| if pos == -1 { |
| err = fmt.Errorf("title contains '[patch' but not ']'") |
| return |
| } |
| title = title[pos+1:] |
| } |
| title = strings.TrimSpace(title) |
| if title == "" { |
| err = fmt.Errorf("failed to extract title") |
| return |
| } |
| if diff == "" { |
| err = fmt.Errorf("failed to extract diff") |
| return |
| } |
| return |
| } |