Repository: jhillyerd/enmime (go)

Issue:
Errors in address format processing without white space
**What I did:**
```
...
From: "=?UTF-8?B?7ZWc6rWt642w7J207YSw7KeE7Z2l7JuQ?="<kodb_pr@kdata.or.kr>
...
```
The following problem occurred during testing with the eml file containing the above sender.

When testing with the same data,  
using the ***mail*** package's **mail.ParseAddressList(m.GetHeader("From"))** works correctly,  
but when using **Envelope.AddressList("From")**, a **mail: no angle-addr** error occurs.


**What I expected:**
([]\*Mail.Address) returned without error,


**What I got:**
returned error
**mail: no angle-addr**

**Release or branch I am using:**
both v0.5.0 and master

(Please attach a sample message if you feel it will help reproduce the issue)


Pull request description:
Resolve #112 by adding "quotedDisplayName" detector

Patch:
diff --git a/header.go b/header.go
index 5503952..64fe012 100644
--- a/header.go
+++ b/header.go
@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"bytes"
 	stderrors "errors"
+	"fmt"
 	"io"
 	"mime"
 	"net/textproto"
@@ -170,7 +171,15 @@ func decodeToUTF8Base64Header(input string) string {
 		return input
 	}
 
-	tokens := strings.FieldsFunc(input, whiteSpaceRune)
+	// The standard lib performs an incremental inspection of this string, where the
+	// "skipSpace" method only strings.trimLeft for spaces and tabs. Here we have a
+	// hard dependency on space existing and not on next expected rune
+	//
+	// For resolving #112 with the least change, I will implement the
+	// "quoted display-name" detector, which will resolve the case specific
+	// issue stated in #112, but only in the case of a quoted display-name
+	// followed, without whitespace, by addr-spec.
+	tokens := strings.FieldsFunc(quotedDisplayName(input), whiteSpaceRune)
 	output := make([]string, len(tokens))
 	for i, token := range tokens {
 		if len(token) > 4 && strings.Contains(token, "=?") {
@@ -196,6 +205,14 @@ func decodeToUTF8Base64Header(input string) string {
 	return strings.Join(output, " ")
 }
 
+func quotedDisplayName(s string) string {
+	if !strings.HasPrefix(s, "\"") {
+		return s
+	}
+	idx := strings.LastIndex(s, "\"")
+	return fmt.Sprintf("%s %s", s[:idx+1], s[idx+1:])
+}
+
 // parseMediaType is a more tolerant implementation of Go's mime.ParseMediaType function.
 func parseMediaType(ctype string) (mtype string, params map[string]string, invalidParams []string, err error) {
 	mtype, params, err = mime.ParseMediaType(ctype)


Test patch:
diff --git a/header_test.go b/header_test.go
index 81465d3..95b2ec0 100644
--- a/header_test.go
+++ b/header_test.go
@@ -148,6 +148,8 @@ func TestDecodeToUTF8Base64Header(t *testing.T) {
 		{"=?UTF-8?Q?Miros=C5=82aw?= <u@h>", "=?UTF-8?b?TWlyb3PFgmF3?= <u@h>"},
 		{"First Last <u@h> (=?iso-8859-1?q?#=a3_c=a9_r=ae_u=b5?=)",
 			"First Last <u@h> (=?UTF-8?b?I8KjIGPCqSBywq4gdcK1?=)"},
+		// Quoted display name without space before angle-addr spec, Issue #112
+		{"\"=?UTF-8?b?TWlyb3PFgmF3?=\"<u@h>", "=?UTF-8?b?Ik1pcm9zxYJhdyI=?= <u@h>"},
 	}
 
 	for _, tt := range testTable {