Repository: jhillyerd/enmime (go)

Issue:
Possible to handle these `From:` values?
I got messages with `From:` like this:
```
From: Name< user@domain.com >
From: Name <sales@a.com >
```
Both report `unclosed angle-addr` error, but MUAs work fine.

I wonder whether we can handle this in enmime. :)

Pull request:
fix: Handle spaces inside angle brackets
closes #339 

Patch:
diff --git a/internal/stringutil/addr.go b/internal/stringutil/addr.go
index c3eaa42..4a02a83 100644
--- a/internal/stringutil/addr.go
+++ b/internal/stringutil/addr.go
@@ -34,6 +34,7 @@ func EnsureCommaDelimitedAddresses(s string) string {
 	inQuotes := false
 	inDomain := false
 	escapeSequence := false
+	inAngles := false
 	sb := strings.Builder{}
 	for i, r := range s {
 		if escapeSequence {
@@ -46,6 +47,19 @@ func EnsureCommaDelimitedAddresses(s string) string {
 			sb.WriteRune(r)
 			continue
 		}
+
+		if r == '<' {
+			inAngles = true
+			sb.WriteRune(r)
+			continue
+		}
+
+		if r == '>' {
+			inAngles = false
+			sb.WriteRune(r)
+			continue
+		}
+
 		if inQuotes {
 			if r == '\\' {
 				escapeSequence = true
@@ -74,13 +88,17 @@ func EnsureCommaDelimitedAddresses(s string) string {
 					sb.WriteRune(r)
 					continue
 				}
-				if r == ' ' {
+				if r == ' ' && !inAngles {
 					inDomain = false
 					sb.WriteRune(',')
 					sb.WriteRune(r)
 					continue
 				}
 			}
+
+			if inAngles && r == ' ' {
+				continue
+			}
 		}
 		sb.WriteRune(r)
 	}


Test patch:
diff --git a/internal/stringutil/addr_test.go b/internal/stringutil/addr_test.go
index 0ce4eac..a4e3624 100644
--- a/internal/stringutil/addr_test.go
+++ b/internal/stringutil/addr_test.go
@@ -108,6 +108,22 @@ func TestCommaDelimitedAddressLists(t *testing.T) {
 			have: `"Joe @ Company" <joe@company.com>;<other@company.com>`,
 			want: `"Joe @ Company" <joe@company.com>,<other@company.com>`,
 		},
+		{
+			have: `"Joe @ Company" <joe@company.com >;<other@company.com>`,
+			want: `"Joe @ Company" <joe@company.com>,<other@company.com>`,
+		},
+		{
+			have: `"Joe @ Company" <joe@company.com>;<other@company.com     >`,
+			want: `"Joe @ Company" <joe@company.com>,<other@company.com>`,
+		},
+		{
+			have: `"Joe @ Company" <joe@company.com>;<  other@company.com>`,
+			want: `"Joe @ Company" <joe@company.com>,<other@company.com>`,
+		},
+		{
+			have: `"Joe @ Company" <  joe@company.com  >;< other@company.com     >`,
+			want: `"Joe @ Company" <joe@company.com>,<other@company.com>`,
+		},
 	}
 	for _, tt := range testData {
 		t.Run(tt.have, func(t *testing.T) {