summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-06-02 22:32:01 +0700
committerShulhan <ms@kilabit.info>2023-06-04 01:02:25 +0700
commit2c39bba9bde3a9920b27962fb833419c8c0f8d3c (patch)
treea292ffacb3663d4dc85902ec449ecf8c4b1853c5
parent15a0a9c6ad711362ccbdcc491edcac3b9e93d73b (diff)
downloadpakakeh.go-2c39bba9bde3a9920b27962fb833419c8c0f8d3c.tar.xz
lib/email: set the Field Type and unpack its value on ParseField
Once the field Name has detected and its Value is valid, we can unpack the Value based to type that it represent, for example to Date or Mailbox. This changes remove calling to unpack directly in some tests and check an error when testing ParseHeader.
-rw-r--r--lib/email/field.go11
-rw-r--r--lib/email/field_test.go33
-rw-r--r--lib/email/header_test.go13
3 files changed, 22 insertions, 35 deletions
diff --git a/lib/email/field.go b/lib/email/field.go
index 4e7a0ffe..c4b6a437 100644
--- a/lib/email/field.go
+++ b/lib/email/field.go
@@ -29,6 +29,10 @@ type Field struct {
// Value contains "relaxed" canonicalization of field value.
Value []byte
+ // Params contains unpacked parameter from Value.
+ // Not all content type has parameters.
+ Params []Param
+
// oriName contains "simple" canonicalization of field name.
oriName []byte
// oriValue contains "simple" canonicalization of field value.
@@ -78,6 +82,12 @@ func ParseField(raw []byte) (field *Field, rest []byte, err error) {
}
}
+ field.updateType()
+ err = field.unpack()
+ if err != nil {
+ return nil, nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
rest = raw
return field, rest, nil
}
@@ -554,6 +564,7 @@ func (field *Field) unpackContentType() (err error) {
return err
}
+ field.Params = field.contentType.Params
field.unpacked = true
return nil
diff --git a/lib/email/field_test.go b/lib/email/field_test.go
index b8d7c5cb..3a63171b 100644
--- a/lib/email/field_test.go
+++ b/lib/email/field_test.go
@@ -273,10 +273,10 @@ func TestUnpackMailbox(t *testing.T) {
in []byte
}{{
in: []byte("Sender: local\r\n"),
- expErr: `ParseMailboxes: empty or invalid address`,
+ expErr: `ParseField: ParseMailboxes: empty or invalid address`,
}, {
in: []byte("Sender: test@one, test@two\r\n"),
- expErr: "multiple address in sender: 'test@one, test@two\r\n'",
+ expErr: "ParseField: multiple address in sender: 'test@one, test@two\r\n'",
}, {
in: []byte("Sender: <test@one>\r\n"),
exp: "sender:<test@one>\r\n",
@@ -291,12 +291,6 @@ func TestUnpackMailbox(t *testing.T) {
continue
}
- err = field.unpack()
- if err != nil {
- test.Assert(t, "error", c.expErr, err.Error())
- continue
- }
-
test.Assert(t, "Sender:", []byte(c.exp), field.Relaxed())
}
}
@@ -323,12 +317,6 @@ func TestUnpackMailboxList(t *testing.T) {
continue
}
- err = field.unpack()
- if err != nil {
- test.Assert(t, "error", c.expErr, err.Error())
- continue
- }
-
test.Assert(t, "From:", []byte(c.exp), field.Relaxed())
}
}
@@ -340,7 +328,7 @@ func TestField_unpackContentType(t *testing.T) {
in []byte
}{{
in: []byte("Content-Type: text;\r\n"),
- expErr: "ParseContentType: missing subtype",
+ expErr: "ParseField: ParseContentType: missing subtype",
}, {
in: []byte("Content-Type: text/plain;\r\n"),
exp: "text/plain",
@@ -355,21 +343,6 @@ func TestField_unpackContentType(t *testing.T) {
continue
}
- err = field.unpack()
- if err != nil {
- test.Assert(t, "error", c.expErr, err.Error())
- continue
- }
-
- test.Assert(t, "Content-Type", c.exp, field.contentType.String())
- test.Assert(t, "field.unpacked", true, field.unpacked)
-
- err = field.unpack()
- if err != nil {
- test.Assert(t, "error", c.expErr, err.Error())
- continue
- }
-
test.Assert(t, "Content-Type", c.exp, field.contentType.String())
test.Assert(t, "field.unpacked", true, field.unpacked)
}
diff --git a/lib/email/header_test.go b/lib/email/header_test.go
index ce5b9ead..142001b7 100644
--- a/lib/email/header_test.go
+++ b/lib/email/header_test.go
@@ -12,9 +12,10 @@ import (
func TestHeaderBoundary(t *testing.T) {
cases := []struct {
- desc string
- in string
- exp []byte
+ desc string
+ in string
+ expError string
+ exp []byte
}{{
desc: "With no content-type",
in: "From: Nathaniel Borenstein <nsb@bellcore.com>\r\n" +
@@ -23,7 +24,7 @@ func TestHeaderBoundary(t *testing.T) {
"Subject: Sample message\r\n" +
"\r\n",
}, {
- desc: "With invalid content-type",
+ desc: "With invalid content-type boundary",
in: "From: Nathaniel Borenstein <nsb@bellcore.com>\r\n" +
"To: Ned Freed <ned@innosoft.com>\r\n" +
"Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)\r\n" +
@@ -31,6 +32,7 @@ func TestHeaderBoundary(t *testing.T) {
"MIME-Version: 1.0\r\n" +
"Content-type: multipart/mixed; boundary=simple:boundary\r\n" +
"\r\n",
+ expError: `ParseField: ParseContentType: invalid parameter value 'simple:boundary'`,
}, {
desc: "With boundary",
in: "From: Nathaniel Borenstein <nsb@bellcore.com>\r\n" +
@@ -48,7 +50,8 @@ func TestHeaderBoundary(t *testing.T) {
header, _, err := ParseHeader([]byte(c.in))
if err != nil {
- t.Fatal(err)
+ test.Assert(t, `error`, c.expError, err.Error())
+ continue
}
test.Assert(t, "Boundary", c.exp, header.Boundary())