diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2019-05-13 14:15:14 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-05-13 14:15:14 +0200 |
| commit | 69423a1d41ce792ddad1c5636b61df7cb2e91440 (patch) | |
| tree | cedd1e5c0d0d4c098dee2679d510509e56447176 /pkg | |
| parent | 92d5fb8ed39c68c9741df483d5e50f619dacffd9 (diff) | |
pkg/email: allow commands in subject
Several users attempted this and there does not seem
to be any reason to not allow this.
So parse out command from subject as well.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/email/parser.go | 32 | ||||
| -rw-r--r-- | pkg/email/parser_test.go | 23 |
2 files changed, 37 insertions, 18 deletions
diff --git a/pkg/email/parser.go b/pkg/email/parser.go index 0f4e1d40c..9c37331f7 100644 --- a/pkg/email/parser.go +++ b/pkg/email/parser.go @@ -4,7 +4,6 @@ package email import ( - "bytes" "encoding/base64" "fmt" "io" @@ -104,6 +103,7 @@ func Parse(r io.Reader, ownEmails []string) (*Email, error) { return nil, err } bodyStr := string(body) + subject := msg.Header.Get("Subject") cmd := CmdNone patch, cmdStr, cmdArgs := "", "", "" if !fromMe { @@ -116,7 +116,7 @@ func Parse(r io.Reader, ownEmails []string) (*Email, error) { if patch == "" { _, patch, _ = ParsePatch(bodyStr) } - cmd, cmdStr, cmdArgs = extractCommand(body) + cmd, cmdStr, cmdArgs = extractCommand(subject + "\n" + bodyStr) } link := "" if match := groupsLinkRe.FindStringSubmatchIndex(bodyStr); match != nil { @@ -126,10 +126,10 @@ func Parse(r io.Reader, ownEmails []string) (*Email, error) { BugID: bugID, MessageID: msg.Header.Get("Message-ID"), Link: link, - Subject: msg.Header.Get("Subject"), + Subject: subject, From: from[0].String(), Cc: ccList, - Body: string(body), + Body: bodyStr, Patch: patch, Command: cmd, CommandStr: cmdStr, @@ -195,8 +195,8 @@ func CanonicalEmail(email string) string { // extractCommand extracts command to syzbot from email body. // Commands are of the following form: // ^#syz cmd args... -func extractCommand(body []byte) (cmd Command, str, args string) { - cmdPos := bytes.Index(append([]byte{'\n'}, body...), []byte("\n"+commandPrefix)) +func extractCommand(body string) (cmd Command, str, args string) { + cmdPos := strings.Index("\n"+body, "\n"+commandPrefix) if cmdPos == -1 { cmd = CmdNone return @@ -205,17 +205,17 @@ func extractCommand(body []byte) (cmd Command, str, args string) { for cmdPos < len(body) && body[cmdPos] == ' ' { cmdPos++ } - cmdEnd := bytes.IndexByte(body[cmdPos:], '\n') + cmdEnd := strings.IndexByte(body[cmdPos:], '\n') if cmdEnd == -1 { cmdEnd = len(body) - cmdPos } - if cmdEnd1 := bytes.IndexByte(body[cmdPos:], '\r'); cmdEnd1 != -1 && cmdEnd1 < cmdEnd { + if cmdEnd1 := strings.IndexByte(body[cmdPos:], '\r'); cmdEnd1 != -1 && cmdEnd1 < cmdEnd { cmdEnd = cmdEnd1 } - if cmdEnd1 := bytes.IndexByte(body[cmdPos:], ' '); cmdEnd1 != -1 && cmdEnd1 < cmdEnd { + if cmdEnd1 := strings.IndexByte(body[cmdPos:], ' '); cmdEnd1 != -1 && cmdEnd1 < cmdEnd { cmdEnd = cmdEnd1 } - str = string(body[cmdPos : cmdPos+cmdEnd]) + str = body[cmdPos : cmdPos+cmdEnd] switch str { default: cmd = CmdUnknown @@ -253,14 +253,14 @@ func extractCommand(body []byte) (cmd Command, str, args string) { return } -func extractArgsTokens(body []byte, num int) string { +func extractArgsTokens(body string, num int) string { var args []string for pos := 0; len(args) < num && pos < len(body); { - lineEnd := bytes.IndexByte(body[pos:], '\n') + lineEnd := strings.IndexByte(body[pos:], '\n') if lineEnd == -1 { lineEnd = len(body) - pos } - line := strings.TrimSpace(string(body[pos : pos+lineEnd])) + line := strings.TrimSpace(body[pos : pos+lineEnd]) for { line1 := strings.Replace(line, " ", " ", -1) if line == line1 { @@ -276,17 +276,17 @@ func extractArgsTokens(body []byte, num int) string { return strings.TrimSpace(strings.Join(args, " ")) } -func extractArgsLine(body []byte) string { +func extractArgsLine(body string) string { pos := 0 for pos < len(body) && (body[pos] == ' ' || body[pos] == '\t' || body[pos] == '\n' || body[pos] == '\r') { pos++ } - lineEnd := bytes.IndexByte(body[pos:], '\n') + lineEnd := strings.IndexByte(body[pos:], '\n') if lineEnd == -1 { lineEnd = len(body) - pos } - return strings.TrimSpace(string(body[pos : pos+lineEnd])) + return strings.TrimSpace(body[pos : pos+lineEnd]) } func parseBody(r io.Reader, headers mail.Header) ([]byte, [][]byte, error) { diff --git a/pkg/email/parser_test.go b/pkg/email/parser_test.go index 0085adeb9..ba027f8e7 100644 --- a/pkg/email/parser_test.go +++ b/pkg/email/parser_test.go @@ -15,13 +15,13 @@ import ( func TestExtractCommand(t *testing.T) { for i, test := range extractCommandTests { t.Run(fmt.Sprint(i), func(t *testing.T) { - cmd, str, args := extractCommand([]byte(test.body)) + cmd, str, args := extractCommand(test.body) if cmd != test.cmd || str != test.str || !reflect.DeepEqual(args, test.args) { t.Logf("expect: %v %q %q", test.cmd, test.str, test.args) t.Logf("got : %v %q %q", cmd, str, args) t.Fail() } - cmd, str, args = extractCommand([]byte(strings.Replace(test.body, "\n", "\r\n", -1))) + cmd, str, args = extractCommand(strings.Replace(test.body, "\n", "\r\n", -1)) if cmd != test.cmd || str != test.str || !reflect.DeepEqual(args, test.args) { t.Logf("expect: %v %q %q", test.cmd, test.str, test.args) t.Logf("got : %v %q %q", cmd, str, args) @@ -656,4 +656,23 @@ When freeing a lockf struct that already is part of a linked list, make sure to CommandStr: "fix:", CommandArgs: "When freeing a lockf struct that already is part of a linked list, make sure to", }}, + + {`Date: Sun, 7 May 2017 19:54:00 -0700 +Message-ID: <123> +Subject: #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master +From: bob@example.com +To: syzbot <foo+4564456@bar.com> + +nothing to see here`, + Email{ + BugID: "4564456", + MessageID: "<123>", + Subject: "#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master", + From: "<bob@example.com>", + Cc: []string{"bob@example.com"}, + Body: `nothing to see here`, + Command: CmdTest, + CommandStr: "test:", + CommandArgs: "git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master", + }}, } |
