-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
What version of Go are you using (go version
)?
$ go version go version go1.20.1 darwin/amd64
Does this issue reproduce with the latest release?
Yes.
What did you do?
Create an empty directory and save code below in main.go
, run go mod tidy && go run .
.
Note: it contains header Custom/Header: v
.
package main
import (
"log"
"net/mail"
"strings"
)
func main() {
msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400
From: Gopher <[email protected]>
To: Another Gopher <[email protected]>
Subject: Gophers at Gophercon
Custom/Header: v
Message body
`
r := strings.NewReader(msg)
m, err := mail.ReadMessage(r)
if err != nil {
log.Fatal(err)
}
println(m.Header.Get("Custom/Header"))
}
What did you expect to see?
Print value of email header Custom/Header
: v
What did you see instead?
2023/03/04 20:57:52 malformed MIME header line: Custom/Header: v
exit status 1
Function mail.ReadMessage()
calls textproto.ReadMIMEHeader()
, it calls internal function validHeaderValueByte()
(in net/textproto
) to validate characters in email header field, /
in header field is considered as invalid.
The problem is, validHeaderValueByte()
is designed to validate characters in HTTP header, not email header.
According to RFC 5322 "Internet Message Format", section "2.2 Header fields":
A field name MUST be composed of printable US-ASCII characters (i.e.,
characters that have values between 33 and 126, inclusive), except
colon.
Here's full list of printable US-ASCII characters:
https://www.ascii-code.com/characters/printable-characters
For example, characters /
, *
, [
, ]
are allowed in email header field according to RFC doc, but it won't pass current validHeaderFieldByte()
because it's disallowed in http header field. This causes parse error as shown in above sample code. I believe there're some similar issues caused by validHeaderValueByte()
too.
We may need a new exported function like ReadMIMEHeader
but for email (maybe name it as ReadEmailMIMEHeader()
), and allow characters as defined in RFC 5322, but other code in net/textproto
may need some changes too.