Skip to content

Commit

Permalink
IMAP BODYSTRUCTURE parse error with long, encoded filenames (backport,
Browse files Browse the repository at this point in the history
…fixes #499)

Backport of #498
  • Loading branch information
marcelmay committed Nov 5, 2022
1 parent 55d66f3 commit a073b3a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
Expand Up @@ -26,7 +26,7 @@
* Message Sequence Numbers or UIDs.
* <p> reinitialize() must be called on deserialization to reset Logger
*
* Reference: RFC 2060 - para 2.3 https://www.ietf.org/rfc/rfc2060.txt
* Reference: <a href="https://www.ietf.org/rfc/rfc2060.txt">RFC 2060 - para 2.3</a>
*
* @author <a href="mailto:sascha@kulawik.de">Sascha Kulawik</a>
* @author <a href="mailto:charles@benett1.demon.co.uk">Charles Benett</a>
Expand Down Expand Up @@ -121,7 +121,7 @@ void setUID(int thisUID) {
}

/**
* Parses key data items from a MimeMessage for seperate storage.
* Parses key data items from a MimeMessage for separate storage.
* TODO this is a mess, and should be completely revamped.
*/
void parseMimePart(MimePart part) {
Expand Down Expand Up @@ -651,12 +651,15 @@ public Header(String line) {
String[] strs = line.split(";");
if (0 != strs.length) {
value = strs[0];
params = new HashSet<>(strs.length);
params = new HashSet<>();
for (int i = 1; i < strs.length; i++) {
String p = strs[i].trim();
int e = p.indexOf('=');
String key = p.substring(0, e);
String val = p.substring(e + 1);
String val = p.substring(e + 1)
// Workaround for continuation bug?
// https://github.com/greenmail-mail-test/greenmail/issues/498
.replaceAll("\r\n[\t\u0020]"," ");
p = Q + strip(key) + Q + SP + Q + strip(val) + Q;
params.add(p);
}
Expand Down
Expand Up @@ -144,7 +144,7 @@ public void testTextPlainWithUTF8SenderAndReceiverAndGreenMailApi() throws Messa
MimeMessage receivedMessage = greenMail.getReceivedMessages()[0];
assertThat(receivedMessage.getFrom()[0].toString()).isEqualTo(fromAddress.toString());
assertThat(Arrays.stream(receivedMessage.getAllRecipients()).map(Object::toString).toArray())
.isEqualTo(new String[] { toAddress.toString() });
.isEqualTo(new String[]{toAddress.toString()});

greenMail.setUser("to@localhost", "pwd");

Expand All @@ -153,7 +153,7 @@ public void testTextPlainWithUTF8SenderAndReceiverAndGreenMailApi() throws Messa
try {
Folder inboxFolder = store.getFolder("INBOX");
inboxFolder.open(Folder.READ_ONLY);
Message[] messages = new Message[] { null };
Message[] messages = new Message[]{null};
MessageCountListener listener = new MessageCountListener() {
@Override
public void messagesRemoved(MessageCountEvent e) {
Expand Down Expand Up @@ -181,7 +181,7 @@ public void messagesAdded(MessageCountEvent e) {

assertThat(messages[0].getFrom()[0].toString()).isEqualTo(fromAddress.toString());
assertThat(Arrays.stream(messages[0].getAllRecipients()).map(Object::toString).toArray())
.isEqualTo(new String[] { toAddress.toString() });
.isEqualTo(new String[]{toAddress.toString()});

inboxFolder.close();
} finally {
Expand All @@ -200,4 +200,46 @@ private void sendMessage(InternetAddress fromAddress, InternetAddress toAddress)

GreenMailUtil.sendMimeMessage(message);
}

@Test
public void testAttachmentWithLongEncodedUTF8Name() throws MessagingException, IOException {
// Prepare mail
greenMail.setUser("to@localhost", "pwd");
String fileName = "кирилица testimage_ünicöde_\uD83C\uDF36";
final String fileNameEncoded = MimeUtility.encodeText(fileName);
GreenMailUtil.sendAttachmentEmail(
"to@localhost", "from@localhost", "subject", "body",
new byte[]{0, 1, 2}, "image/gif",
fileNameEncoded,
"testimage_description", greenMail.getSmtp().getServerSetup());

greenMail.waitForIncomingEmail(1);

// Verify
final IMAPStore store = greenMail.getImap().createStore();
store.connect("to@localhost", "pwd");
try {
Folder inboxFolder = store.getFolder("INBOX");
inboxFolder.open(Folder.READ_ONLY);
try {
Message[] messages = inboxFolder.getMessages();
assertThat(messages).hasSize(1);
final MimeMultipart content = (MimeMultipart) messages[0].getContent();
assertThat(messages[0].getContent() != null).isTrue();
String receivedFileName = "";
for (int i = 0; i < content.getCount(); i++) {
final MimeBodyPart bodyPart = (MimeBodyPart) content.getBodyPart(i);
if (bodyPart.getContentType().startsWith("IMAGE/GIF")) {
receivedFileName = bodyPart.getFileName();
}
}
assertThat(receivedFileName).isEqualTo(fileNameEncoded);
assertThat(MimeUtility.decodeText(receivedFileName)).isEqualTo(fileName);
} finally {
inboxFolder.close();
}
} finally {
store.close();
}
}
}

0 comments on commit a073b3a

Please sign in to comment.