github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/email/patch.go (about) 1 // Copyright 2017 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package email 5 6 import ( 7 "bufio" 8 "bytes" 9 "regexp" 10 "strings" 11 ) 12 13 func ParsePatch(message []byte) (diff string) { 14 s := bufio.NewScanner(bytes.NewReader(message)) 15 diffStarted := false 16 for s.Scan() { 17 ln := s.Text() 18 if lineMatchesDiffStart(ln) { 19 diffStarted = true 20 diff += ln + "\n" 21 continue 22 } 23 if diffStarted { 24 if ln == "" || ln == "--" || ln == "-- " || ln[0] == '>' { 25 diffStarted = false 26 continue 27 } 28 if strings.HasPrefix(ln, " ") || strings.HasPrefix(ln, "+") || 29 strings.HasPrefix(ln, "-") || strings.HasPrefix(ln, "@") || 30 strings.HasPrefix(ln, "================") { 31 diff += ln + "\n" 32 continue 33 } 34 } 35 } 36 err := s.Err() 37 if err == bufio.ErrTooLong { 38 // It's a problem of the incoming patch, rather than anything else. 39 // Anyway, if a patch contains too long lines, we're probably not 40 // interested in it, so let's pretent we didn't see it. 41 diff = "" 42 return 43 } else if err != nil { 44 panic("error while scanning from memory: " + err.Error()) 45 } 46 return 47 } 48 49 var diffRegexps = []*regexp.Regexp{ 50 regexp.MustCompile(`^(---|\+\+\+) [^\s]`), 51 regexp.MustCompile(`^diff --git`), 52 regexp.MustCompile(`^index [0-9a-f]+\.\.[0-9a-f]+`), 53 regexp.MustCompile(`^new file mode [0-9]+`), 54 regexp.MustCompile(`^Index: [^\s]`), 55 } 56 57 func lineMatchesDiffStart(ln string) bool { 58 for _, re := range diffRegexps { 59 if re.MatchString(ln) { 60 return true 61 } 62 } 63 return false 64 }