aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/email/lore/parse.go30
-rw-r--r--pkg/email/lore/parse_test.go143
-rw-r--r--pkg/email/lore/read.go19
-rw-r--r--syz-cluster/email-reporter/main.go8
-rw-r--r--syz-cluster/email-reporter/stream.go7
-rw-r--r--syz-cluster/email-reporter/stream_test.go4
-rw-r--r--syz-cluster/series-tracker/main.go2
-rw-r--r--tools/syz-lore/query_lkml.go3
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++ {