Skip to content

Commit 2760497

Browse files
author
Roger Riggs
committed
8237368: Problem with NullPointerException in RMI TCPEndpoint.read
Reviewed-by: mchung, alanb
1 parent f8f98bd commit 2760497

File tree

2 files changed

+114
-1
lines changed

2 files changed

+114
-1
lines changed

src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ public static TCPEndpoint read(ObjectInput in)
554554
host = in.readUTF();
555555
port = in.readInt();
556556
csf = (RMIClientSocketFactory) in.readObject();
557-
if (Proxy.isProxyClass(csf.getClass())) {
557+
if (csf != null && Proxy.isProxyClass(csf.getClass())) {
558558
throw new IOException("Invalid SocketFactory");
559559
}
560560
break;
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
25+
import java.io.IOException;
26+
import java.io.Serializable;
27+
import java.io.ObjectInputStream;
28+
import java.net.Socket;
29+
import java.rmi.Remote;
30+
import java.rmi.RemoteException;
31+
import java.rmi.server.RMIClientSocketFactory;
32+
import java.rmi.server.RMISocketFactory;
33+
import java.rmi.server.UnicastRemoteObject;
34+
35+
/* @test
36+
* @bug 8237368
37+
* @summary Allow custom socket factory to be null in TCPEndpoint.
38+
* @run main/othervm TCPEndpointReadBug
39+
*/
40+
public class TCPEndpointReadBug {
41+
42+
public static void main(String[] args) throws Exception {
43+
final I implC = new C();
44+
final I remoteC = (I)UnicastRemoteObject.exportObject(
45+
implC, 0, new CSF(), RMISocketFactory.getDefaultSocketFactory());
46+
47+
// Pass a remote object with a custom socket factory as an argument
48+
remoteC.echo(remoteC);
49+
50+
// Pass nothing and get an object with a custom socket factory in return
51+
remoteC.echo(null);
52+
}
53+
54+
interface I extends Remote {
55+
I echo(I intf) throws RemoteException;
56+
}
57+
58+
static class C implements I {
59+
@Override
60+
public I echo(I intf) {
61+
try {
62+
return (I)UnicastRemoteObject
63+
.exportObject(new C(),0, new CSF(), RMISocketFactory.getDefaultSocketFactory());
64+
} catch (RemoteException e) {
65+
e.printStackTrace();
66+
}
67+
return null;
68+
}
69+
}
70+
71+
/**
72+
* A configurable socket factory in which for test purposes supplies null.
73+
*/
74+
static class CSF implements Serializable, RMIClientSocketFactory {
75+
private static final long serialVersionUID = 1;
76+
77+
@Override
78+
public boolean equals(Object object) {
79+
return object instanceof CSF;
80+
}
81+
82+
@Override
83+
public int hashCode() {
84+
return 424242;
85+
}
86+
87+
@Override
88+
public Socket createSocket(String host, int port)
89+
throws IOException {
90+
91+
final RMIClientSocketFactory defaultFactory =
92+
RMISocketFactory.getDefaultSocketFactory();
93+
return defaultFactory.createSocket(host, port);
94+
}
95+
96+
/**
97+
* Use writeReplace to use a different client socket factory. In the
98+
* problematic case, the replacement is null.
99+
*/
100+
private Object writeReplace() {
101+
return null;
102+
}
103+
104+
/**
105+
* Instances of this class should never be deserialized because they
106+
* are always replaced during serialization.
107+
*/
108+
@SuppressWarnings("unused")
109+
private void readObject(ObjectInputStream in) {
110+
throw new AssertionError();
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)