forked from pool/java-1_8_0-openjdk
80 lines
3.4 KiB
Diff
80 lines
3.4 KiB
Diff
--- icedtea-3.8.0/openjdk/jdk/src/share/classes/java/io/ObjectStreamClass.java 2018-09-18 09:59:41.495643758 +0200
|
|
+++ icedtea-3.8.0/openjdk/jdk/src/share/classes/java/io/ObjectStreamClass.java 2018-09-18 09:59:57.923733188 +0200
|
|
@@ -86,6 +86,18 @@
|
|
private static final ObjectStreamField[] serialPersistentFields =
|
|
NO_FIELDS;
|
|
|
|
+ /** true if deserialization constructor checking is disabled */
|
|
+ private static boolean disableSerialConstructorChecks =
|
|
+ AccessController.doPrivileged(
|
|
+ new PrivilegedAction<Boolean>() {
|
|
+ public Boolean run() {
|
|
+ String prop = "jdk.disableSerialConstructorChecks";
|
|
+ return "true".equals(System.getProperty(prop))
|
|
+ ? Boolean.TRUE : Boolean.FALSE;
|
|
+ }
|
|
+ }
|
|
+ ).booleanValue();
|
|
+
|
|
/** reflection factory for obtaining serialization constructors */
|
|
private static final ReflectionFactory reflFactory =
|
|
AccessController.doPrivileged(
|
|
@@ -1497,6 +1509,46 @@
|
|
}
|
|
|
|
/**
|
|
+ * Given a class, determines whether its superclass has
|
|
+ * any constructors that are accessible from the class.
|
|
+ * This is a special purpose method intended to do access
|
|
+ * checking for a serializable class and its superclasses
|
|
+ * up to, but not including, the first non-serializable
|
|
+ * superclass. This also implies that the superclass is
|
|
+ * always non-null, because a serializable class must be a
|
|
+ * class (not an interface) and Object is not serializable.
|
|
+ *
|
|
+ * @param cl the class from which access is checked
|
|
+ * @return whether the superclass has a constructor accessible from cl
|
|
+ */
|
|
+ private static boolean superHasAccessibleConstructor(Class<?> cl) {
|
|
+ Class<?> superCl = cl.getSuperclass();
|
|
+ assert Serializable.class.isAssignableFrom(cl);
|
|
+ assert superCl != null;
|
|
+ if (packageEquals(cl, superCl)) {
|
|
+ // accessible if any non-private constructor is found
|
|
+ for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
|
|
+ if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ } else {
|
|
+ // accessible if the parent is public and any constructor
|
|
+ // is protected or public
|
|
+ if ((superCl.getModifiers() & Modifier.PUBLIC) == 0) {
|
|
+ return false;
|
|
+ }
|
|
+ for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
|
|
+ if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
* Returns subclass-accessible no-arg constructor of first non-serializable
|
|
* superclass, or null if none found. Access checks are disabled on the
|
|
* returned constructor (if any).
|
|
@@ -1504,7 +1556,9 @@
|
|
private static Constructor<?> getSerializableConstructor(Class<?> cl) {
|
|
Class<?> initCl = cl;
|
|
while (Serializable.class.isAssignableFrom(initCl)) {
|
|
- if ((initCl = initCl.getSuperclass()) == null) {
|
|
+ Class<?> prev = initCl;
|
|
+ if ((initCl = initCl.getSuperclass()) == null ||
|
|
+ (!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
|
|
return null;
|
|
}
|
|
}
|