aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2023-06-19 15:35:50 -0700
committerIan Lance Taylor <iant@google.com>2023-06-21 22:17:05 +0000
commitb59efe6c341c3873ff9088990ec4513336c8685f (patch)
tree56ea2971b82aa53ba47988daedb27dbe3de75d0f
parentc32f1afb4147a7380d9c2efa8503434198190b3a (diff)
downloadgo-b59efe6c341c3873ff9088990ec4513336c8685f.tar.gz
go-b59efe6c341c3873ff9088990ec4513336c8685f.zip
[release-branch.go1.20] net/mail: permit more characters in mail headers
We parse mail messages using net/textproto. For #53188, we tightened up the bytes permitted by net/textproto to match RFC 7230. However, this package uses RFC 5322 which is more permissive. Restore the permisiveness we used to have, so that older code continues to work. For #58862 For #60332 Fixes #60874 Fixes #60875 Change-Id: I5437f5e18a756f6ca61c13c4d8ba727be73eff9a Reviewed-on: https://go-review.googlesource.com/c/go/+/504881 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Damien Neil <dneil@google.com>
-rw-r--r--src/net/mail/message.go51
-rw-r--r--src/net/mail/message_test.go28
2 files changed, 78 insertions, 1 deletions
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index 6268c08f47..862f72de78 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -14,6 +14,7 @@ Notable divergences:
such as breaking addresses across lines.
- No unicode normalization is performed.
- The special characters ()[]:;@\, are allowed to appear unquoted in names.
+ - A leading From line is permitted, as in mbox format (RFC 4155).
*/
package mail
@@ -53,7 +54,7 @@ type Message struct {
func ReadMessage(r io.Reader) (msg *Message, err error) {
tp := textproto.NewReader(bufio.NewReader(r))
- hdr, err := tp.ReadMIMEHeader()
+ hdr, err := readHeader(tp)
if err != nil {
return nil, err
}
@@ -64,6 +65,54 @@ func ReadMessage(r io.Reader) (msg *Message, err error) {
}, nil
}
+// readHeader reads the message headers from r.
+// This is like textproto.ReadMIMEHeader, but doesn't validate.
+// The fix for issue #53188 tightened up net/textproto to enforce
+// restrictions of RFC 7230.
+// This package implements RFC 5322, which does not have those restrictions.
+// This function copies the relevant code from net/textproto,
+// simplified for RFC 5322.
+func readHeader(r *textproto.Reader) (map[string][]string, error) {
+ m := make(map[string][]string)
+
+ // The first line cannot start with a leading space.
+ if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
+ line, err := r.ReadLine()
+ if err != nil {
+ return m, err
+ }
+ return m, errors.New("malformed initial line: " + line)
+ }
+
+ for {
+ kv, err := r.ReadContinuedLine()
+ if kv == "" {
+ return m, err
+ }
+
+ // Key ends at first colon.
+ k, v, ok := strings.Cut(kv, ":")
+ if !ok {
+ return m, errors.New("malformed header line: " + kv)
+ }
+ key := textproto.CanonicalMIMEHeaderKey(k)
+
+ // Permit empty key, because that is what we did in the past.
+ if key == "" {
+ continue
+ }
+
+ // Skip initial spaces in value.
+ value := strings.TrimLeft(v, " \t")
+
+ m[key] = append(m[key], value)
+
+ if err != nil {
+ return m, err
+ }
+ }
+}
+
// Layouts suitable for passing to time.Parse.
// These are tried in order.
var (
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
index 61e50ccfd5..c37f3928f4 100644
--- a/src/net/mail/message_test.go
+++ b/src/net/mail/message_test.go
@@ -39,6 +39,34 @@ So, "Hello".
},
body: "This is a message just to say hello.\nSo, \"Hello\".\n",
},
+ {
+ // RFC 5322 permits any printable ASCII character,
+ // except colon, in a header key. Issue #58862.
+ in: `From: iant@golang.org
+Custom/Header: v
+
+Body
+`,
+ header: Header{
+ "From": []string{"iant@golang.org"},
+ "Custom/Header": []string{"v"},
+ },
+ body: "Body\n",
+ },
+ {
+ // RFC 4155 mbox format. We've historically permitted this,
+ // so we continue to permit it. Issue #60332.
+ in: `From iant@golang.org Mon Jun 19 00:00:00 2023
+From: iant@golang.org
+
+Hello, gophers!
+`,
+ header: Header{
+ "From": []string{"iant@golang.org"},
+ "From iant@golang.org Mon Jun 19 00": []string{"00:00 2023"},
+ },
+ body: "Hello, gophers!\n",
+ },
}
func TestParsing(t *testing.T) {