From c65e57b2a6f3bfbb2302f9e719346d51fa6e1750 Mon Sep 17 00:00:00 2001 From: Ashraf Ali Date: Sat, 29 Aug 2026 21:57:11 +0600 Subject: [PATCH] Encode non-ASCII attachment file names according to RFC 2231 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SMTP Sampler used javax.mail 1.5.0-b01, which mangles attachment file names that contain non-ASCII characters (for example a file named "текст.txt" was sent as "B5:AB.txt"), so recipients could not see the original file name. Update javax.mail to 1.6.2 (com.sun.mail:javax.mail), which encodes non-ASCII file name parameters according to RFC 2231. The javax.mail namespace is unchanged, so no code changes are needed. Closes #6652 --- src/bom-thirdparty/build.gradle.kts | 2 +- src/components/build.gradle.kts | 2 +- src/protocol/mail/build.gradle.kts | 2 +- .../sampler/protocol/SendMailCommandTest.java | 90 +++++++++++++++++++ xdocs/changes.xml | 2 + 5 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/protocol/mail/src/test/java/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommandTest.java diff --git a/src/bom-thirdparty/build.gradle.kts b/src/bom-thirdparty/build.gradle.kts index 7a7307e9f21..af9733ed420 100644 --- a/src/bom-thirdparty/build.gradle.kts +++ b/src/bom-thirdparty/build.gradle.kts @@ -75,7 +75,7 @@ dependencies { api("io.burt:jmespath-jackson:0.6.0") api("jakarta.jms:jakarta.jms-api:3.1.0") api("javax.activation:javax.activation-api:1.2.0") - api("javax.mail:mail:1.5.0-b01") + api("com.sun.mail:javax.mail:1.6.2") api("jcharts:jcharts:0.7.5") api("junit:junit:4.13.2") { because("ApacheJMeter_junit depends on junit4") diff --git a/src/components/build.gradle.kts b/src/components/build.gradle.kts index 5653af3c135..73087378d9b 100644 --- a/src/components/build.gradle.kts +++ b/src/components/build.gradle.kts @@ -35,7 +35,7 @@ dependencies { ) } - api("javax.mail:mail") { + api("com.sun.mail:javax.mail") { exclude("javax.activation", "activation") } // There's no javax.activation:activation:1.2.0, so we use com.sun... diff --git a/src/protocol/mail/build.gradle.kts b/src/protocol/mail/build.gradle.kts index 204f331e2d0..8ac552926ef 100644 --- a/src/protocol/mail/build.gradle.kts +++ b/src/protocol/mail/build.gradle.kts @@ -22,7 +22,7 @@ plugins { dependencies { api(projects.src.core) - api("javax.mail:mail") { + api("com.sun.mail:javax.mail") { exclude("javax.activation", "activation") } // There's no javax.activation:activation:1.2.0, so we use com.sun... diff --git a/src/protocol/mail/src/test/java/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommandTest.java b/src/protocol/mail/src/test/java/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommandTest.java new file mode 100644 index 00000000000..78379ed1467 --- /dev/null +++ b/src/protocol/mail/src/test/java/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommandTest.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jmeter.protocol.smtp.sampler.protocol; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Collections; + +import javax.mail.Message; +import javax.mail.internet.InternetAddress; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +class SendMailCommandTest { + + private static final String NON_ASCII_FILE_NAME = "\u0442\u0435\u043a\u0441\u0442.txt"; // Russian for "text" + + @TempDir + File tempDir; + + @Test + void testNonAsciiAttachmentFileNameIsEncodedPerRfc2231() throws Exception { + SendMailCommand sendMailCommand = createSendMailCommandWithAttachment(NON_ASCII_FILE_NAME); + String rawMessage = writeMessageToString(sendMailCommand.prepareMessage()); + // The file name must be encoded according to RFC 2231, so that the + // recipients see the original file name (see issue #6652) + assertTrue( + rawMessage.contains("filename*=UTF-8''%D1%82%D0%B5%D0%BA%D1%81%D1%82.txt"), + "filename* parameter with RFC 2231 encoded file name expected in:\n" + rawMessage); + // The mangled name must not appear anywhere + assertFalse(rawMessage.contains("B5:AB"), "mangled file name found in:\n" + rawMessage); + } + + @Test + void testAsciiAttachmentFileNameIsNotEncoded() throws Exception { + SendMailCommand sendMailCommand = createSendMailCommandWithAttachment("attachment.txt"); + String rawMessage = writeMessageToString(sendMailCommand.prepareMessage()); + assertTrue( + rawMessage.contains("filename=attachment.txt"), + "plain ASCII file name expected in:\n" + rawMessage); + assertFalse(rawMessage.contains("filename*="), "unexpected RFC 2231 encoding in:\n" + rawMessage); + } + + private SendMailCommand createSendMailCommandWithAttachment(String attachmentName) throws Exception { + File attachment = new File(tempDir, attachmentName); + Files.writeString(attachment.toPath(), "attachment content", StandardCharsets.UTF_8); + + SendMailCommand sendMailCommand = new SendMailCommand(); + sendMailCommand.setSmtpServer("localhost"); + sendMailCommand.setSmtpPort("25"); + sendMailCommand.setConnectionTimeOut("1000"); + sendMailCommand.setTimeOut("1000"); + sendMailCommand.setSender("from@example.com"); + sendMailCommand.setReceiverTo(Collections.singletonList(new InternetAddress("to@example.com"))); + sendMailCommand.setSubject("attachment file name test"); + sendMailCommand.setMailBody("body"); + sendMailCommand.addAttachment(attachment); + return sendMailCommand; + } + + private static String writeMessageToString(Message message) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try (outputStream) { + message.writeTo(outputStream); + } + return outputStream.toString(StandardCharsets.UTF_8); + } +} diff --git a/xdocs/changes.xml b/xdocs/changes.xml index 13e0d097e6d..c3300497f38 100644 --- a/xdocs/changes.xml +++ b/xdocs/changes.xml @@ -98,6 +98,7 @@ Summary
  • Update json-path to 2.10.0 for JSON query expressions.
  • Update Neo4j Java driver to 6.x for Bolt-based database tests.
  • Update Rhino JavaScript engine to 1.8.0 for JSR-223 JavaScript execution.
  • +
  • Update javax.mail to 1.6.2 from 1.5.0-b01, so mail attachments with non-ASCII file names are encoded correctly.
  • UI

    @@ -109,6 +110,7 @@ Summary Bug fixes

    General