summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-06-02 14:43:34 +0200
committerRobin Jarry <robin@jarry.cc>2022-06-07 16:19:27 +0200
commit955f7683af104b98ec67ef259f0cbe4c8f2a52ed (patch)
tree61e08f711914fd25cb65ceccb5636cf74692f00c
parent8b6f9719a84fa0ee31d84b9e864495af4f166d92 (diff)
downloadaerc-955f7683af104b98ec67ef259f0cbe4c8f2a52ed.zip
parse: fix content-type parsing error
If an error occurs when parsing the content-type, check if the content-type is quoted; if so, remove quotes. If this is not the case, then return a text/plain content-type as a sane fallback option, so that the message can be at least viewed in plaintext. Fixes: https://todo.sr.ht/~rjarry/aerc/44 Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/lib/parse.go27
-rw-r--r--worker/lib/parse_test.go25
-rw-r--r--worker/lib/testdata/message/valid/quoted-mime-type45
3 files changed, 96 insertions, 1 deletions
diff --git a/worker/lib/parse.go b/worker/lib/parse.go
index 5d95046..bdd927f 100644
--- a/worker/lib/parse.go
+++ b/worker/lib/parse.go
@@ -64,12 +64,37 @@ func splitMIME(m string) (string, string) {
return parts[0], parts[1]
}
+func fixContentType(h message.Header) (string, map[string]string) {
+ ct, rest := h.Get("Content-Type"), ""
+ if i := strings.Index(ct, ";"); i > 0 {
+ ct, rest = ct[:i], ct[i:]
+ }
+
+ // check if there are quotes around the content type
+ if strings.Contains(ct, "\"") {
+ header := strings.ReplaceAll(ct, "\"", "")
+ if rest != "" {
+ header += rest
+ }
+ h.Set("Content-Type", header)
+ if contenttype, params, err := h.ContentType(); err == nil {
+ return contenttype, params
+ }
+ }
+
+ // if all else fails, return text/plain
+ return "text/plain", nil
+}
+
func ParseEntityStructure(e *message.Entity) (*models.BodyStructure, error) {
var body models.BodyStructure
contentType, ctParams, err := e.Header.ContentType()
if err != nil {
- return nil, fmt.Errorf("could not parse content type: %v", err)
+ // try to fix the error; if all measures fail, then return a
+ // text/plain content type to display at least plaintext
+ contentType, ctParams = fixContentType(e.Header)
}
+
mimeType, mimeSubType := splitMIME(contentType)
body.MIMEType = mimeType
body.MIMESubType = mimeSubType
diff --git a/worker/lib/parse_test.go b/worker/lib/parse_test.go
index 1219098..7e5bb36 100644
--- a/worker/lib/parse_test.go
+++ b/worker/lib/parse_test.go
@@ -10,6 +10,31 @@ import (
"git.sr.ht/~rjarry/aerc/models"
)
+func TestMessageInfoParser(t *testing.T) {
+ rootDir := "testdata/message/valid"
+ msgFiles, err := ioutil.ReadDir(rootDir)
+ die(err)
+
+ for _, fi := range msgFiles {
+ if fi.IsDir() {
+ continue
+ }
+
+ p := fi.Name()
+ t.Run(p, func(t *testing.T) {
+ m := newMockRawMessageFromPath(filepath.Join(rootDir, p))
+ mi, err := MessageInfo(m)
+ if err != nil {
+ t.Fatal("Failed to create MessageInfo with:", err)
+ }
+
+ if perr := mi.Error; perr != nil {
+ t.Fatal("Expected no parsing error, but got:", mi.Error)
+ }
+ })
+ }
+}
+
func TestMessageInfoHandledError(t *testing.T) {
rootDir := "testdata/message/invalid"
msgFiles, err := ioutil.ReadDir(rootDir)
diff --git a/worker/lib/testdata/message/valid/quoted-mime-type b/worker/lib/testdata/message/valid/quoted-mime-type
new file mode 100644
index 0000000..d9af28a
--- /dev/null
+++ b/worker/lib/testdata/message/valid/quoted-mime-type
@@ -0,0 +1,45 @@
+Subject: Your ECOLINES tickets
+X-PHP-Originating-Script: 33:functions.inc.php
+From: ECOLINES <ecolines@ecolines.lv>
+Content-Type: multipart/mixed;
+ boundary="PHP-mixed-ba319678ca12656cfb8cd46e736ce09d"
+Message-Id: <E1nvIQS-0004tm-Bc@legacy.ecolines.net>
+Date: Sun, 29 May 2022 15:53:44 +0300
+
+--PHP-mixed-ba319678ca12656cfb8cd46e736ce09d
+Content-Type: multipart/alternative; boundary="PHP-alt-ba319678ca12656cfb8cd46e736ce09d"
+
+--PHP-alt-ba319678ca12656cfb8cd46e736ce09d
+Content-Type: text/plain; charset="UTF-8"
+Content-Transfer-Encoding: 7bit
+
+Your tickets are attached to this message. Also You can print out Your tickets from our website www.ecolines.net<b
+r />
+…
+
+--PHP-alt-ba319678ca12656cfb8cd46e736ce09d
+Content-Type: text/html; charset="UTF-8"
+Content-Transfer-Encoding: 7bit
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+…
+
+--PHP-alt-ba319678ca12656cfb8cd46e736ce09d--
+
+--PHP-mixed-ba319678ca12656cfb8cd46e736ce09d
+Content-Type: "application/pdf"; name="17634428.pdf"
+Content-Disposition: attachment; filename="17634428.pdf"
+Content-Transfer-Encoding: base64
+
+JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/AFkAbwB1AHIAIAB0AGkAYwBrAGUAdCkKL0Ny
+…
+
+--PHP-mixed-ba319678ca12656cfb8cd46e736ce09d
+Content-Type: "application/pdf"; name="invoice-6385490.pdf"
+Content-Disposition: attachment; filename="invoice-6385490.pdf"
+Content-Transfer-Encoding: base64
+
+JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/AEkAbgB2AG8AaQBjAGUpCi9DcmVhdG9yICj+
+…
+
+--PHP-mixed-ba319678ca12656cfb8cd46e736ce09d--