undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,234 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.io.*;
import java.rmi.server.*;
import java.net.*;
public class Compress {
interface CompressConstants {
// constants for 6-bit code values
static final int NOP = 0; // no operation: used to pad words on flush()
static final int RAW = 1; // introduces raw byte format
static final int BASE = 2; // base for codes found in lookup table
static final String codeTable =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()";
}
public static class CompressRMIClientSocketFactory
implements java.rmi.server.RMIClientSocketFactory, Serializable {
public Socket createSocket(String host, int port)
throws IOException {
return ((Socket) new CompressSocket(host, port));
}
}
public static class CompressRMIServerSocketFactory
implements RMIServerSocketFactory,
Serializable {
public ServerSocket createServerSocket(int port)
throws IOException {
return ((ServerSocket) new CompressServerSocket(port));
}
}
public static class CompressSocket extends Socket {
private InputStream in;
private OutputStream out;
public CompressSocket() { super(); }
public CompressSocket(String host, int port) throws IOException {
super(host, port);
}
public InputStream getInputStream() throws IOException {
if (in == null) {
in = new CompressInputStream(super.getInputStream());
}
return in;
}
public OutputStream getOutputStream() throws IOException {
if (out == null) {
out = new CompressOutputStream(super.getOutputStream());
}
return out;
}
}
public static class CompressServerSocket extends ServerSocket {
public CompressServerSocket(int port) throws IOException {
super(port);
}
public Socket accept() throws IOException {
Socket s = new CompressSocket();
implAccept(s);
return s;
}
}
public static class CompressInputStream extends FilterInputStream
implements CompressConstants
{
public CompressInputStream(InputStream in) {
super(in);
}
// buffer of unpacked 6-bit codes from last 32-word read
int buf[] = new int[5];
// position of next code to read in buffer (5 == end of buffer)
int bufPos = 5;
public int read() throws IOException {
try {
int code;
do {
code = readCode();
} while (code == NOP); // ignore NOP codes
if (code >= BASE)
return codeTable.charAt(code - BASE);
else if (code == RAW) {
int high = readCode();
int low = readCode();
return (high << 4) | low;
} else
throw new IOException("unknown compression code: " + code);
} catch (EOFException e) {
return -1;
}
}
public int read(byte b[], int off, int len) throws IOException {
if (len <= 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
/*****
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
if (b != null) {
b[off + i] = (byte)c;
}
}
} catch (IOException ee) {
}
*****/
return i;
}
private int readCode() throws IOException {
if (bufPos == 5) {
int b1 = in.read();
int b2 = in.read();
int b3 = in.read();
int b4 = in.read();
if ((b1 | b2 | b3 | b4) < 0)
throw new EOFException();
int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
buf[0] = (pack >>> 24) & 0x3F;
buf[1] = (pack >>> 18) & 0x3F;
buf[2] = (pack >>> 12) & 0x3F;
buf[3] = (pack >>> 6) & 0x3F;
buf[4] = (pack >>> 0) & 0x3F;
bufPos = 0;
}
return buf[bufPos++];
}
}
public static class CompressOutputStream extends FilterOutputStream
implements CompressConstants
{
public CompressOutputStream(OutputStream out) {
super(out);
}
// buffer of 6-bit codes to pack into next 32-bit word
int buf[] = new int[5];
// number of valid codes pending in buffer
int bufPos = 0;
public void write(int b) throws IOException {
b &= 0xFF; // force argument to a byte
int pos = codeTable.indexOf((char)b);
if (pos != -1)
writeCode(BASE + pos);
else {
writeCode(RAW);
writeCode(b >> 4);
writeCode(b & 0xF);
}
}
public void write(byte b[], int off, int len) throws IOException {
/*
* This is quite an inefficient implementation, because it has to
* call the other write method for every byte in the array. It
* could be optimized for performance by doing all the processing
* in this method.
*/
for (int i = 0; i < len; i++)
write(b[off + i]);
}
public void flush() throws IOException {
while (bufPos > 0)
writeCode(NOP);
}
private void writeCode(int c) throws IOException {
buf[bufPos++] = c;
if (bufPos == 5) { // write next word when we have 5 codes
int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) |
(buf[3] << 6) | buf[4];
out.write((pack >>> 24) & 0xFF);
out.write((pack >>> 16) & 0xFF);
out.write((pack >>> 8) & 0xFF);
out.write((pack >>> 0) & 0xFF);
bufPos = 0;
}
}
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.rmi.*;
import java.rmi.server.*;
interface Hello extends Remote {
String sayHello() throws RemoteException;
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
public class HelloImpl
extends UnicastRemoteObject
implements Hello
{
public static boolean clientCalledSuccessfully = false;
public HelloImpl() throws RemoteException {
super(0);
}
public synchronized String sayHello() {
HelloImpl.clientCalledSuccessfully = true;
System.out.println("hello method called");
this.notifyAll();
return "hello";
}
public static void main(String[] args) {
/*
* The following line is required with the JDK 1.2 VM so that the
* VM can exit gracefully when this test completes. Otherwise, the
* conservative garbage collector will find a handle to the server
* object on the native stack and not clear the weak reference to
* it in the RMI runtime's object table.
*/
Object dummy = new Object();
Hello hello = null;
Registry registry = null;
try {
String protocol = "";
if (args.length >= 1)
protocol = args[0];
int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
registry = java.rmi.registry.LocateRegistry.
getRegistry("localhost", registryPort,
new Compress.CompressRMIClientSocketFactory());
UseCustomSocketFactory.checkStub(registry, "RMIClientSocket");
hello = (Hello) registry.lookup("/HelloServer");
/* lookup server */
System.err.println(hello.sayHello() +
", remote greeting.");
} catch (Exception e) {
System.err.println("EXCEPTION OCCURRED:");
e.printStackTrace();
} finally {
hello = null;
}
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// Stub class generated by rmic, do not edit.
// Contents subject to change without notice.
public final class HelloImpl_Stub
extends java.rmi.server.RemoteStub
implements Hello, java.rmi.Remote
{
private static java.rmi.server.Operation[] operations = {
new java.rmi.server.Operation("java.lang.String sayHello()")
};
private static final long interfaceHash = 6486744599627128933L;
private static final long serialVersionUID = 2;
private static boolean useNewInvoke;
private static java.lang.reflect.Method $method_sayHello_0;
static {
try {
java.rmi.server.RemoteRef.class.getMethod("invoke",
new java.lang.Class[] {
java.rmi.Remote.class,
java.lang.reflect.Method.class,
java.lang.Object[].class,
long.class
});
useNewInvoke = true;
$method_sayHello_0 = Hello.class.getMethod("sayHello", new java.lang.Class[] {});
} catch (java.lang.NoSuchMethodException e) {
useNewInvoke = false;
}
}
// constructors
public HelloImpl_Stub() {
super();
}
public HelloImpl_Stub(java.rmi.server.RemoteRef ref) {
super(ref);
}
// methods from remote interfaces
// implementation of sayHello()
public java.lang.String sayHello()
throws java.rmi.RemoteException
{
try {
if (useNewInvoke) {
Object $result = ref.invoke(this, $method_sayHello_0, null, 6043973830760146143L);
return ((java.lang.String) $result);
} else {
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
ref.invoke(call);
java.lang.String $result;
try {
java.io.ObjectInput in = call.getInputStream();
$result = (java.lang.String) in.readObject();
} catch (java.io.IOException e) {
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
} catch (java.lang.ClassNotFoundException e) {
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
} finally {
ref.done(call);
}
return $result;
}
} catch (java.lang.RuntimeException e) {
throw e;
} catch (java.rmi.RemoteException e) {
throw e;
} catch (java.lang.Exception e) {
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
}
}
}

View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4148850
*
* @summary synopsis: need to obtain remote references securely
*
* @author Laird Dornin; code borrowed from Ann Wollrath
*
* @library ../../../../testlibrary
* @modules java.rmi/sun.rmi.registry
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
* @build TestLibrary Compress Hello HelloImpl HelloImpl_Stub
* @run main/othervm/timeout=240 UseCustomSocketFactory
*/
import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
/**
* Test ensures that the rmiregistry is capable of running over customx
* (i.e. compression) client and server socket factories.
*/
public class UseCustomSocketFactory {
Hello hello = null;
public static void main(String[] args) {
Registry registry = null;
HelloImpl impl = null;
System.out.println("\nRegression test for bug 4148850\n");
int registryPort = -1;
try {
impl = new HelloImpl();
/* Make sure that the rmiregistry can communicate over a
* custom socket. Ensure that the functionality exists to
* allow the rmiregistry to be secure.
*/
registry = LocateRegistry.
createRegistry(0,
new Compress.CompressRMIClientSocketFactory(),
new Compress.CompressRMIServerSocketFactory());
registryPort = TestLibrary.getRegistryPort(registry);
registry.rebind("/HelloServer", impl);
checkStub(registry, "RMIServerSocket");
} catch (Exception e) {
TestLibrary.bomb("creating registry", e);
}
JavaVM serverVM = new JavaVM("HelloImpl",
" -Drmi.registry.port=" +
registryPort,
"");
try {
/*
* spawn VM for HelloServer which will download a client socket
* factory
*/
serverVM.start();
synchronized (impl) {
System.out.println("waiting for remote notification");
if (!HelloImpl.clientCalledSuccessfully) {
impl.wait(75 * 1000);
}
if (!HelloImpl.clientCalledSuccessfully) {
throw new RuntimeException("Client did not execute call in time...");
}
}
System.err.println("\nRegression test for bug 4148850 passed.\n ");
} catch (Exception e) {
TestLibrary.bomb("test failed", e);
} finally {
serverVM.destroy();
try {
registry.unbind("/HelloServer");
} catch (Exception e) {
TestLibrary.bomb("unbinding HelloServer", e);
}
TestLibrary.unexport(registry);
TestLibrary.unexport(impl);
impl = null;
registry = null;
}
}
static void checkStub(Object stub, String toCheck) throws RemoteException {
System.err.println("Ensuring that the stub contains a socket factory string: " +
toCheck);
System.err.println(stub);
if (stub.toString().indexOf(toCheck) < 0) {
throw new RemoteException("RemoteStub.toString() did not contain instance of "
+ toCheck);
}
}
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
interface CompressConstants {
// constants for 6-bit code values
static final int NOP = 0; // no operation: used to pad words on flush()
static final int RAW = 1; // introduces raw byte format
static final int BASE = 2; // base for codes found in lookup table
static final String codeTable =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()";
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.io.*;
class CompressInputStream extends FilterInputStream
implements CompressConstants
{
public CompressInputStream(InputStream in) {
super(in);
}
// buffer of unpacked 6-bit codes from last 32-word read
int buf[] = new int[5];
// position of next code to read in buffer (5 == end of buffer)
int bufPos = 5;
public int read() throws IOException {
try {
int code;
do {
code = readCode();
} while (code == NOP); // ignore NOP codes
if (code >= BASE)
return codeTable.charAt(code - BASE);
else if (code == RAW) {
int high = readCode();
int low = readCode();
return (high << 4) | low;
} else
throw new IOException("unknown compression code: " + code);
} catch (EOFException e) {
return -1;
}
}
public int read(byte b[], int off, int len) throws IOException {
if (len <= 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
/*****
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
if (b != null) {
b[off + i] = (byte)c;
}
}
} catch (IOException ee) {
}
*****/
return i;
}
private int readCode() throws IOException {
if (bufPos == 5) {
int b1 = in.read();
int b2 = in.read();
int b3 = in.read();
int b4 = in.read();
if ((b1 | b2 | b3 | b4) < 0)
throw new EOFException();
int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
buf[0] = (pack >>> 24) & 0x3F;
buf[1] = (pack >>> 18) & 0x3F;
buf[2] = (pack >>> 12) & 0x3F;
buf[3] = (pack >>> 6) & 0x3F;
buf[4] = (pack >>> 0) & 0x3F;
bufPos = 0;
}
return buf[bufPos++];
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.io.*;
class CompressOutputStream extends FilterOutputStream
implements CompressConstants
{
public CompressOutputStream(OutputStream out) {
super(out);
}
// buffer of 6-bit codes to pack into next 32-bit word
int buf[] = new int[5];
// number of valid codes pending in buffer
int bufPos = 0;
public void write(int b) throws IOException {
b &= 0xFF; // force argument to a byte
int pos = codeTable.indexOf((char)b);
if (pos != -1)
writeCode(BASE + pos);
else {
writeCode(RAW);
writeCode(b >> 4);
writeCode(b & 0xF);
}
}
public void write(byte b[], int off, int len) throws IOException {
/*
* This is quite an inefficient implementation, because it has to
* call the other write method for every byte in the array. It
* could be optimized for performance by doing all the processing
* in this method.
*/
for (int i = 0; i < len; i++)
write(b[off + i]);
}
public void flush() throws IOException {
while (bufPos > 0)
writeCode(NOP);
}
private void writeCode(int c) throws IOException {
buf[bufPos++] = c;
if (bufPos == 5) { // write next word when we have 5 codes
int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) |
(buf[3] << 6) | buf[4];
out.write((pack >>> 24) & 0xFF);
out.write((pack >>> 16) & 0xFF);
out.write((pack >>> 8) & 0xFF);
out.write((pack >>> 0) & 0xFF);
bufPos = 0;
}
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.rmi.*;
public interface Echo extends Remote {
byte[] echoNot(byte[] data) throws RemoteException;
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.rmi.*;
import java.rmi.server.*;
public class EchoImpl
extends UnicastRemoteObject
implements Echo
{
private static final byte[] pattern = { (byte) 'A' };
public EchoImpl(String protocol) throws RemoteException {
super(0,
new MultiSocketFactory.ClientFactory(protocol, pattern),
new MultiSocketFactory.ServerFactory(protocol, pattern));
}
public byte[] echoNot(byte[] data) {
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++)
result[i] = (byte) ~data[i];
return result;
}
public static void main(String[] args) {
/*
* The following line is required with the JDK 1.2 VM so that the
* VM can exit gracefully when this test completes. Otherwise, the
* conservative garbage collector will find a handle to the server
* object on the native stack and not clear the weak reference to
* it in the RMI runtime's object table.
*/
Object dummy = new Object();
try {
String protocol = "";
if (args.length >= 1)
protocol = args[0];
System.out.println("EchoServer: creating remote object");
EchoImpl impl = new EchoImpl(protocol);
int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
System.out.println("EchoServer: binding in registry");
Naming.rebind("//:" + registryPort +
"/EchoServer", impl);
System.out.println("EchoServer ready.");
} catch (Exception e) {
System.err.println("EXCEPTION OCCURRED:");
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// Stub class generated by rmic, do not edit.
// Contents subject to change without notice.
public final class EchoImpl_Stub
extends java.rmi.server.RemoteStub
implements Echo, java.rmi.Remote
{
private static final long serialVersionUID = 2;
private static java.lang.reflect.Method $method_echoNot_0;
static {
try {
$method_echoNot_0 = Echo.class.getMethod("echoNot", new java.lang.Class[] {byte[].class});
} catch (java.lang.NoSuchMethodException e) {
throw new java.lang.NoSuchMethodError(
"stub class initialization failed");
}
}
// constructors
public EchoImpl_Stub(java.rmi.server.RemoteRef ref) {
super(ref);
}
// methods from remote interfaces
// implementation of echoNot(byte[])
public byte[] echoNot(byte[] $param_arrayOf_byte_1)
throws java.rmi.RemoteException
{
try {
Object $result = ref.invoke(this, $method_echoNot_0, new java.lang.Object[] {$param_arrayOf_byte_1}, -4295721514897591756L);
return ((byte[]) $result);
} catch (java.lang.RuntimeException e) {
throw e;
} catch (java.rmi.RemoteException e) {
throw e;
} catch (java.lang.Exception e) {
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
}
}
}

View file

@ -0,0 +1,226 @@
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*/
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
import java.util.zip.*;
public class MultiSocketFactory {
private static RMISocketFactory def =
RMISocketFactory.getDefaultSocketFactory();
public static class ServerFactory
implements RMIServerSocketFactory, Serializable
{
private String protocol;
private byte[] data;
public ServerFactory(String protocol, byte[] data) {
this.protocol = protocol;
this.data = data;
}
public ServerSocket createServerSocket(int port) throws IOException
{
if (protocol.equals("compress")) {
return new CompressServerSocket(port);
} else if (protocol.equals("xor")) {
if (data == null || data.length != 1)
throw new IOException("invalid argument for XOR protocol");
return new XorServerSocket(port, data[0]);
}
return def.createServerSocket(port);
}
}
public static class ClientFactory
implements RMIClientSocketFactory, Serializable
{
private String protocol;
private byte[] data;
public ClientFactory(String protocol, byte[] data) {
this.protocol = protocol;
this.data = data;
}
public Socket createSocket(String host, int port)
throws IOException
{
if (protocol.equals("compress")) {
return new CompressSocket(host, port);
} else if (protocol.equals("xor")) {
if (data == null || data.length != 1)
throw new IOException("invalid argument for XOR protocol");
return new XorSocket(host, port, data[0]);
}
return def.createSocket(host, port);
}
}
static class CompressSocket extends Socket {
private InputStream in;
private OutputStream out;
public CompressSocket() { super(); }
public CompressSocket(String host, int port) throws IOException {
super(host, port);
}
public InputStream getInputStream() throws IOException {
if (in == null) {
in = new CompressInputStream(super.getInputStream());
}
return in;
}
public OutputStream getOutputStream() throws IOException {
if (out == null) {
out = new CompressOutputStream(super.getOutputStream());
}
return out;
}
}
static class CompressServerSocket extends ServerSocket {
public CompressServerSocket(int port) throws IOException {
super(port);
}
public Socket accept() throws IOException {
Socket s = new CompressSocket();
implAccept(s);
return s;
}
}
static class XorSocket extends Socket {
private byte pattern;
private InputStream in;
private OutputStream out;
public XorSocket(byte pattern) { super(); this.pattern = pattern; }
public XorSocket(String host, int port, byte pattern)
throws IOException
{
super(host, port);
this.pattern = pattern;
}
public InputStream getInputStream() throws IOException {
if (in == null) {
in = new XorInputStream(super.getInputStream(), pattern);
}
return in;
}
public OutputStream getOutputStream() throws IOException {
if (out == null) {
out = new XorOutputStream(super.getOutputStream(), pattern);
}
return out;
}
}
static class XorServerSocket extends ServerSocket {
private byte pattern;
public XorServerSocket(int port, byte pattern) throws IOException {
super(port);
this.pattern = pattern;
}
public Socket accept() throws IOException {
Socket s = new XorSocket(pattern);
implAccept(s);
return s;
}
}
static class XorOutputStream extends FilterOutputStream {
private byte pattern;
public XorOutputStream(OutputStream out, byte pattern) {
super(out);
this.pattern = pattern;
}
public void write(int b) throws IOException {
out.write(b ^ pattern);
out.flush();
}
public void write(byte b[], int off, int len) throws IOException {
for (int i = 0; i < len; i++)
write(b[off + i]);
}
}
static class XorInputStream extends FilterInputStream {
private byte pattern;
public XorInputStream(InputStream in, byte pattern) {
super(in);
this.pattern = pattern;
}
public int read() throws IOException {
int b = in.read();
// System.out.print("BEFORE: " + Integer.toHexString(b));
if (b != -1)
b = (b ^ pattern) & 0xFF;
// System.out.println("\tAFTER: " + Integer.toHexString(b));
return b;
}
public int read(byte b[], int off, int len) throws IOException {
if (len <= 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
/*****
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
if (b != null) {
b[off + i] = (byte)c;
}
}
} catch (IOException ee) {
}
*****/
return i;
}
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
/* @test
* @bug 8237368
* @summary Allow custom socket factory to be null in TCPEndpoint.
* @run main/othervm TCPEndpointReadBug
*/
public class TCPEndpointReadBug {
public static void main(String[] args) throws Exception {
final I implC = new C();
final I remoteC = (I)UnicastRemoteObject.exportObject(
implC, 0, new CSF(), RMISocketFactory.getDefaultSocketFactory());
// Pass a remote object with a custom socket factory as an argument
remoteC.echo(remoteC);
// Pass nothing and get an object with a custom socket factory in return
remoteC.echo(null);
}
interface I extends Remote {
I echo(I intf) throws RemoteException;
}
static class C implements I {
@Override
public I echo(I intf) {
try {
return (I)UnicastRemoteObject
.exportObject(new C(),0, new CSF(), RMISocketFactory.getDefaultSocketFactory());
} catch (RemoteException e) {
e.printStackTrace();
}
return null;
}
}
/**
* A configurable socket factory in which for test purposes supplies null.
*/
static class CSF implements Serializable, RMIClientSocketFactory {
private static final long serialVersionUID = 1;
@Override
public boolean equals(Object object) {
return object instanceof CSF;
}
@Override
public int hashCode() {
return 424242;
}
@Override
public Socket createSocket(String host, int port)
throws IOException {
final RMIClientSocketFactory defaultFactory =
RMISocketFactory.getDefaultSocketFactory();
return defaultFactory.createSocket(host, port);
}
/**
* Use writeReplace to use a different client socket factory. In the
* problematic case, the replacement is null.
*/
private Object writeReplace() {
return null;
}
/**
* Instances of this class should never be deserialized because they
* are always replaced during serialization.
*/
@SuppressWarnings("unused")
private void readObject(ObjectInputStream in) {
throw new AssertionError();
}
}
}

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4127826
*
* @summary synopsis: need to download factories for use with custom socket
* types
* @author Ann Wollrath
*
* @library ../../../../testlibrary
* @modules java.rmi/sun.rmi.registry
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
* @build TestLibrary JavaVM Echo EchoImpl EchoImpl_Stub
* @run main/othervm/timeout=120 UseCustomSocketFactory
*/
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.*;
import java.rmi.registry.*;
public class UseCustomSocketFactory {
public static void main(String[] args) {
int registryPort = -1;
String[] protocols = new String[] { "", "compress", "xor" };
System.out.println("\nRegression test for bug 4127826\n");
try {
Registry registry = TestLibrary.createRegistryOnEphemeralPort();
registryPort = TestLibrary.getRegistryPort(registry);
} catch (RemoteException e) {
TestLibrary.bomb("creating registry", e);
}
for (String protocol : protocols) {
JavaVM serverVM = new JavaVM("EchoImpl",
" -Drmi.registry.port=" +
registryPort, protocol);
System.err.println("\nusing protocol: " +
("".equals(protocol) ? "none" : protocol));
try {
/* spawn VM for EchoServer */
serverVM.start();
/* lookup server */
Echo obj = null;
// 16 seconds timeout
long stopTime = System.currentTimeMillis() + 16000;
do {
try {
obj = (Echo) Naming.lookup("//:" + registryPort +
"/EchoServer");
break;
} catch (NotBoundException e) {
try {
Thread.sleep(200);
} catch (InterruptedException ignore) {
}
}
} while (System.currentTimeMillis() < stopTime);
if (obj == null)
TestLibrary.bomb("server not bound in 8 tries", null);
/* invoke remote method and print result*/
System.err.println("Bound to " + obj);
byte[] data = ("Greetings, citizen " +
System.getProperty("user.name") + "!"). getBytes();
byte[] result = obj.echoNot(data);
for (int j = 0; j < result.length; j++)
result[j] = (byte) ~result[j];
System.err.println("Result: " + new String(result));
} catch (IOException e) {
TestLibrary.bomb("test failed", e);
} finally {
serverVM.destroy();
try {
Naming.unbind("//:" + registryPort +
"/EchoServer");
} catch (RemoteException | NotBoundException | MalformedURLException e) {
TestLibrary.bomb("unbinding EchoServer", e);
}
}
}
}
}