aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-12-19 13:36:40 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-12-19 13:36:40 +0100
commita87e30dc1b7779d39613a85345ec19e449901dd4 (patch)
tree01817a59e15a258b8e8e3d7d369afcc626b5c8cd /pkg
parentf2909d097e6c4709eff07a86e6a3e12534a56a20 (diff)
pkg/email: improve parsing of splitted lines
Allow: full-commit-title-on-next-line This allows commit titles between 70 and 80 cols with gmail. Also be more permissive wrt spaces and tabs.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/email/parser.go61
-rw-r--r--pkg/email/parser_test.go48
2 files changed, 80 insertions, 29 deletions
diff --git a/pkg/email/parser.go b/pkg/email/parser.go
index 67c0159cd..c59736a1b 100644
--- a/pkg/email/parser.go
+++ b/pkg/email/parser.go
@@ -172,42 +172,69 @@ func extractCommand(body []byte) (cmd, args string) {
return
}
cmdPos += len(commandPrefix)
+ for cmdPos < len(body) && body[cmdPos] == ' ' {
+ cmdPos++
+ }
cmdEnd := bytes.IndexByte(body[cmdPos:], '\n')
if cmdEnd == -1 {
cmdEnd = len(body) - cmdPos
}
- cmdLine := strings.TrimSpace(string(body[cmdPos : cmdPos+cmdEnd]))
- if cmdLine == "" {
- return
+ if cmdEnd1 := bytes.IndexByte(body[cmdPos:], '\r'); cmdEnd1 != -1 && cmdEnd1 < cmdEnd {
+ cmdEnd = cmdEnd1
}
- split := strings.Split(cmdLine, " ")
- cmd = split[0]
- var aargs []string
- if len(split) > 1 {
- aargs = split[1:]
+ if cmdEnd1 := bytes.IndexByte(body[cmdPos:], ' '); cmdEnd1 != -1 && cmdEnd1 < cmdEnd {
+ cmdEnd = cmdEnd1
}
- // Text emails are split at 80 columns are the transformation is irrevesible.
- // Try to restore args for some commands that don't have spaces in args.
- want := 0
+ cmd = string(body[cmdPos : cmdPos+cmdEnd])
+ // Some email clients split text emails at 80 columns are the transformation is irrevesible.
+ // We try hard to restore what was there before.
+ // For "test:" command we know that there must be 2 tokens without spaces.
+ // For "fix:"/"dup:" we need a whole non-empty line of text.
switch cmd {
case "test:":
- want = 2
+ args = extractArgsTokens(body[cmdPos+cmdEnd:], 2)
case "test_5_arg_cmd":
- want = 5
+ args = extractArgsTokens(body[cmdPos+cmdEnd:], 5)
+ case "fix:", "dup:":
+ args = extractArgsLine(body[cmdPos+cmdEnd:])
}
- for pos := cmdPos + cmdEnd + 1; len(aargs) < want && pos < len(body); {
+ return
+}
+
+func extractArgsTokens(body []byte, num int) string {
+ var args []string
+ for pos := 0; len(args) < num && pos < len(body); {
lineEnd := bytes.IndexByte(body[pos:], '\n')
if lineEnd == -1 {
lineEnd = len(body) - pos
}
line := strings.TrimSpace(string(body[pos : pos+lineEnd]))
+ for {
+ line1 := strings.Replace(line, " ", " ", -1)
+ if line == line1 {
+ break
+ }
+ line = line1
+ }
if line != "" {
- aargs = append(aargs, strings.Split(line, " ")...)
+ args = append(args, strings.Split(line, " ")...)
}
pos += lineEnd + 1
}
- args = strings.TrimSpace(strings.Join(aargs, " "))
- return
+ return strings.TrimSpace(strings.Join(args, " "))
+}
+
+func extractArgsLine(body []byte) 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')
+ if lineEnd == -1 {
+ lineEnd = len(body) - pos
+ }
+ return strings.TrimSpace(string(body[pos : pos+lineEnd]))
}
func parseBody(r io.Reader, headers mail.Header) (body []byte, attachments [][]byte, err error) {
diff --git a/pkg/email/parser_test.go b/pkg/email/parser_test.go
index e4e79e253..727dafc02 100644
--- a/pkg/email/parser_test.go
+++ b/pkg/email/parser_test.go
@@ -19,6 +19,12 @@ func TestExtractCommand(t *testing.T) {
t.Logf("got : %q %q", cmd, args)
t.Fail()
}
+ cmd, args = extractCommand([]byte(strings.Replace(test.body, "\n", "\r\n", -1)))
+ if cmd != test.cmd || !reflect.DeepEqual(args, test.args) {
+ t.Logf("expect: %q %q", test.cmd, test.args)
+ t.Logf("got : %q %q", cmd, args)
+ t.Fail()
+ }
})
}
}
@@ -118,24 +124,24 @@ var extractCommandTests = []struct {
body: `Hello,
line1
-#syz foo bar baz `,
- cmd: "foo",
+#syz fix: bar baz `,
+ cmd: "fix:",
args: "bar baz",
},
{
body: `Hello,
line1
-#syz foo bar baz
+#syz fix: bar baz
line 2
`,
- cmd: "foo",
+ cmd: "fix:",
args: "bar baz",
},
{
body: `
line1
-> #syz foo bar baz
+> #syz fix: bar baz
line 2
`,
cmd: "",
@@ -173,7 +179,7 @@ locking/core
body: `
#syz test_5_arg_cmd arg1
- arg2 arg3
+ arg2 arg3
arg4
arg5
@@ -206,6 +212,24 @@ arg2
cmd: "test_5_arg_cmd",
args: "arg1 arg2",
},
+ {
+ body: `
+#syz fix:
+arg1 arg2 arg3
+arg4 arg5
+
+`,
+ cmd: "fix:",
+ args: "arg1 arg2 arg3",
+ },
+ {
+ body: `
+#syz fix: arg1 arg2 arg3
+arg4 arg5
+`,
+ cmd: "fix:",
+ args: "arg1 arg2 arg3",
+ },
}
type ParseTest struct {
@@ -223,7 +247,7 @@ Content-Type: text/plain; charset="UTF-8"
text body
second line
-#syz command arg1 arg2 arg3
+#syz fix: arg1 arg2 arg3
last line
--
You received this message because you are subscribed to the Google Groups "syzkaller" group.
@@ -240,7 +264,7 @@ For more options, visit https://groups.google.com/d/optout.`,
Cc: []string{"bob@example.com"},
Body: `text body
second line
-#syz command arg1 arg2 arg3
+#syz fix: arg1 arg2 arg3
last line
--
You received this message because you are subscribed to the Google Groups "syzkaller" group.
@@ -249,7 +273,7 @@ To post to this group, send email to syzkaller@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller/abcdef@google.com.
For more options, visit https://groups.google.com/d/optout.`,
Patch: "",
- Command: "command",
+ Command: "fix:",
CommandArgs: "arg1 arg2 arg3",
}},
@@ -280,7 +304,7 @@ From: Bob <bob@example.com>
To: syzbot <bot@example.com>, Alice <alice@example.com>
Content-Type: text/plain
-#syz command
+#syz invalid
text body
second line
last line`,
@@ -289,12 +313,12 @@ last line`,
Subject: "test subject",
From: "\"Bob\" <bob@example.com>",
Cc: []string{"alice@example.com", "bob@example.com", "bot@example.com"},
- Body: `#syz command
+ Body: `#syz invalid
text body
second line
last line`,
Patch: "",
- Command: "command",
+ Command: "invalid",
CommandArgs: "",
}},