This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch 1.x
in repository https://gitbox.apache.org/repos/asf/commons-email.git
The following commit(s) were added to refs/heads/1.x by this push:
new a05eccb4 MultiPartEmail attach methods now throw an IOException if the
given file is a directory.
a05eccb4 is described below
commit a05eccb4ff0deee76a6017d46fa0f5aea3356afd
Author: Gary Gregory <[email protected]>
AuthorDate: Wed Feb 11 19:49:56 2026 -0500
MultiPartEmail attach methods now throw an IOException if the given file
is a directory.
Fix tests on Java 25 and up
---
pom.xml | 18 +++++-----
src/changes/changes.xml | 2 ++
.../java/org/apache/commons/mail/EmailUtils.java | 39 ++++++++++++++++++++++
.../org/apache/commons/mail/MultiPartEmail.java | 11 ++----
.../apache/commons/mail/MultiPartEmailTest.java | 8 +++++
5 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/pom.xml b/pom.xml
index 07481b8e..4c284f58 100644
--- a/pom.xml
+++ b/pom.xml
@@ -463,7 +463,6 @@
</plugin>
</plugins>
</reporting>
-
<profiles>
<profile>
<id>java17</id>
@@ -471,6 +470,9 @@
<activation>
<jdk>[17,)</jdk>
</activation>
+ <properties>
+ <mockito-core.version>5.21.0</mockito-core.version>
+ </properties>
<build>
<plugins>
<plugin>
@@ -495,14 +497,13 @@
</profile>
<profile>
<id>java8</id>
- <activation>
- <jdk>[1.8,11)</jdk>
- </activation>
- <properties>
- <mockito-core.version>4.11.0</mockito-core.version>
- </properties>
+ <activation>
+ <jdk>[1.8,11)</jdk>
+ </activation>
+ <properties>
+ <mockito-core.version>4.11.0</mockito-core.version>
+ </properties>
</profile>
-
<profile>
<id>rc</id>
<distributionManagement>
@@ -515,5 +516,4 @@
</distributionManagement>
</profile>
</profiles>
-
</project>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index a5f5c562..7e839578 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -27,6 +27,8 @@
<!-- FIX -->
<action type="fix" dev="ggregory" due-to="Gary Gregory">Fix minor PMD
violations (Unnecessary qualifier).</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">Fix tests on
Java 25 and up.</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>
<!-- ADD -->
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump
commons-parent from 65 to 96.</action>
diff --git a/src/main/java/org/apache/commons/mail/EmailUtils.java
b/src/main/java/org/apache/commons/mail/EmailUtils.java
index c4130b0e..2efdcdc4 100644
--- a/src/main/java/org/apache/commons/mail/EmailUtils.java
+++ b/src/main/java/org/apache/commons/mail/EmailUtils.java
@@ -20,10 +20,13 @@ package org.apache.commons.mail;
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;
import javax.mail.MessagingException;
@@ -93,6 +96,42 @@ 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.
+ */
+ 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.
+ */
+ 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/src/main/java/org/apache/commons/mail/MultiPartEmail.java
b/src/main/java/org/apache/commons/mail/MultiPartEmail.java
index 4310554c..c31eccb2 100644
--- a/src/main/java/org/apache/commons/mail/MultiPartEmail.java
+++ b/src/main/java/org/apache/commons/mail/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;
@@ -200,7 +199,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,9 +224,7 @@ public class MultiPartEmail extends Email {
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);
@@ -246,9 +243,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/src/test/java/org/apache/commons/mail/MultiPartEmailTest.java
b/src/test/java/org/apache/commons/mail/MultiPartEmailTest.java
index 1753327c..b08b937c 100644
--- a/src/test/java/org/apache/commons/mail/MultiPartEmailTest.java
+++ b/src/test/java/org/apache/commons/mail/MultiPartEmailTest.java
@@ -133,6 +133,10 @@ public 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
@@ -176,6 +180,10 @@ public 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 */