This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-email.git
The following commit(s) were added to refs/heads/master by this push:
new 88567932 MultiPartEmail attach methods now throw an IOException if the
given file is a directory
88567932 is described below
commit 88567932dc17dae04564e564d9333682a98a2dd8
Author: Gary Gregory <[email protected]>
AuthorDate: Wed Feb 11 19:27:36 2026 -0500
MultiPartEmail attach methods now throw an IOException if the given file
is a directory
---
.../org/apache/commons/mail2/core/EmailUtils.java | 43 ++++++++++++++++++++++
.../commons/mail2/jakarta/MultiPartEmail.java | 17 ++-------
.../commons/mail2/jakarta/MultiPartEmailTest.java | 8 ++++
.../apache/commons/mail2/javax/MultiPartEmail.java | 20 +++-------
.../commons/mail2/javax/MultiPartEmailTest.java | 8 ++++
src/changes/changes.xml | 1 +
6 files changed, 69 insertions(+), 28 deletions(-)
diff --git
a/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailUtils.java
b/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailUtils.java
index 4f070ae9..a6210f79 100644
---
a/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailUtils.java
+++
b/commons-email2-core/src/main/java/org/apache/commons/mail2/core/EmailUtils.java
@@ -17,11 +17,16 @@
package org.apache.commons.mail2.core;
+import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.BitSet;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Random;
/**
@@ -86,6 +91,44 @@ public final class EmailUtils {
SAFE_URL.set('@');
}
+ /**
+ * Checks that the given file exists and is not a directory.
+ *
+ * @param file the file to check.
+ * @return the given file if it exists and is not a directory.
+ * @throws IOException if the given file does not exist or is a directory.
+ * @since 2.0.0-M2
+ */
+ public static File check(final File file) throws IOException {
+ Objects.requireNonNull(file, "file");
+ if (!file.exists()) {
+ throw new IOException("\"" + file + "\" does not exist");
+ }
+ if (file.isDirectory()) {
+ throw new IOException("\"" + file + "\" is a directory");
+ }
+ return file;
+ }
+
+ /**
+ * Checks that the given file exists and is not a directory.
+ *
+ * @param file the file to check.
+ * @return the given file if it exists and is not a directory.
+ * @throws IOException if the given file does not exist or is a directory.
+ * @since 2.0.0-M2
+ */
+ public static Path check(final Path file) throws IOException {
+ Objects.requireNonNull(file, "file");
+ if (!Files.exists(file)) {
+ throw new IOException("\"" + file + "\" does not exist");
+ }
+ if (Files.isDirectory(file)) {
+ throw new IOException("\"" + file + "\" is a directory");
+ }
+ return file;
+ }
+
/**
* Encodes an input string according to RFC 2392. Unsafe characters are
escaped.
*
diff --git
a/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/MultiPartEmail.java
b/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/MultiPartEmail.java
index 4f7cea31..cf26ad58 100644
---
a/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/MultiPartEmail.java
+++
b/commons-email2-jakarta/src/main/java/org/apache/commons/mail2/jakarta/MultiPartEmail.java
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
-import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.util.Objects;
@@ -202,10 +201,7 @@ public class MultiPartEmail extends Email {
String fileName = null;
try {
fileName = attachment.getPath();
- final File file = new File(fileName);
- if (!file.exists()) {
- throw new IOException("\"" + fileName + "\" does not
exist");
- }
+ final File file = EmailUtils.check(new File(fileName));
result = attach(new FileDataSource(file),
attachment.getName(), attachment.getDescription(), attachment.getDisposition());
} catch (final IOException e) {
throw new EmailException("Cannot attach file \"" + fileName +
"\"", e);
@@ -225,14 +221,11 @@ public class MultiPartEmail extends Email {
* @since 1.3
*/
public MultiPartEmail attach(final File file) throws EmailException {
- final String fileName = file.getAbsolutePath();
try {
- if (!file.exists()) {
- throw new IOException("\"" + fileName + "\" does not exist");
- }
+ EmailUtils.check(file);
return attach(new FileDataSource(file), file.getName(), null,
EmailAttachment.ATTACHMENT);
} catch (final IOException e) {
- throw new EmailException("Cannot attach file \"" + fileName +
"\"", e);
+ throw new EmailException("Cannot attach file \"" + file + "\"", e);
}
}
@@ -248,9 +241,7 @@ public class MultiPartEmail extends Email {
public MultiPartEmail attach(final Path file, final OpenOption... options)
throws EmailException {
final Path fileName = file.toAbsolutePath();
try {
- if (!Files.exists(file)) {
- throw new IOException("\"" + fileName + "\" does not exist");
- }
+ EmailUtils.check(file);
return attach(new PathDataSource(file,
FileTypeMap.getDefaultFileTypeMap(), options),
Objects.toString(file.getFileName(), null), null,
EmailAttachment.ATTACHMENT);
} catch (final IOException e) {
diff --git
a/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/MultiPartEmailTest.java
b/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/MultiPartEmailTest.java
index 183469f6..2b304925 100644
---
a/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/MultiPartEmailTest.java
+++
b/commons-email2-jakarta/src/test/java/org/apache/commons/mail2/jakarta/MultiPartEmailTest.java
@@ -136,6 +136,10 @@ class MultiPartEmailTest extends AbstractEmailTest {
final EmailAttachment attachment4 = new EmailAttachment();
attachment4.setPath("");
assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("ThisFileDoesNotExist.txt");
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("target"); // a directory, not a file
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
}
@Test
@@ -179,6 +183,10 @@ class MultiPartEmailTest extends AbstractEmailTest {
final EmailAttachment attachment4 = new EmailAttachment();
attachment4.setPath("");
assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("ThisFileDoesNotExist.txt");
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("target"); // a directory, not a file
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
}
/** TODO implement test for GetContainer */
diff --git
a/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/MultiPartEmail.java
b/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/MultiPartEmail.java
index 252b0e18..236d60f7 100644
---
a/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/MultiPartEmail.java
+++
b/commons-email2-javax/src/main/java/org/apache/commons/mail2/javax/MultiPartEmail.java
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
-import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.util.Objects;
@@ -202,7 +201,7 @@ public class MultiPartEmail extends Email {
String fileName = null;
try {
fileName = attachment.getPath();
- final File file = new File(fileName);
+ final File file = EmailUtils.check(new File(fileName));
if (!file.exists()) {
throw new IOException("\"" + fileName + "\" does not
exist");
}
@@ -225,14 +224,11 @@ public class MultiPartEmail extends Email {
* @since 1.3
*/
public MultiPartEmail attach(final File file) throws EmailException {
- final String fileName = file.getAbsolutePath();
try {
- if (!file.exists()) {
- throw new IOException("\"" + fileName + "\" does not exist");
- }
+ EmailUtils.check(file);
return attach(new FileDataSource(file), file.getName(), null,
EmailAttachment.ATTACHMENT);
} catch (final IOException e) {
- throw new EmailException("Cannot attach file \"" + fileName +
"\"", e);
+ throw new EmailException("Cannot attach file \"" + file + "\"", e);
}
}
@@ -246,15 +242,12 @@ public class MultiPartEmail extends Email {
* @since 1.6.0
*/
public MultiPartEmail attach(final Path file, final OpenOption... options)
throws EmailException {
- final Path fileName = file.toAbsolutePath();
try {
- if (!Files.exists(file)) {
- throw new IOException("\"" + fileName + "\" does not exist");
- }
+ EmailUtils.check(file);
return attach(new PathDataSource(file,
FileTypeMap.getDefaultFileTypeMap(), options),
Objects.toString(file.getFileName(), null), null,
EmailAttachment.ATTACHMENT);
} catch (final IOException e) {
- throw new EmailException("Cannot attach file \"" + fileName +
"\"", e);
+ throw new EmailException("Cannot attach file \"" + file + "\"", e);
}
}
@@ -307,7 +300,6 @@ public class MultiPartEmail extends Email {
// before a multipart message can be sent, we must make sure
that
// the content for the main body part was actually set. If not,
// an IOException will be thrown during super.send().
-
final BodyPart body = getPrimaryBodyPart();
try {
body.getContent();
@@ -318,11 +310,9 @@ public class MultiPartEmail extends Email {
// throw new EmailException(e);
}
}
-
if (subType != null) {
getContainer().setSubType(subType);
}
-
super.buildMimeMessage();
} catch (final MessagingException e) {
throw new EmailException(e);
diff --git
a/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/MultiPartEmailTest.java
b/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/MultiPartEmailTest.java
index 085e8def..2f2bcfbf 100644
---
a/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/MultiPartEmailTest.java
+++
b/commons-email2-javax/src/test/java/org/apache/commons/mail2/javax/MultiPartEmailTest.java
@@ -136,6 +136,10 @@ class MultiPartEmailTest extends AbstractEmailTest {
final EmailAttachment attachment4 = new EmailAttachment();
attachment4.setPath("");
assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("ThisFileDoesNotExist.txt");
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("target"); // a directory, not a file
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
}
@Test
@@ -179,6 +183,10 @@ class MultiPartEmailTest extends AbstractEmailTest {
final EmailAttachment attachment4 = new EmailAttachment();
attachment4.setPath("");
assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("ThisFileDoesNotExist.txt");
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
+ attachment4.setPath("target"); // a directory, not a file
+ assertThrows(EmailException.class, () -> email.attach(attachment4));
}
/** TODO implement test for GetContainer */
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 59b2b6c3..2b63b34f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -27,6 +27,7 @@
<!-- FIX -->
<action type="update" due-to="Derek Wickern, Gary Gregory"
dev="ggregory">Handle IllegalArgumentException thrown for invalid email address
#328.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">Fix Apache RAT
plugin console warnings.</action>
+ <action type="fix" dev="ggregory" due-to="Gary Gregory, Henri Cook,
Sebb">MultiPartEmail attach methods now throw an IOException if the given file
is a directory.</action>
<!-- UPDATE -->
<action type="update" due-to="Gary Gregory, Dependabot"
dev="ggregory">Bump commons-parent from 72 to 96 #279, #293, #297, #304, #350,
#376, #386, #390, #392.</action>
<action type="update" due-to="Gary Gregory" dev="ggregory">Bump
org.mockito:mockito-core from 5.13.0 to 5.21.0 #290, #296, #302, #319, #336,
#338, #344, #353, #366.</action>