Repository: jhillyerd/enmime (go)

Issue:
Review detectAttachmentHeader doc comment
Doc comment for `detectAttachmentHeader(header textproto.MIMEHeader) bool` in detect.go appears to be out of date.

Pull request description:
Resolves #86
Updated "detectAttachmentHeader" doc comment to, more accurately, depict the function flow

Patch:
diff --git a/detect.go b/detect.go
index 01e2ef3..32cb140 100644
--- a/detect.go
+++ b/detect.go
@@ -18,10 +18,10 @@ func detectMultipartMessage(root *Part) bool {
 	return strings.HasPrefix(mediatype, ctMultipartPrefix)
 }
 
-// detectAttachmentHeader returns true, if the given header defines an attachment.  First it checks
-// if the Content-Disposition header defines an attachement or inline attachment. If this test is
-// false, the Content-Type header is checked for attachment, but not inline.  Email clients use
-// inline for their text bodies.
+// detectAttachmentHeader returns true, if the given header defines an attachment. First it checks
+// if the Content-Disposition header defines either an attachment part or an inline part with at
+// least one parameter. If this test is false, the Content-Type header is checked for attachment,
+// but not inline. Email clients use inline for their text bodies.
 //
 // Valid Attachment-Headers:
 //
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 {