aboutsummaryrefslogtreecommitdiffstats
path: root/syz-cluster/series-tracker
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-02-18 18:13:35 +0100
committerAleksandr Nogikh <nogikh@google.com>2025-02-19 14:51:27 +0000
commit3b79d489db1ad98df7f1986a4695f581e6be9be3 (patch)
tree5f708b9863a1a9707113e7216084da887333cbfa /syz-cluster/series-tracker
parentcbd8edabd77d676c77120894f85f37dbf22d32a1 (diff)
syz-cluster/series-tracker: collect Cc addresses
Extract Cc addresses for the processed patch series.
Diffstat (limited to 'syz-cluster/series-tracker')
-rw-r--r--syz-cluster/series-tracker/main.go38
-rw-r--r--syz-cluster/series-tracker/main_test.go45
2 files changed, 81 insertions, 2 deletions
diff --git a/syz-cluster/series-tracker/main.go b/syz-cluster/series-tracker/main.go
index 6a0379fc2..a9de34a31 100644
--- a/syz-cluster/series-tracker/main.go
+++ b/syz-cluster/series-tracker/main.go
@@ -4,12 +4,17 @@
package main
import (
+ "bytes"
"context"
+ "errors"
"flag"
"fmt"
"log"
+ "maps"
"path/filepath"
"regexp"
+ "slices"
+ "sort"
"time"
"github.com/google/syzkaller/pkg/email"
@@ -141,11 +146,18 @@ func (sf *SeriesFetcher) handleSeries(ctx context.Context, series *lore.Series,
Link: "https://lore.kernel.org/all/" + series.MessageID,
PublishedAt: date,
}
- for _, patch := range series.Patches {
- body, err := idToReader[patch.MessageID].Read()
+ sp := seriesProcessor{}
+ for i, patch := range series.Patches {
+ raw, err := idToReader[patch.MessageID].Read()
if err != nil {
return fmt.Errorf("failed to extract %q: %w", patch.MessageID, err)
}
+ body, err := sp.Process(raw)
+ if err != nil {
+ // Fall back to the raw message.
+ body = raw
+ log.Printf("failed to parse %d: %v", i, err)
+ }
apiSeries.Patches = append(apiSeries.Patches, api.SeriesPatch{
Seq: patch.Seq,
Title: patch.Subject,
@@ -153,6 +165,7 @@ func (sf *SeriesFetcher) handleSeries(ctx context.Context, series *lore.Series,
Body: body,
})
}
+ apiSeries.Cc = sp.Emails()
ret, err := sf.client.UploadSeries(ctx, apiSeries)
if err != nil {
return fmt.Errorf("failed to save series: %w", err)
@@ -170,6 +183,27 @@ func (sf *SeriesFetcher) handleSeries(ctx context.Context, series *lore.Series,
return nil
}
+type seriesProcessor map[string]struct{}
+
+var errFailedToParse = errors.New("failed to parse the email")
+
+func (sp seriesProcessor) Process(raw []byte) ([]byte, error) {
+ msg, err := email.Parse(bytes.NewReader(raw), nil, nil, nil)
+ if err != nil {
+ return raw, fmt.Errorf("%w: %w", errFailedToParse, err)
+ }
+ for _, email := range msg.Cc {
+ sp[email] = struct{}{}
+ }
+ return []byte(msg.Body), nil
+}
+
+func (sp seriesProcessor) Emails() []string {
+ list := slices.Collect(maps.Keys(sp))
+ sort.Strings(list)
+ return list
+}
+
func logSeries(series *lore.Series) {
log.Printf("series ID=%s Subject=%s Patches=%d Version=%d Corrupted=%q",
series.MessageID, series.Subject, len(series.Patches), series.Version,
diff --git a/syz-cluster/series-tracker/main_test.go b/syz-cluster/series-tracker/main_test.go
new file mode 100644
index 000000000..805335076
--- /dev/null
+++ b/syz-cluster/series-tracker/main_test.go
@@ -0,0 +1,45 @@
+// Copyright 2025 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 main
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSeriesProcessor(t *testing.T) {
+ emails := []string{
+ `Date: Sun, 7 May 2017 19:54:00 -0700
+Message-ID: <123>
+Subject: test subject
+From: Bob <bob@example.com>
+To: A <a@a.com>
+Cc: B <b@b.com>, C <b@b.com>
+
+first body`,
+ `Date: Sun, 7 May 2017 19:55:00 -0700
+Message-ID: <234>
+Subject: test subject2
+From: Bob <bob@example.com>
+To: A <a@a.com>
+Cc: D <d@d.com>
+
+second body`,
+ }
+ bodies := []string{"first body", "second body"}
+
+ sp := seriesProcessor{}
+ for i, raw := range emails {
+ body, err := sp.Process([]byte(raw))
+ if err != nil {
+ t.Fatal(err)
+ }
+ assert.Equal(t, []byte(bodies[i]), body)
+ }
+ assert.Equal(t, []string{
+ "a@a.com", "b@b.com",
+ "bob@example.com", "d@d.com",
+ }, sp.Emails())
+}