From 5ba691effd5a9ee95b403f22ad3b2061cffd11d8 Mon Sep 17 00:00:00 2001 From: bbottema Date: Sun, 20 Oct 2019 14:57:32 +0200 Subject: [PATCH] #230: properly handle missing address value in headers --- .../MimeMessageParseException.java | 2 +- .../mimemessage/MimeMessageParser.java | 19 ++++++---- .../mimemessage/MimeMessageParserTest.java | 37 ++++++++++++++++++- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParseException.java b/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParseException.java index f3fffcd40..a5545ec05 100644 --- a/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParseException.java +++ b/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParseException.java @@ -14,7 +14,7 @@ class MimeMessageParseException extends MailException { static final String ERROR_PARSING_FROMADDRESS = "Error parsing from-address"; - static final String ERROR_PARSING_ADDRESS = "Error parsing [%s] address"; + static final String ERROR_PARSING_ADDRESS = "Error parsing [%s] address [%s]"; static final String ERROR_PARSING_DISPOSITION = "Error parsing MimeMessage disposition"; static final String ERROR_PARSING_CONTENT = "Error parsing MimeMessage Content"; static final String ERROR_PARSING_MULTIPART_COUNT = "Error parsing MimeMessage multipart count"; diff --git a/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParser.java b/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParser.java index 07a84c77d..eff7fed26 100644 --- a/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParser.java +++ b/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParser.java @@ -143,15 +143,15 @@ private static void parseMimePartTree(@Nonnull final MimePart currentPart, @Nonn } } } - + @SuppressWarnings("StatementWithEmptyBody") private static void parseHeader(final Header header, @Nonnull final ParsedMimeMessageComponents parsedComponents) { if (header.getName().equals("Disposition-Notification-To")) { - parsedComponents.dispositionNotificationTo = createAddress(header, "Disposition-Notification-To"); + parsedComponents.dispositionNotificationTo = createAddress(header.getValue(), "Disposition-Notification-To"); } else if (header.getName().equals("Return-Receipt-To")) { - parsedComponents.returnReceiptTo = createAddress(header, "Return-Receipt-To"); + parsedComponents.returnReceiptTo = createAddress(header.getValue(), "Return-Receipt-To"); } else if (header.getName().equals("Return-Path")) { - parsedComponents.bounceToAddress = createAddress(header, "Return-Path"); + parsedComponents.bounceToAddress = createAddress(header.getValue(), "Return-Path"); } else if (!HEADERS_TO_IGNORE.contains(header.getName())) { parsedComponents.headers.put(header.getName(), header.getValue()); } else { @@ -245,12 +245,15 @@ public static List
retrieveAllHeaders(@Nonnull final MimePart part) { } } - @Nonnull - private static InternetAddress createAddress(final Header header, final String typeOfAddress) { + @Nullable + static InternetAddress createAddress(final String address, final String typeOfAddress) { try { - return new InternetAddress(header.getValue()); + return new InternetAddress(address); } catch (final AddressException e) { - throw new MimeMessageParseException(format(MimeMessageParseException.ERROR_PARSING_ADDRESS, typeOfAddress), e); + if (e.getMessage().equals("Empty address")) { + return null; + } + throw new MimeMessageParseException(format(MimeMessageParseException.ERROR_PARSING_ADDRESS, typeOfAddress, address), e); } } diff --git a/src/test/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParserTest.java b/src/test/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParserTest.java index a65d40fd9..0d81a821a 100644 --- a/src/test/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParserTest.java +++ b/src/test/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageParserTest.java @@ -1,5 +1,6 @@ package org.simplejavamail.converter.internal.mimemessage; +import org.assertj.core.api.ThrowableAssert; import org.junit.Test; import org.simplejavamail.converter.EmailConverter; import org.simplejavamail.converter.internal.mimemessage.MimeMessageParser.ParsedMimeMessageComponents; @@ -9,11 +10,15 @@ import org.simplejavamail.email.Recipient; import testutil.ConfigLoaderTestHelper; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; import javax.mail.util.ByteArrayDataSource; import java.io.IOException; +import java.io.UnsupportedEncodingException; import static javax.mail.Message.RecipientType.TO; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.simplejavamail.converter.internal.mimemessage.MimeMessageParser.moveInvalidEmbeddedResourcesToAttachments; public class MimeMessageParserTest { @@ -51,7 +56,37 @@ public void testMoveInvalidEmbeddedResourcesToAttachments_Invalid() throws IOExc assertThat(parsedComponents.cidMap).containsOnlyKeys("moo1"); assertThat(parsedComponents.attachmentList).extracting("key").containsOnly("moo2"); } - + + @Test + public void testCreateAddress() throws AddressException, UnsupportedEncodingException { + assertThat(interpretRecipient("a@b.com")).isEqualTo(new InternetAddress("a@b.com", null)); + assertThat(interpretRecipient(" a@b.com ")).isEqualTo(new InternetAddress("a@b.com", null)); + assertThat(interpretRecipient(" ")).isEqualTo(new InternetAddress("a@b.com", null)); + assertThat(interpretRecipient(" < a@b.com > ")).isEqualTo(new InternetAddress("a@b.com", null)); + assertThat(interpretRecipient("moo ")).isEqualTo(new InternetAddress("a@b.com", "moo")); + assertThat(interpretRecipient("moo")).isEqualTo(new InternetAddress("a@b.com", "moo")); + assertThat(interpretRecipient(" moo< a@b.com > ")).isEqualTo(new InternetAddress("a@b.com", "moo")); + assertThat(interpretRecipient("\"moo\" ")).isEqualTo(new InternetAddress("a@b.com", "moo")); + assertThat(interpretRecipient("\"moo\"")).isEqualTo(new InternetAddress("a@b.com", "moo")); + assertThat(interpretRecipient(" \"moo\"< a@b.com > ")).isEqualTo(new InternetAddress("a@b.com", "moo")); + assertThat(interpretRecipient(" \" m oo \"< a@b.com > ")).isEqualTo(new InternetAddress("a@b.com", " m oo ")); + assertThat(interpretRecipient("< >")).isNull(); + + // next one is unparsable by InternetAddress#parse(), so it should be taken as is + assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { + @Override + public void call() throws Throwable { + interpretRecipient(" \" m oo \" a@b.com "); + } + }) + .isInstanceOf(MimeMessageParseException.class) + .hasMessage("Error parsing [TO] address [ \" m oo \" a@b.com ]"); + } + + private InternetAddress interpretRecipient(String address) { + return MimeMessageParser.createAddress(address, "TO"); + } + @Test // https://github.com/bbottema/simple-java-mail/issues/227 public void testSemiColonSeparatedToAddresses() {