Skip to content

Commit 305a2d5

Browse files
committed
#175: Fixed how attachment names are read back to account for possible <> wrapping. Also, fixed how the tests deal with these names and made it more clear how the attachment name overrides affect conversion results
1 parent 2e04c4c commit 305a2d5

File tree

6 files changed

+59
-23
lines changed

6 files changed

+59
-23
lines changed

src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParser.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.HashMap;
3232
import java.util.List;
3333
import java.util.Map;
34+
import java.util.TreeMap;
3435

3536
import static java.lang.String.format;
3637
import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
@@ -215,13 +216,14 @@ public static String parseDisposition(@Nonnull final MimePart currentPart) {
215216
}
216217

217218
@Nonnull
218-
private static String parseResourceName(@Nullable final String contentID, @Nonnull final String fileName) {
219-
String extension = "";
220-
if (!valueNullOrEmpty(fileName) && fileName.contains(".")) {
221-
extension = fileName.substring(fileName.lastIndexOf("."), fileName.length());
222-
}
223-
if (!valueNullOrEmpty(contentID)) {
224-
return (contentID.endsWith(extension)) ? contentID : contentID + extension;
219+
private static String parseResourceName(@Nullable final String possibleWrappedContentID, @Nonnull final String fileName) {
220+
if (!valueNullOrEmpty(possibleWrappedContentID)) {
221+
// https://regex101.com/r/46ulb2/1
222+
String unwrappedContentID = possibleWrappedContentID.replaceAll("^<?(.*?)>?$", "$1");
223+
String extension = (!valueNullOrEmpty(fileName) && fileName.contains("."))
224+
? fileName.substring(fileName.lastIndexOf("."))
225+
: "";
226+
return (unwrappedContentID.endsWith(extension)) ? unwrappedContentID : unwrappedContentID + extension;
225227
} else {
226228
return fileName;
227229
}
@@ -444,8 +446,8 @@ public static String parseMessageId(@Nonnull final MimeMessage mimeMessage) {
444446
}
445447

446448
public static class ParsedMimeMessageComponents {
447-
private final Map<String, DataSource> attachmentList = new HashMap<>();
448-
private final Map<String, DataSource> cidMap = new HashMap<>();
449+
private final Map<String, DataSource> attachmentList = new TreeMap<>();
450+
private final Map<String, DataSource> cidMap = new TreeMap<>();
449451
private final Map<String, Object> headers = new HashMap<>();
450452
private final List<InternetAddress> toAddresses = new ArrayList<>();
451453
private final List<InternetAddress> ccAddresses = new ArrayList<>();

src/test/java/org/simplejavamail/email/EmailPopulatingBuilderUsingDefaultsFromPropertyFileTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class EmailPopulatingBuilderUsingDefaultsFromPropertyFileTest {
1616
public void testBuilderSimpleBuildWithStandardEmail()
1717
throws IOException {
1818
ByteArrayDataSource namedAttachment = new ByteArrayDataSource("Black Tie Optional", "text/plain");
19-
namedAttachment.setName("dresscode.txt"); // normally not needed, but otherwise the equals will fail
19+
namedAttachment.setName("dresscode-ignored-because-of-override.txt");
2020
String base64String = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABeElEQVRYw2NgoAAYGxu3GxkZ7TY1NZVloDcAWq4MxH+B+D8Qv3FwcOCgtwM6oJaDMTAUXOhmuYqKCjvQ0pdoDrCnmwNMTEwakC0H4u8GBgYC9Ap6DSD+iewAoIPm0ctyLqBlp9F8/x+YE4zpYT8T0LL16JYD8U26+B7oyz4sloPwenpYno3DchCeROsUbwa05A8eB3wB4kqgIxOAuArIng7EW4H4EhC/B+JXQLwDaI4ryZaDSjeg5mt4LCcFXyIn1fdSyXJQVt1OtMWGhoai0OD8T0W8GohZifE1PxD/o7LlsPLiFNAKRrwOABWptLAcqc6QGDAHQEOAYaAc8BNotsJAOgAUAosG1AFA/AtUoY3YEFhKMAvS2AE7iC1+WaG1H6gY3gzE36hUFJ8mqzbU1dUVBBqQBzTgIDQRkWo5qCZdpaenJ0Zx1aytrc0DDB0foIG1oAYKqC0IZK8D4n1AfA6IzwPxXpCFoGoZVEUDaRGGUTAKRgEeAAA2eGJC+ETCiAAAAABJRU5ErkJggg==";
2121

2222
final Email email = EmailBuilder.startingBlank()
@@ -37,7 +37,7 @@ public void testBuilderSimpleBuildWithStandardEmail()
3737
public void testBuilderSimpleBuildWithStandardEmail_PlusOptionals()
3838
throws IOException {
3939
ByteArrayDataSource namedAttachment = new ByteArrayDataSource("Black Tie Optional", "text/plain");
40-
namedAttachment.setName("dresscode.txt"); // normally not needed, but otherwise the equals will fail
40+
namedAttachment.setName("dresscode-ignored-because-of-override.txt");
4141
String base64String = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABeElEQVRYw2NgoAAYGxu3GxkZ7TY1NZVloDcAWq4MxH+B+D8Qv3FwcOCgtwM6oJaDMTAUXOhmuYqKCjvQ0pdoDrCnmwNMTEwakC0H4u8GBgYC9Ap6DSD+iewAoIPm0ctyLqBlp9F8/x+YE4zpYT8T0LL16JYD8U26+B7oyz4sloPwenpYno3DchCeROsUbwa05A8eB3wB4kqgIxOAuArIng7EW4H4EhC/B+JXQLwDaI4ryZaDSjeg5mt4LCcFXyIn1fdSyXJQVt1OtMWGhoai0OD8T0W8GohZifE1PxD/o7LlsPLiFNAKRrwOABWptLAcqc6QGDAHQEOAYaAc8BNotsJAOgAUAosG1AFA/AtUoY3YEFhKMAvS2AE7iC1+WaG1H6gY3gzE36hUFJ8mqzbU1dUVBBqQBzTgIDQRkWo5qCZdpaenJ0Zx1aytrc0DDB0foIG1oAYKqC0IZK8D4n1AfA6IzwPxXpCFoGoZVEUDaRGGUTAKRgEeAAA2eGJC+ETCiAAAAABJRU5ErkJggg==";
4242

4343
final Email email = EmailBuilder.startingBlank()

src/test/java/org/simplejavamail/mailer/MailerLiveTest.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.simplejavamail.email.EmailPopulatingBuilder;
1111
import org.simplejavamail.email.Recipient;
1212
import org.simplejavamail.util.ConfigLoader;
13+
import org.simplejavamail.util.TestDataHelper;
1314
import testutil.EmailHelper;
1415
import testutil.testrules.SmtpServerRule;
1516
import testutil.testrules.TestSmtpServer;
@@ -47,37 +48,37 @@ public void setup() {
4748
@Test
4849
public void createMailSession_EmptySubjectAndBody()
4950
throws IOException, MessagingException {
50-
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, true, false));
51+
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, true, false), true);
5152
}
5253

5354
@Test
5455
public void createMailSession_StandardDummyMailBasicFields()
5556
throws IOException, MessagingException {
56-
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, true, false));
57+
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, true, false), true);
5758
}
5859

