8232419: Improve Registry registration
Reviewed-by: smarks, chegar
This commit is contained in:
parent
34e36a8c01
commit
796f3ba8be
@ -453,16 +453,50 @@ public class ObjectInputStream
|
||||
* @throws IOException Any of the usual Input/Output related exceptions.
|
||||
*/
|
||||
public final Object readObject()
|
||||
throws IOException, ClassNotFoundException {
|
||||
return readObject(Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a String and only a string.
|
||||
*
|
||||
* @return the String read
|
||||
* @throws EOFException If end of file is reached.
|
||||
* @throws IOException If other I/O error has occurred.
|
||||
*/
|
||||
private String readString() throws IOException {
|
||||
try {
|
||||
return (String) readObject(String.class);
|
||||
} catch (ClassNotFoundException cnf) {
|
||||
throw new IllegalStateException(cnf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to read an object from the ObjectInputStream of the expected type.
|
||||
* Called only from {@code readObject()} and {@code readString()}.
|
||||
* Only {@code Object.class} and {@code String.class} are supported.
|
||||
*
|
||||
* @param type the type expected; either Object.class or String.class
|
||||
* @return an object of the type
|
||||
* @throws IOException Any of the usual Input/Output related exceptions.
|
||||
* @throws ClassNotFoundException Class of a serialized object cannot be
|
||||
* found.
|
||||
*/
|
||||
private final Object readObject(Class<?> type)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
if (enableOverride) {
|
||||
return readObjectOverride();
|
||||
}
|
||||
|
||||
if (! (type == Object.class || type == String.class))
|
||||
throw new AssertionError("internal error");
|
||||
|
||||
// if nested read, passHandle contains handle of enclosing object
|
||||
int outerHandle = passHandle;
|
||||
try {
|
||||
Object obj = readObject0(false);
|
||||
Object obj = readObject0(type, false);
|
||||
handles.markDependency(outerHandle, passHandle);
|
||||
ClassNotFoundException ex = handles.lookupException(passHandle);
|
||||
if (ex != null) {
|
||||
@ -557,7 +591,7 @@ public class ObjectInputStream
|
||||
// if nested read, passHandle contains handle of enclosing object
|
||||
int outerHandle = passHandle;
|
||||
try {
|
||||
Object obj = readObject0(true);
|
||||
Object obj = readObject0(Object.class, true);
|
||||
handles.markDependency(outerHandle, passHandle);
|
||||
ClassNotFoundException ex = handles.lookupException(passHandle);
|
||||
if (ex != null) {
|
||||
@ -1577,8 +1611,10 @@ public class ObjectInputStream
|
||||
|
||||
/**
|
||||
* Underlying readObject implementation.
|
||||
* @param type a type expected to be deserialized; non-null
|
||||
* @param unshared true if the object can not be a reference to a shared object, otherwise false
|
||||
*/
|
||||
private Object readObject0(boolean unshared) throws IOException {
|
||||
private Object readObject0(Class<?> type, boolean unshared) throws IOException {
|
||||
boolean oldMode = bin.getBlockDataMode();
|
||||
if (oldMode) {
|
||||
int remain = bin.currentBlockRemaining();
|
||||
@ -1610,13 +1646,20 @@ public class ObjectInputStream
|
||||
return readNull();
|
||||
|
||||
case TC_REFERENCE:
|
||||
return readHandle(unshared);
|
||||
// check the type of the existing object
|
||||
return type.cast(readHandle(unshared));
|
||||
|
||||
case TC_CLASS:
|
||||
if (type == String.class) {
|
||||
throw new ClassCastException("Cannot cast a class to java.lang.String");
|
||||
}
|
||||
return readClass(unshared);
|
||||
|
||||
case TC_CLASSDESC:
|
||||
case TC_PROXYCLASSDESC:
|
||||
if (type == String.class) {
|
||||
throw new ClassCastException("Cannot cast a class to java.lang.String");
|
||||
}
|
||||
return readClassDesc(unshared);
|
||||
|
||||
case TC_STRING:
|
||||
@ -1624,15 +1667,27 @@ public class ObjectInputStream
|
||||
return checkResolve(readString(unshared));
|
||||
|
||||
case TC_ARRAY:
|
||||
if (type == String.class) {
|
||||
throw new ClassCastException("Cannot cast an array to java.lang.String");
|
||||
}
|
||||
return checkResolve(readArray(unshared));
|
||||
|
||||
case TC_ENUM:
|
||||
if (type == String.class) {
|
||||
throw new ClassCastException("Cannot cast an enum to java.lang.String");
|
||||
}
|
||||
return checkResolve(readEnum(unshared));
|
||||
|
||||
case TC_OBJECT:
|
||||
if (type == String.class) {
|
||||
throw new ClassCastException("Cannot cast an object to java.lang.String");
|
||||
}
|
||||
return checkResolve(readOrdinaryObject(unshared));
|
||||
|
||||
case TC_EXCEPTION:
|
||||
if (type == String.class) {
|
||||
throw new ClassCastException("Cannot cast an exception to java.lang.String");
|
||||
}
|
||||
IOException ex = readFatalException();
|
||||
throw new WriteAbortedException("writing aborted", ex);
|
||||
|
||||
@ -2004,7 +2059,7 @@ public class ObjectInputStream
|
||||
|
||||
if (ccl == null) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
readObject0(false);
|
||||
readObject0(Object.class, false);
|
||||
}
|
||||
} else if (ccl.isPrimitive()) {
|
||||
if (ccl == Integer.TYPE) {
|
||||
@ -2029,7 +2084,7 @@ public class ObjectInputStream
|
||||
} else {
|
||||
Object[] oa = (Object[]) array;
|
||||
for (int i = 0; i < len; i++) {
|
||||
oa[i] = readObject0(false);
|
||||
oa[i] = readObject0(Object.class, false);
|
||||
handles.markDependency(arrayHandle, passHandle);
|
||||
}
|
||||
}
|
||||
@ -2393,7 +2448,7 @@ public class ObjectInputStream
|
||||
return;
|
||||
|
||||
default:
|
||||
readObject0(false);
|
||||
readObject0(Object.class, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2438,7 +2493,7 @@ public class ObjectInputStream
|
||||
int numPrimFields = fields.length - objVals.length;
|
||||
for (int i = 0; i < objVals.length; i++) {
|
||||
ObjectStreamField f = fields[numPrimFields + i];
|
||||
objVals[i] = readObject0(f.isUnshared());
|
||||
objVals[i] = readObject0(Object.class, f.isUnshared());
|
||||
if (f.getField() != null) {
|
||||
handles.markDependency(objHandle, passHandle);
|
||||
}
|
||||
@ -2479,7 +2534,7 @@ public class ObjectInputStream
|
||||
throw new InternalError();
|
||||
}
|
||||
clear();
|
||||
return (IOException) readObject0(false);
|
||||
return (IOException) readObject0(Object.class, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2601,7 +2656,7 @@ public class ObjectInputStream
|
||||
int numPrimFields = fields.length - objVals.length;
|
||||
for (int i = 0; i < objVals.length; i++) {
|
||||
objVals[i] =
|
||||
readObject0(fields[numPrimFields + i].isUnshared());
|
||||
readObject0(Object.class, fields[numPrimFields + i].isUnshared());
|
||||
objHandles[i] = passHandle;
|
||||
}
|
||||
passHandle = oldHandle;
|
||||
@ -4090,6 +4145,7 @@ public class ObjectInputStream
|
||||
|
||||
static {
|
||||
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::checkArray);
|
||||
SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.internal.access;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
/**
|
||||
* Interface to specify methods for accessing {@code ObjectInputStream}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface JavaObjectInputStreamReadString {
|
||||
String readString(ObjectInputStream ois) throws IOException;
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ public class SharedSecrets {
|
||||
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
|
||||
private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
|
||||
private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
|
||||
private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
|
||||
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
|
||||
private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
|
||||
private static JavaNetInetAddressAccess javaNetInetAddressAccess;
|
||||
@ -283,6 +284,17 @@ public class SharedSecrets {
|
||||
javaUtilResourceBundleAccess = access;
|
||||
}
|
||||
|
||||
public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
|
||||
if (javaObjectInputStreamReadString == null) {
|
||||
unsafe.ensureClassInitialized(ObjectInputStream.class);
|
||||
}
|
||||
return javaObjectInputStreamReadString;
|
||||
}
|
||||
|
||||
public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
|
||||
javaObjectInputStreamReadString = access;
|
||||
}
|
||||
|
||||
public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
|
||||
if (javaObjectInputStreamAccess == null) {
|
||||
unsafe.ensureClassInitialized(ObjectInputStream.class);
|
||||
|
@ -27,7 +27,9 @@
|
||||
package sun.rmi.registry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.rmi.transport.StreamRemoteCall;
|
||||
|
||||
/**
|
||||
@ -83,8 +85,9 @@ public final class RegistryImpl_Skel
|
||||
java.lang.String $param_String_1;
|
||||
java.rmi.Remote $param_Remote_2;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$param_String_1 = (java.lang.String) in.readObject();
|
||||
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
|
||||
$param_String_1 =
|
||||
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
|
||||
$param_Remote_2 = (java.rmi.Remote) in.readObject();
|
||||
} catch (ClassCastException | IOException | ClassNotFoundException e) {
|
||||
call.discardPendingRefs();
|
||||
@ -118,9 +121,10 @@ public final class RegistryImpl_Skel
|
||||
{
|
||||
java.lang.String $param_String_1;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$param_String_1 = (java.lang.String) in.readObject();
|
||||
} catch (ClassCastException | IOException | ClassNotFoundException e) {
|
||||
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
|
||||
$param_String_1 =
|
||||
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
|
||||
} catch (ClassCastException | IOException e) {
|
||||
call.discardPendingRefs();
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
|
||||
} finally {
|
||||
@ -144,8 +148,9 @@ public final class RegistryImpl_Skel
|
||||
java.lang.String $param_String_1;
|
||||
java.rmi.Remote $param_Remote_2;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$param_String_1 = (java.lang.String) in.readObject();
|
||||
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
|
||||
$param_String_1 =
|
||||
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
|
||||
$param_Remote_2 = (java.rmi.Remote) in.readObject();
|
||||
} catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
|
||||
call.discardPendingRefs();
|
||||
@ -169,9 +174,10 @@ public final class RegistryImpl_Skel
|
||||
|
||||
java.lang.String $param_String_1;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$param_String_1 = (java.lang.String) in.readObject();
|
||||
} catch (ClassCastException | IOException | ClassNotFoundException e) {
|
||||
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
|
||||
$param_String_1 =
|
||||
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
|
||||
} catch (ClassCastException | IOException e) {
|
||||
call.discardPendingRefs();
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
|
||||
} finally {
|
||||
|
@ -27,6 +27,7 @@ package sun.rmi.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.lang.reflect.Method;
|
||||
import java.rmi.MarshalException;
|
||||
@ -39,6 +40,8 @@ import java.rmi.server.RemoteObject;
|
||||
import java.rmi.server.RemoteRef;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.rmi.runtime.Log;
|
||||
import sun.rmi.transport.Connection;
|
||||
import sun.rmi.transport.LiveRef;
|
||||
@ -318,6 +321,8 @@ public class UnicastRef implements RemoteRef {
|
||||
} else {
|
||||
throw new Error("Unrecognized primitive type: " + type);
|
||||
}
|
||||
} else if (type == String.class && in instanceof ObjectInputStream) {
|
||||
return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in);
|
||||
} else {
|
||||
return in.readObject();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user