aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbae <unknown>2019-11-04 13:33:27 -0800
committerbell-sw <liberica@bell-sw.com>2020-01-19 09:13:26 +0300
commitd8a068b30e7a96280f2c1df7889c7a65edd6ae26 (patch)
treefd3b9c35a88ab9d353bb0fc502cfcf852cad0e3c
parent4e6dc12e658193762c46569cec8eae2003e8d009 (diff)
downloadjdk8u_jdk-d8a068b30e7a96280f2c1df7889c7a65edd6ae26.tar.gz
8232419: Improve Registry registration
Reviewed-by: andrew
-rw-r--r--src/share/classes/java/io/ObjectInputStream.java76
-rw-r--r--src/share/classes/sun/misc/JavaObjectInputStreamReadString.java38
-rw-r--r--src/share/classes/sun/misc/SharedSecrets.java13
-rw-r--r--src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java26
-rw-r--r--src/share/classes/sun/rmi/server/UnicastRef.java5
5 files changed, 137 insertions, 21 deletions
diff --git a/src/share/classes/java/io/ObjectInputStream.java b/src/share/classes/java/io/ObjectInputStream.java
index cb84d0137d..b16d53b4bc 100644
--- a/src/share/classes/java/io/ObjectInputStream.java
+++ b/src/share/classes/java/io/ObjectInputStream.java
@@ -419,16 +419,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) {
@@ -518,7 +552,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) {
@@ -1517,8 +1551,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();
@@ -1550,13 +1586,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:
@@ -1564,15 +1607,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);
@@ -1947,7 +2002,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) {
@@ -1972,7 +2027,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);
}
}
@@ -2250,7 +2305,7 @@ public class ObjectInputStream
return;
default:
- readObject0(false);
+ readObject0(Object.class, false);
break;
}
}
@@ -2284,7 +2339,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);
}
@@ -2305,7 +2360,7 @@ public class ObjectInputStream
throw new InternalError();
}
clear();
- return (IOException) readObject0(false);
+ return (IOException) readObject0(Object.class, false);
}
/**
@@ -2449,7 +2504,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;
@@ -3926,5 +3981,6 @@ public class ObjectInputStream
}
static {
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+ SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
}
}
diff --git a/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java b/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java
new file mode 100644
index 0000000000..ed7a6c3e66
--- /dev/null
+++ b/src/share/classes/sun/misc/JavaObjectInputStreamReadString.java
@@ -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 sun.misc;
+
+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;
+}
+
diff --git a/src/share/classes/sun/misc/SharedSecrets.java b/src/share/classes/sun/misc/SharedSecrets.java
index cc3fc642af..d046e4b194 100644
--- a/src/share/classes/sun/misc/SharedSecrets.java
+++ b/src/share/classes/sun/misc/SharedSecrets.java
@@ -59,6 +59,7 @@ public class SharedSecrets {
private static JavaAWTAccess javaAWTAccess;
private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
+ private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
@@ -202,8 +203,18 @@ public class SharedSecrets {
return javaAWTAccess;
}
+ 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() {
+ public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
if (javaObjectInputStreamAccess == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
}
diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java b/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
index c0a06f1f01..2d9102f1a6 100644
--- a/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
@@ -27,7 +27,9 @@
package sun.rmi.registry;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import sun.misc.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 {
diff --git a/src/share/classes/sun/rmi/server/UnicastRef.java b/src/share/classes/sun/rmi/server/UnicastRef.java
index 831c41bd9e..b01a2b87ec 100644
--- a/src/share/classes/sun/rmi/server/UnicastRef.java
+++ b/src/share/classes/sun/rmi/server/UnicastRef.java
@@ -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;
@@ -38,6 +39,8 @@ import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef;
import java.security.AccessController;
+
+import sun.misc.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();
}