summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-07-27 18:01:06 +0700
committerShulhan <ms@kilabit.info>2024-08-03 13:09:13 +0700
commiteaebb61204abad3760a8353840f8abaccc917216 (patch)
tree1983d73ce2d7117aef7fc79467f0a0590aaca2c6
parentdf32c82e55437af79d8ed85b955daac5ff3fdf4c (diff)
downloadpakakeh.go-eaebb61204abad3760a8353840f8abaccc917216.tar.xz
lib/email: allow message that end lines with LF only
Although, a message from network must end with CRLF, a message from (another) client may have been sanitized and end with LF only.
-rw-r--r--lib/email/field.go5
-rw-r--r--lib/email/field_test.go15
-rw-r--r--lib/email/header.go4
-rw-r--r--lib/email/message_test.go2
4 files changed, 19 insertions, 7 deletions
diff --git a/lib/email/field.go b/lib/email/field.go
index 982f2dd8..77cd9d92 100644
--- a/lib/email/field.go
+++ b/lib/email/field.go
@@ -114,7 +114,7 @@ func (field *Field) parseName(raw []byte) (rest []byte, err error) {
break
}
if raw[x] < 33 || raw[x] > 126 {
- return nil, fmt.Errorf(`%s: invalid character %q`, logp, raw[x])
+ return nil, fmt.Errorf(`%s: %q invalid character %q`, logp, raw[:x], raw[x])
}
}
// Skip WSP before ':'.
@@ -158,6 +158,9 @@ func (field *Field) parseValue(raw []byte) (rest []byte, err error) {
x++
break
}
+ if raw[x] == lf {
+ break
+ }
if raw[x] < 33 || raw[x] > 126 {
return nil, fmt.Errorf(`%s: invalid field value %q`, logp, raw[x])
}
diff --git a/lib/email/field_test.go b/lib/email/field_test.go
index 84a1c6ca..b3716bf1 100644
--- a/lib/email/field_test.go
+++ b/lib/email/field_test.go
@@ -34,7 +34,7 @@ func TestParseField(t *testing.T) {
}, {
desc: "With only CRLF",
raw: []byte("\r\n"),
- expErr: `ParseField: parseName: invalid character '\r'`,
+ expErr: `ParseField: parseName: "" invalid character '\r'`,
}, {
desc: "Without separator and CRLF",
raw: []byte("name"),
@@ -42,7 +42,7 @@ func TestParseField(t *testing.T) {
}, {
desc: "Without separator",
raw: []byte("name\r\n"),
- expErr: `ParseField: parseName: invalid character '\r'`,
+ expErr: `ParseField: parseName: "name" invalid character '\r'`,
}, {
desc: "With space on name",
raw: []byte("na me\r\n"),
@@ -68,9 +68,14 @@ func TestParseField(t *testing.T) {
raw: []byte("name:value"),
expErr: `ParseField: parseValue: invalid or missing termination`,
}, {
- desc: "Without CR",
- raw: []byte("name:value\n"),
- expErr: `ParseField: parseValue: invalid field value '\n'`,
+ desc: `Without CR`,
+ raw: []byte("name:value\n"),
+ exp: &Field{
+ Name: "name",
+ Value: "value\r\n",
+ oriName: "name",
+ oriValue: "value\n",
+ },
}, {
desc: "Without LF",
raw: []byte("name:value\r"),
diff --git a/lib/email/header.go b/lib/email/header.go
index 7c4db291..1e0eae03 100644
--- a/lib/email/header.go
+++ b/lib/email/header.go
@@ -43,6 +43,10 @@ func ParseHeader(raw []byte) (hdr *Header, rest []byte, err error) {
rest = raw
for len(rest) >= 2 {
+ if rest[0] == lf {
+ rest = rest[1:]
+ return hdr, rest, nil
+ }
if rest[0] == cr && rest[1] == lf {
rest = rest[2:]
return hdr, rest, nil
diff --git a/lib/email/message_test.go b/lib/email/message_test.go
index a26f81c6..96dc2a1c 100644
--- a/lib/email/message_test.go
+++ b/lib/email/message_test.go
@@ -69,7 +69,7 @@ func TestMessageParseMessage(t *testing.T) {
exp: "\r\n",
}, {
in: "testdata/invalid-header.txt",
- expErr: `ParseMessage: ParseField: parseValue: invalid field value '\n'`,
+ expErr: `ParseMessage: ParseField: ParseMailboxes: empty or invalid address`,
}, {
in: "testdata/rfc5322-A.6.3.txt",
exp: "from:John Doe <jdoe@machine(comment). example>\r\n" +