5960
@Test
6061
public void createMailSession_StandardDummyMail_AllFields()
6162
throws IOException, MessagingException {
62-
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, false, false));
63+
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, false, false), true);
6364
}
6465

6566
@Test
6667
public void createMailSession_StandardDummyMail_IncludingCustomHeaders()
6768
throws IOException, MessagingException {
68-
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, false, true));
69+
assertSendingEmail(EmailHelper.createDummyEmailBuilder(true, false, true), true);
6970
}
7071

7172
@Test
7273
public void createMailSession_StandardDummyMailWithId()
7374
throws IOException, MessagingException {
74-
assertSendingEmail(EmailHelper.createDummyEmailBuilder("<123@456>", true, false, false));
75+
assertSendingEmail(EmailHelper.createDummyEmailBuilder("<123@456>", true, false, false), true);
7576
}
7677

7778
@Test
7879
public void createMailSession_OutlookMessageTest()
7980
throws IOException, MessagingException {
80-
Email email = assertSendingEmail(readOutlookMessage("test-messages/HTML mail with replyto and attachment and embedded image.msg"));
81+
Email email = assertSendingEmail(readOutlookMessage("test-messages/HTML mail with replyto and attachment and embedded image.msg"), false);
8182

8283
// Google SMTP overrode this, Outlook recognized it as: Benny Bottema <[email protected]>; on behalf of; lollypop <[email protected]>
8384
EmailAssert.assertThat(email).hasFromRecipient(new Recipient("lollypop", "[email protected]", null));
@@ -104,7 +105,7 @@ public void createMailSession_OutlookMessageTest()
104105
assertThat(normalizeText(attachment2.readAllData())).isEqualTo("On the moon!");
105106
}
106107

