This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 4f77aab13a JAMES-4011 Use MIME4J to decode filename
4f77aab13a is described below

commit 4f77aab13a6696f1417b4cb4728ed26b34a9de74
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Tue Feb 27 08:50:45 2024 +0100

    JAMES-4011 Use MIME4J to decode filename
    
    This is more lenient
---
 .../james/transport/mailets/StripAttachment.java   | 20 ++++++++++--
 .../transport/mailets/StripAttachmentTest.java     | 37 ++++++++++++++++++++++
 mailet/standard/src/test/resources/mime/space.eml  | 24 ++++++++++++++
 3 files changed, 79 insertions(+), 2 deletions(-)

diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
index 459e7fb0d4..115b5bd45e 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
@@ -50,6 +50,11 @@ import 
org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.james.javax.MultipartUtil;
 import org.apache.james.mime4j.codec.DecodeMonitor;
 import org.apache.james.mime4j.codec.DecoderUtil;
+import org.apache.james.mime4j.dom.field.ContentDispositionField;
+import org.apache.james.mime4j.field.ContentDispositionFieldLenientImpl;
+import org.apache.james.mime4j.field.ContentTypeFieldLenientImpl;
+import org.apache.james.mime4j.stream.Field;
+import org.apache.james.mime4j.stream.RawField;
 import org.apache.mailet.Attribute;
 import org.apache.mailet.AttributeName;
 import org.apache.mailet.AttributeUtils;
@@ -385,7 +390,18 @@ public class StripAttachment extends GenericMailet {
 
     @VisibleForTesting String getFilename(BodyPart bodyPart) {
         try {
-            String fileName = bodyPart.getFileName();
+            String fileName = 
Optional.ofNullable(bodyPart.getHeader("Content-Disposition"))
+                .map(h -> h[0])
+                .map(h -> new RawField("Content-Disposition", h))
+                .map(h -> ContentDispositionFieldLenientImpl.PARSER.parse(h, 
DecodeMonitor.SILENT))
+                .map(ContentDispositionField::getFilename)
+                .or(Throwing.supplier(() -> 
Optional.ofNullable(bodyPart.getHeader("Content-Type"))
+                    .map(h -> h[0])
+                    .map(h -> new RawField("Content-Type", h))
+                    .map(h -> ContentTypeFieldLenientImpl.PARSER.parse(h, 
DecodeMonitor.SILENT))
+                    .map(Field::getName)).sneakyThrow())
+                .orElse(null);
+
             if (fileName != null) {
                 return 
renameWithConfigurationPattern(decodeFilename(fileName));
             }
@@ -467,7 +483,7 @@ public class StripAttachment extends GenericMailet {
     }
 
     private File outputFile(Part part, Optional<String> fileName) throws 
MessagingException, IOException {
-        Optional<String> maybePartFileName = 
Optional.ofNullable(part.getFileName());
+        Optional<String> maybePartFileName = fileName.or(Throwing.supplier(() 
-> Optional.ofNullable(part.getFileName())).sneakyThrow());
         return createTempFile(fileName.orElse(maybePartFileName.orElse(null)));
     }
 
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
index c2e4a3efd3..a374b5d1c9 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
@@ -44,6 +44,8 @@ import org.apache.james.core.builder.MimeMessageBuilder;
 import org.apache.james.junit.TemporaryFolderExtension;
 import org.apache.james.junit.TemporaryFolderExtension.TemporaryFolder;
 import org.apache.james.transport.mailets.StripAttachment.OutputFileName;
+import org.apache.james.util.ClassLoaderUtils;
+import org.apache.james.util.MimeMessageUtil;
 import org.apache.mailet.AttributeName;
 import org.apache.mailet.AttributeUtils;
 import org.apache.mailet.AttributeValue;
@@ -340,6 +342,41 @@ class StripAttachmentTest {
             .hasValueSatisfying(assertValue.sneakyThrow());
     }
 
+    @Test
+    void serviceShouldHandleFilenameWithSpace(TemporaryFolder temporaryFolder) 
throws Exception {
+        StripAttachment mailet = new StripAttachment();
+
+        String customAttribute = "my.custom.attribute";
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+            .mailetName("Test")
+            .setProperty("remove", "matched")
+            .setProperty("directory", temporaryFolder.getFolderPath())
+            .setProperty("pattern", ".*\\.pdf")
+            .setProperty("attribute", customAttribute)
+            .build();
+        mailet.init(mci);
+
+        String expectedKey = "Vietnam Airline.pdf";
+        MimeMessage message = 
MimeMessageUtil.mimeMessageFromStream(ClassLoaderUtils.getSystemResourceAsSharedStream("mime/space.eml"));
+
+        Mail mail = FakeMail.builder()
+            .name("from-message-builder")
+            .mimeMessage(message)
+            .build();
+
+        mailet.service(mail);
+
+        Optional<Map<String, AttributeValue<?>>> savedValue = 
AttributeUtils.getValueAndCastFromMail(mail, AttributeName.of(customAttribute), 
MAP_STRING_BYTES_CLASS);
+        ConsumerChainer<Map<String, AttributeValue<?>>> assertValue = 
Throwing.consumer(saved -> {
+            assertThat(saved)
+                .hasSize(1)
+                .containsKeys(expectedKey);
+        });
+        assertThat(savedValue)
+            .isPresent()
+            .hasValueSatisfying(assertValue.sneakyThrow());
+    }
+
     @Test
     void serviceShouldDecodeHeaderFilenames() throws Exception, IOException {
         StripAttachment mailet = new StripAttachment();
diff --git a/mailet/standard/src/test/resources/mime/space.eml 
b/mailet/standard/src/test/resources/mime/space.eml
new file mode 100644
index 0000000000..456b218a0b
--- /dev/null
+++ b/mailet/standard/src/test/resources/mime/space.eml
@@ -0,0 +1,24 @@
+Content-Type: multipart/mixed; boundary="------------gwA6NAbT8Pk0FYCy0yoPh61m"
+Message-ID: <1745dbd6-f23b-44d0-be4c-9b9472c50...@linagora.com>
+Date: Tue, 27 Feb 2024 07:38:14 +0100
+MIME-Version: 1.0
+To: BT TEST <x...@linagora.com>
+From: "x...@linagora.com" <x...@linagora.com>
+Subject: Space
+
+This is a multi-part message in MIME format.
+--------------gwA6NAbT8Pk0FYCy0yoPh61m
+Content-Type: text/plain; charset=UTF-8; format=flowed
+Content-Transfer-Encoding: 7bit
+
+space in attachment filename
+
+--------------gwA6NAbT8Pk0FYCy0yoPh61m
+Content-Type: application/pdf
+Content-Disposition: attachment; filename=Vietnam Airline.pdf
+Content-Transfer-Encoding: base64
+
+JVBERi0xLjUKJbXtrvsKMyAwIG9iago8PCAvTGVuZ3RoIDQgMCBSCiAgIC9GaWx0ZXIgL0Zs
+YXRlRGVjb2RlCj4+CnN0cmVhbQp4nN1aS6/buhHe61foD1ghh28g0OIC3XTVAgfooujC9jm+
+
+--------------gwA6NAbT8Pk0FYCy0yoPh61m--


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to