aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/email/parser.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-07-05 19:45:56 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-07-05 19:45:56 +0200
commit6fe1bcf384a34fdfc1704ff98ee5151a75d031a2 (patch)
treeec0fc9cc5a17cdafacd6a04bb599865a2d959dbe /pkg/email/parser.go
parent6231964849eb9362c20b82279d92da96fb556209 (diff)
pkg/email: add AddAddrContext/RemoveAddrContext
Replace extractBugID function with more general AddAddrContext/RemoveAddrContext.
Diffstat (limited to 'pkg/email/parser.go')
-rw-r--r--pkg/email/parser.go69
1 files changed, 39 insertions, 30 deletions
diff --git a/pkg/email/parser.go b/pkg/email/parser.go
index 5d8c54d2c..f0297a588 100644
--- a/pkg/email/parser.go
+++ b/pkg/email/parser.go
@@ -50,11 +50,12 @@ func Parse(r io.Reader, ownEmail string) (*Email, error) {
bugID := ""
var ccList []string
for _, addr := range append(cc, to...) {
- bugID1, own := extractBugID(addr.Address, ownEmail)
- if bugID == "" {
- bugID = bugID1
- }
- if !own {
+ cleaned, context, _ := RemoveAddrContext(addr.Address)
+ if cleaned == ownEmail {
+ if bugID == "" {
+ bugID = context
+ }
+ } else {
ccList = append(ccList, addr.String())
}
}
@@ -87,31 +88,39 @@ func Parse(r io.Reader, ownEmail string) (*Email, error) {
return email, nil
}
-// extractBugID extracts bug ID encoded in receiver email.
-// We send emails from <something+BUG_ID_HASH@something.com>.
-// from is potentially such email address, canonical is <something@something.com>.
-// This function returns BUG_ID_HASH, or an empty string if from does not contain
-// the hash or is different from canonical.
-func extractBugID(from, canonical string) (string, bool) {
- if email, err := mail.ParseAddress(canonical); err == nil {
- canonical = email.Address
- }
- canonical = strings.ToLower(canonical)
- plusPos := strings.IndexByte(from, '+')
- if plusPos == -1 {
- return "", strings.ToLower(from) == canonical
- }
- atPos := strings.IndexByte(from[plusPos:], '@')
- if atPos == -1 {
- return "", false
- }
- user := from[:plusPos]
- domain := from[plusPos+atPos:]
- hash := from[plusPos+1 : plusPos+atPos]
- if strings.ToLower(user+domain) != canonical {
- return "", false
- }
- return hash, true
+// AddAddrContext embeds context into local part of the provided email address using '+'.
+// Returns the resulting email address.
+func AddAddrContext(email, context string) (string, error) {
+ addr, err := mail.ParseAddress(email)
+ if err != nil {
+ return "", fmt.Errorf("failed to parse %q as email: %v", email, err)
+ }
+ at := strings.IndexByte(addr.Address, '@')
+ if at == -1 {
+ return "", fmt.Errorf("failed to parse %q as email: no @", email)
+ }
+ addr.Address = addr.Address[:at] + "+" + context + addr.Address[at:]
+ return addr.String(), nil
+}
+
+// RemoveAddrContext extracts context after '+' from the local part of the provided email address.
+// Returns address without the context and the context.
+func RemoveAddrContext(email string) (string, string, error) {
+ addr, err := mail.ParseAddress(email)
+ if err != nil {
+ return "", "", fmt.Errorf("failed to parse %q as email: %v", email, err)
+ }
+ at := strings.IndexByte(addr.Address, '@')
+ if at == -1 {
+ return "", "", fmt.Errorf("failed to parse %q as email: no @", email)
+ }
+ plus := strings.LastIndexByte(addr.Address[:at], '+')
+ if plus == -1 {
+ return email, "", nil
+ }
+ context := addr.Address[plus+1 : at]
+ addr.Address = addr.Address[:plus] + addr.Address[at:]
+ return addr.String(), context, nil
}
// extractCommand extracts command to syzbot from email body.