diff options
| -rw-r--r-- | pkg/email/lore/parse.go | 30 | ||||
| -rw-r--r-- | pkg/email/lore/parse_test.go | 143 | ||||
| -rw-r--r-- | pkg/email/lore/read.go | 19 | ||||
| -rw-r--r-- | syz-cluster/email-reporter/main.go | 8 | ||||
| -rw-r--r-- | syz-cluster/email-reporter/stream.go | 7 | ||||
| -rw-r--r-- | syz-cluster/email-reporter/stream_test.go | 4 | ||||
| -rw-r--r-- | syz-cluster/series-tracker/main.go | 2 | ||||
| -rw-r--r-- | tools/syz-lore/query_lkml.go | 3 |
8 files changed, 118 insertions, 98 deletions
diff --git a/pkg/email/lore/parse.go b/pkg/email/lore/parse.go index 9d1a010f5..d71e2a362 100644 --- a/pkg/email/lore/parse.go +++ b/pkg/email/lore/parse.go @@ -20,7 +20,7 @@ type Thread struct { MessageID string Type dashapi.DiscussionType BugIDs []string - Messages []*email.Email + Messages []*Email } // Series represents a single patch series sent over email. @@ -35,19 +35,19 @@ type Series struct { type Patch struct { Seq int - *email.Email + *Email } // Threads extracts individual threads from a list of emails. -func Threads(emails []*email.Email) []*Thread { +func Threads(emails []*Email) []*Thread { return listThreads(emails, 0) } -func listThreads(emails []*email.Email, maxDepth int) []*Thread { +func listThreads(emails []*Email, maxDepth int) []*Thread { ctx := &parseCtx{ maxDepth: maxDepth, - messages: map[string]*email.Email{}, - next: map[*email.Email][]*email.Email{}, + messages: map[string]*Email{}, + next: map[*Email][]*Email{}, } for _, email := range emails { ctx.record(email) @@ -57,7 +57,7 @@ func listThreads(emails []*email.Email, maxDepth int) []*Thread { } // PatchSeries is similar to Threads, but returns only the patch series submitted to the mailing lists. -func PatchSeries(emails []*email.Email) []*Series { +func PatchSeries(emails []*Email) []*Series { var ret []*Series // Normally, all following series patches are sent in response to the first email sent. // So there's no sense to look at deeper replies. @@ -180,17 +180,17 @@ func parsePatchSubject(subject string) (PatchSubject, bool) { type parseCtx struct { maxDepth int threads []*Thread - messages map[string]*email.Email - next map[*email.Email][]*email.Email + messages map[string]*Email + next map[*Email][]*Email } -func (c *parseCtx) record(msg *email.Email) { +func (c *parseCtx) record(msg *Email) { c.messages[msg.MessageID] = msg } func (c *parseCtx) process() { // List messages for which we dont't have ancestors. - nodes := []*email.Email{} + nodes := []*Email{} for _, msg := range c.messages { if msg.InReplyTo == "" || c.messages[msg.InReplyTo] == nil { nodes = append(nodes, msg) @@ -220,15 +220,15 @@ func (c *parseCtx) process() { } } -func (c *parseCtx) visit(msg *email.Email, thread *Thread, depth int) { +func (c *parseCtx) visit(msg *Email, thread *Thread, depth int) { var oldInfo *email.OldThreadInfo if thread != nil { oldInfo = &email.OldThreadInfo{ ThreadType: thread.Type, } } - msgType := DiscussionType(msg) - switch email.NewMessageAction(msg, msgType, oldInfo) { + msgType := DiscussionType(msg.Email) + switch email.NewMessageAction(msg.Email, msgType, oldInfo) { case email.ActionIgnore: thread = nil case email.ActionAppend: @@ -238,7 +238,7 @@ func (c *parseCtx) visit(msg *email.Email, thread *Thread, depth int) { MessageID: msg.MessageID, Subject: msg.Subject, Type: msgType, - Messages: []*email.Email{msg}, + Messages: []*Email{msg}, } c.threads = append(c.threads, thread) } diff --git a/pkg/email/lore/parse_test.go b/pkg/email/lore/parse_test.go index 0480729ff..743ffc976 100644 --- a/pkg/email/lore/parse_test.go +++ b/pkg/email/lore/parse_test.go @@ -6,7 +6,6 @@ package lore import ( "fmt" "sort" - "strings" "testing" "time" @@ -116,29 +115,35 @@ Bug report`, Subject: "Thread A", MessageID: "<A-Base>", Type: dashapi.DiscussionMention, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<A-Base>", - Subject: "Thread A", - Date: time.Date(2017, time.May, 7, 19, 54, 0, 0, zone), - Author: "a@user.com", - Cc: []string{"a@user.com"}, + Email: &email.Email{ + MessageID: "<A-Base>", + Subject: "Thread A", + Date: time.Date(2017, time.May, 7, 19, 54, 0, 0, zone), + Author: "a@user.com", + Cc: []string{"a@user.com"}, + }, }, { - MessageID: "<A-Child-1>", - Subject: "Re: Thread A", - Date: time.Date(2017, time.May, 7, 19, 55, 0, 0, zone), - Author: "b@user.com", - Cc: []string{"a@user.com", "b@user.com"}, - InReplyTo: "<A-Base>", + Email: &email.Email{ + MessageID: "<A-Child-1>", + Subject: "Re: Thread A", + Date: time.Date(2017, time.May, 7, 19, 55, 0, 0, zone), + Author: "b@user.com", + Cc: []string{"a@user.com", "b@user.com"}, + InReplyTo: "<A-Base>", + }, }, { - MessageID: "<A-Child-1-1>", - Subject: "Re: Re: Thread A", - Date: time.Date(2017, time.May, 7, 19, 56, 0, 0, zone), - Author: "c@user.com", - Cc: []string{"a@user.com", "b@user.com", "c@user.com"}, - InReplyTo: "<A-Child-1>", + Email: &email.Email{ + MessageID: "<A-Child-1-1>", + Subject: "Re: Re: Thread A", + Date: time.Date(2017, time.May, 7, 19, 56, 0, 0, zone), + Author: "c@user.com", + Cc: []string{"a@user.com", "b@user.com", "c@user.com"}, + InReplyTo: "<A-Child-1>", + }, }, }, }, @@ -147,32 +152,38 @@ Bug report`, MessageID: "<Bug>", Type: dashapi.DiscussionReport, BugIDs: []string{"4564456"}, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<Bug>", - BugIDs: []string{"4564456"}, - Subject: "[syzbot] Some bug", - Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), - Author: "syzbot@bar.com", - OwnEmail: true, + Email: &email.Email{ + MessageID: "<Bug>", + BugIDs: []string{"4564456"}, + Subject: "[syzbot] Some bug", + Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), + Author: "syzbot@bar.com", + OwnEmail: true, + }, }, { - MessageID: "<Bug-Reply1>", - BugIDs: []string{"4564456"}, - Subject: "Re: [syzbot] Some bug", - Date: time.Date(2017, time.May, 7, 19, 58, 0, 0, zone), - Author: "c@user.com", - Cc: []string{"c@user.com"}, - InReplyTo: "<Bug>", + Email: &email.Email{ + MessageID: "<Bug-Reply1>", + BugIDs: []string{"4564456"}, + Subject: "Re: [syzbot] Some bug", + Date: time.Date(2017, time.May, 7, 19, 58, 0, 0, zone), + Author: "c@user.com", + Cc: []string{"c@user.com"}, + InReplyTo: "<Bug>", + }, }, { - MessageID: "<Bug-Reply2>", - BugIDs: []string{"4564456"}, - Subject: "Re: [syzbot] Some bug", - Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), - Author: "d@user.com", - Cc: []string{"d@user.com"}, - InReplyTo: "<Bug>", + Email: &email.Email{ + MessageID: "<Bug-Reply2>", + BugIDs: []string{"4564456"}, + Subject: "Re: [syzbot] Some bug", + Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), + Author: "d@user.com", + Cc: []string{"d@user.com"}, + InReplyTo: "<Bug>", + }, }, }, }, @@ -181,14 +192,16 @@ Bug report`, MessageID: "<Patch>", Type: dashapi.DiscussionPatch, BugIDs: []string{"12345"}, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<Patch>", - BugIDs: []string{"12345"}, - Subject: "[PATCH] Some bug fixed", - Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), - Author: "e@user.com", - Cc: []string{"e@user.com"}, + Email: &email.Email{ + MessageID: "<Patch>", + BugIDs: []string{"12345"}, + Subject: "[PATCH] Some bug fixed", + Date: time.Date(2017, time.May, 7, 19, 58, 1, 0, zone), + Author: "e@user.com", + Cc: []string{"e@user.com"}, + }, }, }, }, @@ -197,29 +210,29 @@ Bug report`, MessageID: "<Sub-Discussion>", Type: dashapi.DiscussionMention, BugIDs: []string{"4564456"}, - Messages: []*email.Email{ + Messages: []*Email{ { - MessageID: "<Sub-Discussion>", - InReplyTo: "<Unknown>", - Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), - BugIDs: []string{"4564456"}, - Cc: []string{"person@email.com"}, - Subject: "Another bug discussion", - Author: "person@email.com", + Email: &email.Email{ + MessageID: "<Sub-Discussion>", + InReplyTo: "<Unknown>", + Date: time.Date(2017, time.May, 7, 19, 57, 0, 0, zone), + BugIDs: []string{"4564456"}, + Cc: []string{"person@email.com"}, + Subject: "Another bug discussion", + Author: "person@email.com", + }, }, }, }, "<Sub-Discussion-Bot>": nil, } - emails := []*email.Email{} + var emails []*Email for _, m := range messages { - msg, err := email.Parse(strings.NewReader(m), []string{"syzbot@bar.com"}, - []string{}, []string{"bar.com"}) + msg, err := emailFromRaw([]byte(m), []string{"syzbot@bar.com"}, []string{"bar.com"}) if err != nil { t.Fatal(err) } - msg.Body = "" msg.RawCc = nil emails = append(emails, msg) } @@ -418,9 +431,9 @@ Content-Type: text/plain Bug report`, } - emails := []*email.Email{} + var emails []*Email for _, m := range messages { - msg, err := email.Parse(strings.NewReader(m), nil, nil, nil) + msg, err := emailFromRaw([]byte(m), nil, nil) if err != nil { t.Fatal(err) } @@ -437,7 +450,7 @@ Bug report`, Patches: []Patch{ { Seq: 1, - Email: &email.Email{Subject: "[PATCH] Small patch"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH] Small patch"}}, }, }, }, @@ -448,11 +461,11 @@ Bug report`, Patches: []Patch{ { Seq: 1, - Email: &email.Email{Subject: "[PATCH v2 01/02] First patch"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH v2 01/02] First patch"}}, }, { Seq: 2, - Email: &email.Email{Subject: "[PATCH v2 02/02] Second patch"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH v2 02/02] Second patch"}}, }, }, }, @@ -463,7 +476,7 @@ Bug report`, Patches: []Patch{ { Seq: 1, - Email: &email.Email{Subject: "[PATCH 01/03] Series"}, + Email: &Email{Email: &email.Email{Subject: "[PATCH 01/03] Series"}}, }, }, }, diff --git a/pkg/email/lore/read.go b/pkg/email/lore/read.go index d4e68cf33..90a462d9a 100644 --- a/pkg/email/lore/read.go +++ b/pkg/email/lore/read.go @@ -36,19 +36,28 @@ func ReadArchive(repo vcs.Repo, afterCommit string, afterTime time.Time) ([]Emai return ret, nil } -func (er *EmailReader) Parse(emails, domains []string) (*email.Email, error) { +type Email struct { + *email.Email + HasPatch bool +} + +func (er *EmailReader) Parse(emails, domains []string) (*Email, error) { body, err := er.Read() if err != nil { return nil, err } + return emailFromRaw(body, emails, domains) +} + +func emailFromRaw(body []byte, emails, domains []string) (*Email, error) { msg, err := email.Parse(bytes.NewReader(body), emails, nil, domains) if err != nil { return nil, err } + ret := &Email{Email: msg} // Keep memory consumption low. - msg.Body = "" - msg.Patch = "" - // TODO: We definitely don't care about the patch here. Add an option to avoid extracting it? + ret.Body = "" + ret.Patch = "" // TODO: If emails/domains are nil, we also don't need to parse the body at all. - return msg, nil + return ret, nil } diff --git a/syz-cluster/email-reporter/main.go b/syz-cluster/email-reporter/main.go index bef55eb2b..58617549e 100644 --- a/syz-cluster/email-reporter/main.go +++ b/syz-cluster/email-reporter/main.go @@ -10,7 +10,7 @@ import ( "log" "time" - "github.com/google/syzkaller/pkg/email" + "github.com/google/syzkaller/pkg/email/lore" "github.com/google/syzkaller/syz-cluster/pkg/api" "github.com/google/syzkaller/syz-cluster/pkg/app" "github.com/google/syzkaller/syz-cluster/pkg/emailclient" @@ -48,7 +48,7 @@ func main() { emailConfig: cfg.EmailReporting, sender: sender, } - msgCh := make(chan *email.Email, 16) + msgCh := make(chan *lore.Email, 16) eg, loopCtx := errgroup.WithContext(ctx) if cfg.EmailReporting.LoreArchiveURL != "" { fetcher := NewLKMLEmailStream("/lore-repo/checkout", reporterClient, cfg.EmailReporting, msgCh) @@ -56,14 +56,14 @@ func main() { } eg.Go(func() error { for { - var newEmail *email.Email + var newEmail *lore.Email select { case newEmail = <-msgCh: case <-loopCtx.Done(): return nil } log.Printf("received email %q", newEmail.MessageID) - err := handler.IncomingEmail(loopCtx, newEmail) + err := handler.IncomingEmail(loopCtx, newEmail.Email) if err != nil { // Note that we just print an error and go on instead of retrying. // Some retrying may be reasonable, but it also comes with a risk of flooding diff --git a/syz-cluster/email-reporter/stream.go b/syz-cluster/email-reporter/stream.go index a27f71d9f..7b14a3336 100644 --- a/syz-cluster/email-reporter/stream.go +++ b/syz-cluster/email-reporter/stream.go @@ -10,7 +10,6 @@ import ( "strings" "time" - "github.com/google/syzkaller/pkg/email" "github.com/google/syzkaller/pkg/email/lore" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/syz-cluster/pkg/api" @@ -23,13 +22,13 @@ type LKMLEmailStream struct { reporterName string repoFolder string client *api.ReporterClient - newMessages chan *email.Email + newMessages chan *lore.Email lastCommitDate time.Time lastCommit string } func NewLKMLEmailStream(repoFolder string, client *api.ReporterClient, - cfg *app.EmailConfig, writeTo chan *email.Email) *LKMLEmailStream { + cfg *app.EmailConfig, writeTo chan *lore.Email) *LKMLEmailStream { var ownEmails []string if cfg.Dashapi != nil { ownEmails = append(ownEmails, cfg.Dashapi.From) @@ -141,7 +140,7 @@ func (s *LKMLEmailStream) fetchMessages(ctx context.Context) error { } // If the message was sent via the dashapi sender, the report ID wil be a part of the email address. -func (s *LKMLEmailStream) extractMessageID(msg *email.Email) string { +func (s *LKMLEmailStream) extractMessageID(msg *lore.Email) string { if s.cfg.Dashapi == nil { // The mode is not configured. return "" diff --git a/syz-cluster/email-reporter/stream_test.go b/syz-cluster/email-reporter/stream_test.go index db92ce927..ba35489ff 100644 --- a/syz-cluster/email-reporter/stream_test.go +++ b/syz-cluster/email-reporter/stream_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/google/syzkaller/pkg/email" + "github.com/google/syzkaller/pkg/email/lore" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/syz-cluster/pkg/api" "github.com/google/syzkaller/syz-cluster/pkg/app" @@ -38,7 +38,7 @@ func TestEmailStream(t *testing.T) { // Emulate the lore archive and set up the loop. loreArchive := newLoreArchive(t) - writeTo := make(chan *email.Email, 16) + writeTo := make(chan *lore.Email, 16) emailCfg := &app.EmailConfig{ LoreArchiveURL: loreArchive.remoteRef(), SMTP: &app.SMTPConfig{ diff --git a/syz-cluster/series-tracker/main.go b/syz-cluster/series-tracker/main.go index 015f69290..4f57f99cf 100644 --- a/syz-cluster/series-tracker/main.go +++ b/syz-cluster/series-tracker/main.go @@ -111,7 +111,7 @@ func (sf *SeriesFetcher) Update(ctx context.Context, from time.Time) error { list = append(list, repoList...) } - var emails []*email.Email + var emails []*lore.Email idToReader := map[string]lore.EmailReader{} for _, item := range list { // TODO: this could be done in several threads. diff --git a/tools/syz-lore/query_lkml.go b/tools/syz-lore/query_lkml.go index 4b299c3e8..78d3c3910 100644 --- a/tools/syz-lore/query_lkml.go +++ b/tools/syz-lore/query_lkml.go @@ -16,7 +16,6 @@ import ( "time" "github.com/google/syzkaller/dashboard/dashapi" - "github.com/google/syzkaller/pkg/email" "github.com/google/syzkaller/pkg/email/lore" "github.com/google/syzkaller/pkg/hash" "github.com/google/syzkaller/pkg/osutil" @@ -125,7 +124,7 @@ func processArchives(paths, emails, domains []string) []*lore.Thread { } // Set up some worker threads. - var repoEmails []*email.Email + var repoEmails []*lore.Email var mu sync.Mutex var skipped atomic.Int64 for i := 0; i < threads; i++ { |
