Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 2e5d2f93 authored by Vincent Breitmoser's avatar Vincent Breitmoser Committed by GitHub
Browse files

Merge pull request #3068 from k9mail/fix-encrypted-attached-message

Fix encrypted, attached inner message/rfc822
parents e80aa401 257c2860
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.MimeBodyPart;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.internet.MimeMultipart;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mailstore.util.FileFactory;
import org.apache.commons.io.IOUtils;
import org.apache.james.mime4j.MimeException;
@@ -39,7 +40,7 @@ public class MimePartStreamParser {
                .build();

        MimeStreamParser parser = new MimeStreamParser(parserConfig);
        parser.setContentHandler(new PartBuilder(fileFactory, parsedRootPart));
        parser.setContentHandler(new PartBuilder(parser, fileFactory, parsedRootPart));
        parser.setRecurse();

        try {
@@ -66,11 +67,17 @@ public class MimePartStreamParser {


    private static class PartBuilder implements ContentHandler {
        private MimeStreamParser parser;
        private final FileFactory fileFactory;
        private final MimeBodyPart decryptedRootPart;
        private final Stack<Object> stack = new Stack<>();

        public PartBuilder(FileFactory fileFactory, MimeBodyPart decryptedRootPart) {
        private boolean isMessagePart;
        private boolean isContentDispositionAttachment;

        PartBuilder(MimeStreamParser parser, FileFactory fileFactory,
                MimeBodyPart decryptedRootPart) {
            this.parser = parser;
            this.fileFactory = fileFactory;
            this.decryptedRootPart = decryptedRootPart;
        }
@@ -111,11 +118,13 @@ public class MimePartStreamParser {
        @Override
        public void endBodyPart() throws MimeException {
            stack.pop();
            parser.setRecurse();
        }

        @Override
        public void startHeader() throws MimeException {
            // Do nothing
            isMessagePart = false;
            isContentDispositionAttachment = false;
        }

        @Override
@@ -125,11 +134,22 @@ public class MimePartStreamParser {

            Part part = (Part) stack.peek();
            part.addRawHeader(name, raw);

            String fieldImmediateValue = MimeUtility.getHeaderParameter(parsedField.getBody(), null);
            if ("Content-Type".equalsIgnoreCase(name) && MimeUtility.isMessage(fieldImmediateValue)) {
                isMessagePart = true;
            }

            if ("Content-Disposition".equalsIgnoreCase(name) && "attachment".equalsIgnoreCase(fieldImmediateValue)) {
                isContentDispositionAttachment = true;
            }
        }

        @Override
        public void endHeader() throws MimeException {
            // Do nothing
            if (isMessagePart && isContentDispositionAttachment) {
                parser.setFlat();
            }
        }

        @Override
+75 −0
Original line number Diff line number Diff line
package com.fsck.k9.mailstore


import java.io.ByteArrayInputStream

import com.fsck.k9.mail.internet.MimeBodyPart
import com.fsck.k9.mail.internet.MimeMessage
import com.fsck.k9.mail.internet.MimeMultipart
import org.junit.Test

import org.junit.Assert.*


class MimePartStreamParserTest {
    @Test
    fun innerMessage_DispositionInline() {
        val msg = MimePartStreamParser.parse(null, ByteArrayInputStream(("""From: <x@example.org>
To: <y@example.org>
Subject: Testmail 1
Content-Type: multipart/mixed; boundary=1

--1
Content-Type: text/plain

some text in the first part
--1
Content-Type: message/rfc822; name="message"

To: <z@example.org>
Subject: Hi
Date: now
Content-Type: text/plain

inner text
--1--""").toByteArray()))

        val body = msg.body as MimeMultipart
        assertEquals(2, body.count.toLong())

        val messagePart = body.getBodyPart(1) as MimeBodyPart
        assertEquals("message/rfc822", messagePart.mimeType)
        assertTrue(messagePart.body is MimeMessage)
    }

    @Test
    fun innerMessage_dispositionAttachment() {
        val msg = MimePartStreamParser.parse(null, ByteArrayInputStream(("""From: <x@example.org>
To: <y@example.org>
Subject: Testmail 2
Content-Type: multipart/mixed; boundary=1

--1
Content-Type: text/plain

some text in the first part
--1
Content-Type: message/rfc822; name="message"
Content-Disposition: attachment

To: <z@example.org>
Subject: Hi
Date: now
Content-Type: text/plain

inner text
--1--""").toByteArray()))

        val body = msg.body as MimeMultipart
        assertEquals(2, body.count)

        val messagePart = body.getBodyPart(1) as MimeBodyPart
        assertEquals("message/rfc822", messagePart.mimeType)
        assertTrue(messagePart.body is DeferredFileBody)
    }
}
 No newline at end of file