107-
private Email assertSendingEmail(final EmailPopulatingBuilder originalEmailPopulatingBuilder)
108+
private Email assertSendingEmail(final EmailPopulatingBuilder originalEmailPopulatingBuilder, boolean compensateForDresscodeAttachmentNameOverrideErasure)
108109
throws MessagingException {
109110
Email originalEmail = originalEmailPopulatingBuilder.buildEmail();
110111
mailer.sendMail(originalEmail);
@@ -124,6 +125,11 @@ private Email assertSendingEmail(final EmailPopulatingBuilder originalEmailPopul
124125
if (originalEmailPopulatingBuilder.getBounceToRecipient() != null) {
125126
originalEmailPopulatingBuilder.clearBounceTo();
126127
}
128+
129+
if (compensateForDresscodeAttachmentNameOverrideErasure) {
130+
TestDataHelper.fixDresscodeAttachment(receivedEmail);
131+
}
132+
127133
assertThat(receivedEmail).isEqualTo(originalEmailPopulatingBuilder.buildEmail());
128134
return receivedEmail;
129135
}
@@ -138,7 +144,7 @@ public void createMailSession_ReplyToMessage()
138144

139145
// send reply to initial mail
140146
Email reply = EmailBuilder
141-
.replyingToAll(assertSendingEmail(receivedEmailPopulatingBuilder))
147+
.replyingToAll(assertSendingEmail(receivedEmailPopulatingBuilder, false))
142148
143149
.withPlainText("This is the reply")
144150
.buildEmail();
@@ -170,7 +176,7 @@ public void createMailSession_ReplyToMessage_NotAll_AndCustomReferences()
170176

171177
// send reply to initial mail
172178
Email reply = EmailBuilder
173-
.replyingTo(assertSendingEmail(receivedEmailPopulatingBuilder))
179+
.replyingTo(assertSendingEmail(receivedEmailPopulatingBuilder, false))
174180
.withHeader("References", "dummy-references")
175181
176182
.withPlainText("This is the reply")

src/test/java/org/simplejavamail/mailer/MailerTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.simplejavamail.mailer.MailerBuilder.MailerRegularBuilder;
1010
import org.simplejavamail.mailer.config.TransportStrategy;
1111
import org.simplejavamail.util.ConfigLoader;
12+
import org.simplejavamail.util.TestDataHelper;
1213
import testutil.ConfigLoaderTestHelper;
1314
import testutil.EmailHelper;
1415

@@ -267,12 +268,13 @@ public void testParser()
267268
final EmailPopulatingBuilder emailPopulatingBuilderNormal = EmailHelper.createDummyEmailBuilder(true, false, false);
268269

269270
// let's try producing and then consuming a MimeMessage ->
270-
// (bounce recipient is not part of the Mimemessage, but the Envelope and is configured on the Session, so just ignore this)
271+
// (bounce recipient is not part of the Mimemessage but the Envelope and is configured on the Session, so just ignore this)
271272
emailPopulatingBuilderNormal.clearBounceTo();
272-
Email emailNormal = emailPopulatingBuilderNormal.buildEmail();
273+
final Email emailNormal = emailPopulatingBuilderNormal.buildEmail();
273274
final MimeMessage mimeMessage = EmailConverter.emailToMimeMessage(emailNormal);
274275
final Email emailFromMimeMessage = EmailConverter.mimeMessageToEmail(mimeMessage);
275276

277+
TestDataHelper.fixDresscodeAttachment(emailFromMimeMessage);
276278

277279
assertThat(emailFromMimeMessage).isEqualTo(emailNormal);
278280
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.simplejavamail.util;
2+
3+
import org.simplejavamail.email.AttachmentResource;
4+
import org.simplejavamail.email.Email;
5+
6+
import javax.mail.util.ByteArrayDataSource;
7+
8+
import static java.util.Objects.requireNonNull;
9+
10+
public class TestDataHelper {
11+
/**
12+
* Since the dresscode attachment name was overridden in the input Email, the original attachment's name is lost forever and won't come back when
13+
* converted to MimeMessage. This would result in an unequal email if the MimeMessage was converted back again, so we need to either clear it in
14+
* the input email after converting to MimeMessage, or re-add it to the Email result after converting from the MimeMessage.
15+
* <p>
16+
* We'll do the last to stay closes to the original input:
17+
*/
18+
public static void fixDresscodeAttachment(final Email emailResultFromConvertedMimeMessage) {
19+
for (AttachmentResource attachment : emailResultFromConvertedMimeMessage.getAttachments()) {
20+
if (requireNonNull(attachment.getName()).equals("dresscode.txt")) {
21+
((ByteArrayDataSource) attachment.getDataSource()).setName("dresscode-ignored-because-of-override.txt");
22+
break;
23+
}
24+
}
25+
}
26+
}

src/test/java/testutil/EmailHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public static EmailPopulatingBuilder createDummyEmailBuilder(@Nullable String id
4949

5050
// add two text files in different ways and a black thumbs up embedded image ->
5151
ByteArrayDataSource namedAttachment = new ByteArrayDataSource("Black Tie Optional", "text/plain");
52-
namedAttachment.setName("dresscode.txt"); // normally not needed, but otherwise the equals will fail
52+
namedAttachment.setName("dresscode-ignored-because-of-override.txt");
5353
String base64String = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABeElEQVRYw2NgoAAYGxu3GxkZ7TY1NZVloDcAWq4MxH+B+D8Qv3FwcOCgtwM6oJaDMTAUXOhmuYqKCjvQ0pdoDrCnmwNMTEwakC0H4u8GBgYC9Ap6DSD+iewAoIPm0ctyLqBlp9F8/x+YE4zpYT8T0LL16JYD8U26+B7oyz4sloPwenpYno3DchCeROsUbwa05A8eB3wB4kqgIxOAuArIng7EW4H4EhC/B+JXQLwDaI4ryZaDSjeg5mt4LCcFXyIn1fdSyXJQVt1OtMWGhoai0OD8T0W8GohZifE1PxD/o7LlsPLiFNAKRrwOABWptLAcqc6QGDAHQEOAYaAc8BNotsJAOgAUAosG1AFA/AtUoY3YEFhKMAvS2AE7iC1+WaG1H6gY3gzE36hUFJ8mqzbU1dUVBBqQBzTgIDQRkWo5qCZdpaenJ0Zx1aytrc0DDB0foIG1oAYKqC0IZK8D4n1AfA6IzwPxXpCFoGoZVEUDaRGGUTAKRgEeAAA2eGJC+ETCiAAAAABJRU5ErkJggg==";
5454

5555
return builder

0 commit comments

Comments
 (0)