github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/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 ln == "" || 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 diffStarted = false 35 } 36 } 37 if diff != "" { 38 diff = strings.TrimRight(diff, "\n") + "\n" 39 } 40 err := s.Err() 41 if err == bufio.ErrTooLong { 42 // It's a problem of the incoming patch, rather than anything else. 43 // Anyway, if a patch contains too long lines, we're probably not 44 // interested in it, so let's pretent we didn't see it. 45 diff = "" 46 return 47 } else if err != nil { 48 panic("error while scanning from memory: " + err.Error()) 49 } 50 return 51 } 52 53 var diffRegexps = []*regexp.Regexp{ 54 regexp.MustCompile(`^(---|\+\+\+) [^\s]`), 55 regexp.MustCompile(`^diff --git`), 56 regexp.MustCompile(`^index [0-9a-f]+\.\.[0-9a-f]+`), 57 regexp.MustCompile(`^new file mode [0-9]+`), 58 regexp.MustCompile(`^Index: [^\s]`), 59 } 60 61 func lineMatchesDiffStart(ln string) bool { 62 for _, re := range diffRegexps { 63 if re.MatchString(ln) { 64 return true 65 } 66 } 67 return false 68 }