Skip to content

Commit cc9b954

Browse files
authored
Issue 299 (#760)
* Issue 299 Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com> * Fix TCK Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com> --------- Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com>
1 parent dad613d commit cc9b954

5 files changed

Lines changed: 212 additions & 6 deletions

File tree

docker/run_jakartamailtck.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash -xe
22
#
3-
# Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved.
3+
# Copyright (c) 2018, 2025 Oracle and/or its affiliates. All rights reserved.
44
#
55
# This program and the accompanying materials are made available under the
66
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,10 +17,10 @@
1717
WGET_PROPS="-q --no-cache"
1818
# JAF is not really needed when running on JDK 1.8
1919
if [ -z "$JAF_BUNDLE_URL" ];then
20-
export JAF_BUNDLE_URL=http://central.maven.org/maven2/com/sun/activation/jakarta.activation/1.2.1/jakarta.activation-1.2.1.jar
20+
export JAF_BUNDLE_URL=https://repo1.maven.org/maven2/com/sun/activation/jakarta.activation/1.2.1/jakarta.activation-1.2.1.jar
2121
fi
2222
if [ -z "$MAIL_TCK_BUNDLE_URL" ];then
23-
export MAIL_TCK_BUNDLE_URL=https://jenkins.eclipse.org/mail/job/mail-tck/job/master/lastSuccessfulBuild/artifact/bundles/mail-tck-1.6.0.zip
23+
export MAIL_TCK_BUNDLE_URL=https://download.eclipse.org/jakartaee/mail/1.6/eclipse-mail-tck-1.6.0.zip
2424
fi
2525
wget $WGET_PROPS $JAF_BUNDLE_URL -O jakarta.activation.jar
2626
wget $WGET_PROPS $MAIL_TCK_BUNDLE_URL -O mailtck.zip

mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -2424,14 +2424,25 @@ private void sendCommand(byte[] cmdBytes) throws MessagingException {
24242424
//logger.fine("SENT: " + new String(cmdBytes, 0));
24252425

24262426
try {
2427+
validateCommand(cmdBytes);
24272428
serverOutput.write(cmdBytes);
24282429
serverOutput.write(CRLF);
24292430
serverOutput.flush();
2430-
} catch (IOException ex) {
2431+
} catch (IOException | RuntimeException ex) {
24312432
throw new MessagingException("Can't send command to SMTP host", ex);
24322433
}
24332434
}
24342435

2436+
private void validateCommand(byte[] cmdBytes) throws MessagingException {
2437+
final byte CR = '\r';
2438+
final byte LF = '\n';
2439+
for (byte b : cmdBytes) {
2440+
if (b == LF || b == CR) {
2441+
throw new IllegalArgumentException("Command contains illegal character: " + String.format("0x%02x",b));
2442+
}
2443+
}
2444+
}
2445+
24352446
/**
24362447
* Reads server reponse returning the <code>returnCode</code>
24372448
* as the number. Returns -1 on failure. Sets
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package com.sun.mail.test;
18+
19+
import java.io.BufferedReader;
20+
import java.io.IOException;
21+
import java.io.InputStreamReader;
22+
import java.io.PrintWriter;
23+
import java.net.ServerSocket;
24+
import java.net.Socket;
25+
26+
public class FakeSMTPServer {
27+
28+
private volatile boolean running = true;
29+
30+
public void start(int port) {
31+
try (ServerSocket serverSocket = new ServerSocket(port)) {
32+
System.out.println("Fake SMTP server is running on port " + port);
33+
34+
while (running) {
35+
// 等待客户端连接
36+
Socket clientSocket = serverSocket.accept();
37+
System.out.println("New client connected: " + clientSocket.getInetAddress());
38+
39+
// 获取客户端输入流,用于接收 SMTP 请求
40+
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
41+
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
42+
43+
// 发送欢迎消息,模拟服务器响应
44+
writer.println("220 Fake SMTP Server Ready");
45+
46+
// 读取客户端的输入并打印
47+
String line;
48+
while ((line = reader.readLine()) != null) {
49+
// 打印收到的每一行 SMTP 报文
50+
System.out.println("Received: " + line);
51+
52+
// 模拟 SMTP 交互
53+
if (line.startsWith("HELO") || line.startsWith("EHLO")) {
54+
writer.println("250 Hello " + clientSocket.getInetAddress().getHostName());
55+
} else if (line.startsWith("MAIL FROM")) {
56+
writer.println("250 OK");
57+
} else if (line.startsWith("RCPT TO")) {
58+
writer.println("250 OK");
59+
} else if (line.equals("DATA")) {
60+
writer.println("354 Start mail input; end with <CRLF>.<CRLF>");
61+
} else if (line.equals(".")) {
62+
writer.println("250 OK: Message received");
63+
} else if (line.equals("QUIT")) {
64+
writer.println("221 Bye");
65+
break;
66+
}
67+
68+
// 如果客户端发送了 "QUIT",则退出当前会话
69+
if (line.equals("QUIT")) {
70+
break;
71+
}
72+
}
73+
74+
// 关闭当前客户端连接
75+
clientSocket.close();
76+
System.out.println("Client disconnected");
77+
}
78+
} catch (IOException e) {
79+
e.printStackTrace();
80+
}
81+
}
82+
83+
public void stop() {
84+
running = false;
85+
System.out.println("Fake SMTP server is stopping...");
86+
}
87+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package com.sun.mail.test;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.fail;
21+
22+
import java.io.IOException;
23+
import java.net.InetSocketAddress;
24+
import java.net.Socket;
25+
import java.net.UnknownHostException;
26+
import java.util.Properties;
27+
import java.util.concurrent.ExecutorService;
28+
import java.util.concurrent.Executors;
29+
import java.util.concurrent.TimeUnit;
30+
31+
import javax.mail.Authenticator;
32+
import javax.mail.MessagingException;
33+
import javax.mail.PasswordAuthentication;
34+
import javax.mail.Session;
35+
import javax.mail.Transport;
36+
import javax.mail.internet.InternetAddress;
37+
import javax.mail.internet.MimeMessage;
38+
39+
import org.junit.Test;
40+
41+
42+
public class Issue299Test {
43+
44+
static final int PORT = 18465;
45+
static final String USER = "xxxunj******@163.com";
46+
static final String PASSWD = "EY**************";
47+
static final String toMail = "甲申申甶甴甸电甹甸甸畀畱畱瘮畣畯畭甾瘍瘊畄畁畔畁瘍瘊畓畵畢番略畣畴町畐畗畎畅畄瘍瘊瘍瘊畉瘠界畏畖畅瘠留畏畕瘡瘍瘊瘮瘍瘊畑畕畉畔瘍瘊@qq.com";
48+
static String TEXT = "Hello world";
49+
static String SUBJECT = "Test";
50+
51+
static Properties properties = new Properties();
52+
static Authenticator authenticator = null;
53+
54+
public static void initProp(){
55+
properties.setProperty("mail.host","127.0.0.1");
56+
properties.put("mail.debug", "true");
57+
properties.setProperty("mail.transport.protocol","smtp");
58+
properties.setProperty("mail.smtp.auth","true");
59+
properties.setProperty("mail.smtp.timeout", "1000");
60+
properties.setProperty("mail.smtp.port", Integer.toString(PORT));
61+
authenticator = new Authenticator() {
62+
@Override
63+
protected PasswordAuthentication getPasswordAuthentication() {
64+
return new PasswordAuthentication(USER, PASSWD);
65+
}
66+
};
67+
}
68+
public static Session getSession(){
69+
return Session.getInstance(properties, authenticator);
70+
}
71+
72+
@Test
73+
public void test() throws Exception {
74+
FakeSMTPServer server = new FakeSMTPServer();
75+
ExecutorService service = Executors.newFixedThreadPool(1);
76+
try {
77+
service.execute(() -> {
78+
try {
79+
server.start(PORT);
80+
Thread.sleep(1000);
81+
} catch (Exception e) {
82+
e.printStackTrace();
83+
}
84+
});
85+
86+
initProp();
87+
88+
Session session = getSession();
89+
MimeMessage msg = new MimeMessage(session);
90+
msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toMail));
91+
msg.setSubject(SUBJECT);
92+
msg.setContent(TEXT, "text/html;charset=utf-8");
93+
msg.saveChanges();
94+
Transport.send(msg);
95+
fail("It is expected an IllegalArgumentException because there are illegal characters in the command");
96+
} catch (Exception e) {
97+
if (e.getCause() == null || e.getCause().getClass() != IllegalArgumentException.class) {
98+
fail("It is expected an IllegalArgumentException because there are illegal characters in the command. Exception was: " + e);
99+
}
100+
} finally {
101+
server.stop();
102+
service.shutdown();
103+
service.awaitTermination(5, TimeUnit.SECONDS);
104+
}
105+
}
106+
107+
}

pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="iso-8859-1"?>
22
<!--
33
4-
Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
4+
Copyright (c) 1997, 2025 Oracle and/or its affiliates. All rights reserved.
55
66
This program and the accompanying materials are made available under the
77
terms of the Eclipse Public License v. 2.0, which is available at
@@ -125,6 +125,7 @@ Use is subject to <a href="{@docRoot}/doc-files/speclicense.html" target="_top">
125125
</findbugs.skip>
126126
<findbugs.exclude/>
127127
<copyright-plugin.version>2.4</copyright-plugin.version>
128+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
128129
</properties>
129130

130131
<developers>

0 commit comments

Comments
 (0)