8268826: Cleanup Override in Context-Specific Deserialization Filters
Reviewed-by: dfuchs, bchristi
This commit is contained in:
parent
f791fdf23e
commit
6889a39a3f
src/java.base/share
test/jdk/java/io/Serializable/serialFilter
@ -45,6 +45,7 @@ import java.util.function.Predicate;
|
||||
import static java.io.ObjectInputFilter.Status.*;
|
||||
import static java.lang.System.Logger.Level.TRACE;
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
|
||||
/**
|
||||
* Filter classes, array lengths, and graph metrics during deserialization.
|
||||
@ -308,10 +309,12 @@ public interface ObjectInputFilter {
|
||||
* <li>Otherwise, return {@code otherStatus}.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Example, to create a filter that will allow any class loaded from the platform classloader.
|
||||
* Example, to create a filter that will allow any class loaded from the platform
|
||||
* or bootstrap classloaders.
|
||||
* <pre><code>
|
||||
* ObjectInputFilter f = allowFilter(cl -> cl.getClassLoader() == ClassLoader.getPlatformClassLoader()
|
||||
* || cl.getClassLoader() == null, Status.UNDECIDED);
|
||||
* ObjectInputFilter f
|
||||
* = allowFilter(cl -> cl.getClassLoader() == ClassLoader.getPlatformClassLoader() ||
|
||||
* cl.getClassLoader() == null, Status.UNDECIDED);
|
||||
* </code></pre>
|
||||
*
|
||||
* @param predicate a predicate to test a non-null Class
|
||||
@ -527,23 +530,17 @@ public interface ObjectInputFilter {
|
||||
* The syntax for the property value is the same as for the
|
||||
* {@link #createFilter(String) createFilter} method.
|
||||
*
|
||||
* <p> If only `jdk.serialFilter` is set and not `jdk.serialFilterFactory` the builtin
|
||||
* filter factory, compatible with previous versions, is set and can not be replaced,
|
||||
* see below to override the builtin filter factory.
|
||||
* <p>
|
||||
* If the Java virtual machine is started with the system property
|
||||
* {@systemProperty jdk.serialFilterFactory} or the {@link java.security.Security} property
|
||||
* of the same name, its value names the class to configure the JVM-wide deserialization
|
||||
* filter factory or the special value `OVERRIDE`.
|
||||
* filter factory.
|
||||
* If the system property is not defined, and the {@link java.security.Security} property
|
||||
* {@code jdk.serialFilterFactory} is defined then it is used to configure the filter factory.
|
||||
*
|
||||
* If the value is `OVERRIDE`, the filter factory can be set by the application before
|
||||
* the first deserialization using {@link Config#setSerialFilterFactory(BinaryOperator)};
|
||||
* If it remains unset, the filter factory is a builtin filter factory compatible
|
||||
* with previous versions.
|
||||
*
|
||||
* <p>If not `OVERRIDE`, the class must be public, must have a public zero-argument constructor, implement the
|
||||
* <p>The class must be public, must have a public zero-argument constructor, implement the
|
||||
* {@link BinaryOperator {@literal BinaryOperator<ObjectInputFilter>}} interface, provide its implementation and
|
||||
* be accessible via the {@linkplain ClassLoader#getSystemClassLoader() application class loader}.
|
||||
* If the filter factory constructor is not invoked successfully, an {@link ExceptionInInitializerError}
|
||||
@ -579,11 +576,6 @@ public interface ObjectInputFilter {
|
||||
*/
|
||||
private static final String SERIAL_FILTER_FACTORY_PROPNAME = "jdk.serialFilterFactory";
|
||||
|
||||
/**
|
||||
* The property name to enable tracing of filters.
|
||||
*/
|
||||
private static final String SERIAL_FILTER_TRACE_PROPNAME = "jdk.serialFilterTrace";
|
||||
|
||||
/**
|
||||
* Current static filter.
|
||||
*/
|
||||
@ -599,34 +591,30 @@ public interface ObjectInputFilter {
|
||||
* Boolean to indicate that the filter factory can not be set or replaced.
|
||||
* - an ObjectInputStream has already been created using the current filter factory
|
||||
* - has been set on the command line
|
||||
* - jdk.serialFilter is set and jdk.serialFilterFactory is unset, the builtin can not be replaced
|
||||
* @see Config#setSerialFilterFactory(BinaryOperator)
|
||||
*/
|
||||
private static final AtomicBoolean filterFactoryNoReplace = new AtomicBoolean();
|
||||
|
||||
/**
|
||||
* Debug: Logger
|
||||
* Debug and Trace Logger
|
||||
*/
|
||||
private static final System.Logger configLog;
|
||||
|
||||
/**
|
||||
* True when tracing of filters is enabled.
|
||||
*/
|
||||
private static final boolean traceFilters;
|
||||
|
||||
static {
|
||||
/*
|
||||
* Initialize the configuration containing the filter factory, static filter, and logger.
|
||||
* <ul>
|
||||
* <li>The logger is created.
|
||||
* <li>The property 'jdk.serialFilter" is read, either as a system property or a security property,
|
||||
* and if set, defines the configured static JVM-wide filter and is logged.
|
||||
* <li>The property jdk.serialFilterFactory is read, either as a system property or a security property,
|
||||
* and if set, defines the initial filter factory and is logged.
|
||||
* <li>The property jdk.serialFilterTrace, is read, and if set enables tracing of filters.
|
||||
* <li>If either property is defined or tracing is enabled, the logger is created.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
// Initialize the logger.
|
||||
configLog = System.getLogger("java.io.serialization");
|
||||
|
||||
// Get the values of the system properties, if they are defined
|
||||
String factoryClassName = StaticProperty.jdkSerialFilterFactory();
|
||||
if (factoryClassName == null) {
|
||||
@ -642,12 +630,6 @@ public interface ObjectInputFilter {
|
||||
Security.getProperty(SERIAL_FILTER_PROPNAME));
|
||||
}
|
||||
|
||||
traceFilters = GetBooleanAction.privilegedGetProperty(SERIAL_FILTER_TRACE_PROPNAME);
|
||||
|
||||
// Initialize the logger if either filter factory or filter property is set
|
||||
configLog = (filterString != null || factoryClassName != null || traceFilters)
|
||||
? System.getLogger("java.io.serialization") : null;
|
||||
|
||||
// Initialize the static filter if the jdk.serialFilter is present
|
||||
ObjectInputFilter filter = null;
|
||||
if (filterString != null) {
|
||||
@ -656,7 +638,7 @@ public interface ObjectInputFilter {
|
||||
try {
|
||||
filter = createFilter(filterString);
|
||||
} catch (RuntimeException re) {
|
||||
configLog.log(System.Logger.Level.ERROR,
|
||||
configLog.log(ERROR,
|
||||
"Error configuring filter: {0}", re);
|
||||
}
|
||||
}
|
||||
@ -664,45 +646,32 @@ public interface ObjectInputFilter {
|
||||
|
||||
// Initialize the filter factory if the jdk.serialFilterFactory is defined
|
||||
// otherwise use the builtin filter factory.
|
||||
if (factoryClassName == null || "OVERRIDE".equals(factoryClassName)) {
|
||||
if (factoryClassName == null) {
|
||||
serialFilterFactory = new BuiltinFilterFactory();
|
||||
if (serialFilter != null && factoryClassName == null) {
|
||||
// Ensure backward compatibility, unless factory is explicitly allowed to override
|
||||
// Do not allow factory to be overridden by Config.setSerialFilterFactory
|
||||
filterFactoryNoReplace.set(true);
|
||||
}
|
||||
|
||||
} else {
|
||||
configLog.log(DEBUG,
|
||||
"Creating deserialization filter factory for {0}", factoryClassName);
|
||||
try {
|
||||
// Load using the system class loader, the named class may be an application class.
|
||||
// The static initialization of the class or constructor may create a race
|
||||
// if either calls Config.setSerialFilterFactory; the command line configured
|
||||
// Class should not be overridden.
|
||||
// Cause Config.setSerialFilterFactory to throw {@link IllegalStateException}
|
||||
// if Config.setSerialFilterFactory is called as a side effect of the
|
||||
// static initialization of the class or constructor.
|
||||
filterFactoryNoReplace.set(true);
|
||||
|
||||
Class<?> factoryClass = Class.forName(factoryClassName, true,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
@SuppressWarnings("unchecked")
|
||||
BinaryOperator<ObjectInputFilter> f =
|
||||
BinaryOperator<ObjectInputFilter> factory =
|
||||
(BinaryOperator<ObjectInputFilter>)
|
||||
factoryClass.getConstructor().newInstance(new Object[0]);
|
||||
if (serialFilterFactory != null) {
|
||||
// Init cycle if Config.setSerialFilterFactory called from class initialization
|
||||
configLog.log(System.Logger.Level.ERROR,
|
||||
"FilterFactory provided on the command line can not be overridden");
|
||||
// Do not continue if configuration not initialized
|
||||
throw new ExceptionInInitializerError(
|
||||
"FilterFactory provided on the command line can not be overridden");
|
||||
}
|
||||
serialFilterFactory = f;
|
||||
filterFactoryNoReplace.set(true);
|
||||
configLog.log(DEBUG,
|
||||
"Creating deserialization filter factory for {0}", factoryClassName);
|
||||
serialFilterFactory = factory;
|
||||
} catch (RuntimeException | ClassNotFoundException | NoSuchMethodException |
|
||||
IllegalAccessException | InstantiationException | InvocationTargetException ex) {
|
||||
configLog.log(System.Logger.Level.ERROR,
|
||||
"Error configuring filter factory", ex);
|
||||
Throwable th = (ex instanceof InvocationTargetException ite) ? ite.getCause() : ex;
|
||||
configLog.log(ERROR,
|
||||
"Error configuring filter factory: {0}", (Object)th);
|
||||
// Do not continue if configuration not initialized
|
||||
throw new ExceptionInInitializerError(
|
||||
"FilterFactory configuration: jdk.serialFilterFactory: " + ex.getMessage());
|
||||
throw new ExceptionInInitializerError(th);
|
||||
}
|
||||
}
|
||||
// Setup shared secrets for RegistryImpl to use.
|
||||
@ -719,9 +688,7 @@ public interface ObjectInputFilter {
|
||||
* Logger for filter actions.
|
||||
*/
|
||||
private static void traceFilter(String msg, Object... args) {
|
||||
if (traceFilters && configLog != null) {
|
||||
configLog.log(TRACE, msg, args);
|
||||
}
|
||||
configLog.log(TRACE, msg, args);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -840,12 +807,14 @@ public interface ObjectInputFilter {
|
||||
if (sm != null) {
|
||||
sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION);
|
||||
}
|
||||
if (serialFilterFactory == null)
|
||||
throw new IllegalStateException("Serial filter factory initialization incomplete");
|
||||
if (filterFactoryNoReplace.getAndSet(true)) {
|
||||
throw new IllegalStateException("Cannot replace filter factory: " +
|
||||
serialFilterFactory.getClass().getName());
|
||||
final String msg = serialFilterFactory != null
|
||||
? serialFilterFactory.getClass().getName()
|
||||
: "initialization incomplete";
|
||||
throw new IllegalStateException("Cannot replace filter factory: " + msg);
|
||||
}
|
||||
configLog.log(DEBUG,
|
||||
"Setting deserialization filter factory to {0}", filterFactory.getClass().getName());
|
||||
serialFilterFactory = filterFactory;
|
||||
}
|
||||
|
||||
@ -1163,7 +1132,7 @@ public interface ObjectInputFilter {
|
||||
}
|
||||
if (!checkComponentType) {
|
||||
// As revised; do not check the component type for arrays
|
||||
traceFilter("Pattern array class: {0}, filter: {1}", clazz, this);
|
||||
traceFilter("Pattern filter array class: {0}, filter: {1}", clazz, this);
|
||||
return Status.UNDECIDED;
|
||||
}
|
||||
do {
|
||||
@ -1174,7 +1143,7 @@ public interface ObjectInputFilter {
|
||||
|
||||
if (clazz.isPrimitive()) {
|
||||
// Primitive types are undecided; let someone else decide
|
||||
traceFilter("Pattern UNDECIDED, primitive class: {0}, filter: {1}", clazz, this);
|
||||
traceFilter("Pattern filter UNDECIDED, primitive class: {0}, filter: {1}", clazz, this);
|
||||
return UNDECIDED;
|
||||
} else {
|
||||
// Find any filter that allowed or rejected the class
|
||||
@ -1184,7 +1153,7 @@ public interface ObjectInputFilter {
|
||||
.filter(p -> p != Status.UNDECIDED)
|
||||
.findFirst();
|
||||
Status s = status.orElse(Status.UNDECIDED);
|
||||
traceFilter("Pattern {0}, class: {1}, filter: {2}", s, cl, this);
|
||||
traceFilter("Pattern filter {0}, class: {1}, filter: {2}", s, cl, this);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@ -1283,18 +1252,18 @@ public interface ObjectInputFilter {
|
||||
public ObjectInputFilter.Status checkInput(FilterInfo info) {
|
||||
Status firstStatus = Objects.requireNonNull(first.checkInput(info), "status");
|
||||
if (REJECTED.equals(firstStatus)) {
|
||||
traceFilter("MergeFilter REJECT first: {0}, filter: {1}",
|
||||
traceFilter("MergeFilter REJECTED first: {0}, filter: {1}",
|
||||
firstStatus, this);
|
||||
return REJECTED;
|
||||
}
|
||||
Status secondStatus = Objects.requireNonNull(second.checkInput(info), "other status");
|
||||
if (REJECTED.equals(secondStatus)) {
|
||||
traceFilter("MergeFilter REJECT {0}, {1}, filter: {2}",
|
||||
traceFilter("MergeFilter REJECTED {0}, {1}, filter: {2}",
|
||||
firstStatus, secondStatus, this);
|
||||
return REJECTED;
|
||||
}
|
||||
if (ALLOWED.equals(firstStatus) || ALLOWED.equals(secondStatus)) {
|
||||
traceFilter("MergeFilter ALLOW either: {0}, {1}, filter: {2}",
|
||||
traceFilter("MergeFilter ALLOWED either: {0}, {1}, filter: {2}",
|
||||
firstStatus, secondStatus, this);
|
||||
return ALLOWED;
|
||||
}
|
||||
@ -1332,7 +1301,6 @@ public interface ObjectInputFilter {
|
||||
Class<?> clazz = info.serialClass();
|
||||
if (clazz == null || !UNDECIDED.equals(status))
|
||||
return status;
|
||||
status = REJECTED;
|
||||
// Find the base component type
|
||||
while (clazz.isArray()) {
|
||||
clazz = clazz.getComponentType();
|
||||
|
@ -194,7 +194,7 @@ public final class StaticProperty {
|
||||
* in this method. The caller of this method should take care to ensure
|
||||
* that the returned property is not made accessible to untrusted code.</strong>
|
||||
*
|
||||
* @return the {@code user.name} system property
|
||||
* @return the {@code jdk.serialFilterFactory} system property
|
||||
*/
|
||||
public static String jdkSerialFilterFactory() {
|
||||
return JDK_SERIAL_FILTER_FACTORY;
|
||||
|
@ -980,14 +980,12 @@ jdk.xml.dsig.secureValidationPolicy=\
|
||||
|
||||
|
||||
#
|
||||
# Deserialization system-wide filter factory
|
||||
# Deserialization JVM-wide filter factory
|
||||
#
|
||||
# A filter factory class name is used to configure the system-wide filter factory.
|
||||
# The filter factory value "OVERRIDE" in combination with setting "jdk.serialFilter"
|
||||
# indicates that the builtin filter factory can be overridden by the application.
|
||||
# A filter factory class name is used to configure the JVM-wide filter factory.
|
||||
# The class must be public, must have a public zero-argument constructor, implement the
|
||||
# java.util.stream.BinaryOperator<ObjectInputFilter> interface, provide its implementation and
|
||||
# be accessible via the application class loader.
|
||||
# java.util.function.BinaryOperator<java.io.ObjectInputFilter> interface, provide its
|
||||
# implementation and be accessible via the application class loader.
|
||||
# A builtin filter factory is used if no filter factory is defined.
|
||||
# See java.io.ObjectInputFilter.Config for more information.
|
||||
#
|
||||
@ -997,7 +995,7 @@ jdk.xml.dsig.secureValidationPolicy=\
|
||||
#jdk.serialFilterFactory=<classname>
|
||||
|
||||
#
|
||||
# Deserialization system-wide filter
|
||||
# Deserialization JVM-wide filter
|
||||
#
|
||||
# A filter, if configured, is used by the filter factory to provide the filter used by
|
||||
# java.io.ObjectInputStream during deserialization to check the contents of the stream.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, 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
|
||||
@ -54,6 +54,7 @@ public class FilterWithSecurityManagerTest {
|
||||
ObjectInputFilter filter;
|
||||
|
||||
@BeforeClass
|
||||
@SuppressWarnings("removal")
|
||||
public void setup() throws Exception {
|
||||
setSecurityManager = System.getSecurityManager() != null;
|
||||
Object toDeserialized = Long.MAX_VALUE;
|
||||
@ -65,7 +66,8 @@ public class FilterWithSecurityManagerTest {
|
||||
* Test that setting process-wide filter is checked by security manager.
|
||||
*/
|
||||
@Test
|
||||
public void testGlobalFilter() throws Exception {
|
||||
@SuppressWarnings("removal")
|
||||
public void testGlobalFilter() {
|
||||
ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
|
||||
|
||||
try {
|
||||
@ -88,6 +90,7 @@ public class FilterWithSecurityManagerTest {
|
||||
* Test that setting specific filter is checked by security manager.
|
||||
*/
|
||||
@Test(dependsOnMethods = { "testGlobalFilter" })
|
||||
@SuppressWarnings("removal")
|
||||
public void testSpecificFilter() throws Exception {
|
||||
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(bais)) {
|
||||
|
@ -142,6 +142,7 @@ public class GlobalFilterTest {
|
||||
* If there is no security manager then setting it should work.
|
||||
*/
|
||||
@Test()
|
||||
@SuppressWarnings("removal")
|
||||
static void setGlobalFilter() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
ObjectInputFilter filter = new SerialFilterTest.Validator();
|
||||
|
@ -47,8 +47,8 @@ import static java.io.ObjectInputFilter.Status.REJECTED;
|
||||
import static java.io.ObjectInputFilter.Status.UNDECIDED;
|
||||
|
||||
/* @test
|
||||
* @run testng/othervm -Djdk.serialFilterTrace=true SerialFactoryExample
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFactoryExample$FilterInThread -Djdk.serialFilterTrace=true SerialFactoryExample
|
||||
* @run testng/othervm SerialFactoryExample
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFactoryExample$FilterInThread SerialFactoryExample
|
||||
* @summary Test SerialFactoryExample
|
||||
*/
|
||||
|
||||
@ -599,19 +599,28 @@ public class SerialFactoryExample {
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the predicate to the class being deserialized, if the class is non-null
|
||||
* and if it returns {@code true}, return the requested status. Otherwise, return UNDECIDED.
|
||||
* Returns a filter that returns {@code ifTrueStatus} or the {@code ifFalseStatus}
|
||||
* based on the predicate of the {@code non-null} class and {@code UNDECIDED}
|
||||
* if the class is {@code null}.
|
||||
*
|
||||
* @param info the FilterInfo
|
||||
* @return the status of applying the predicate, otherwise {@code UNDECIDED}
|
||||
* @return a filter that returns {@code ifTrueStatus} or the {@code ifFalseStatus}
|
||||
* based on the predicate of the {@code non-null} class and {@code UNDECIDED}
|
||||
* if the class is {@code null}
|
||||
*/
|
||||
public ObjectInputFilter.Status checkInput(FilterInfo info) {
|
||||
Class<?> clazz = info.serialClass();
|
||||
return (clazz != null && predicate.test(clazz)) ? ifTrueStatus : ifFalseStatus;
|
||||
Status status = (clazz == null) ? UNDECIDED
|
||||
: (predicate.test(clazz)) ? ifTrueStatus : ifFalseStatus;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a String describing the filter, its predicate, and true and false status values.
|
||||
* @return a String describing the filter, its predicate, and true and false status values.
|
||||
*/
|
||||
public String toString() {
|
||||
return "predicate(" + predicate + ")";
|
||||
return "predicate(" + predicate + ", ifTrue: " + ifTrueStatus + ", ifFalse:" + ifFalseStatus+ ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.ObjectInputFilter;
|
||||
import java.io.ObjectInputFilter.Config;
|
||||
import java.util.function.BinaryOperator;
|
||||
|
||||
/* @test
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=ForcedError_NoSuchClass SerialFactoryFaults
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFactoryFaults$NoPublicConstructor SerialFactoryFaults
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFactoryFaults$ConstructorThrows SerialFactoryFaults
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFactoryFaults$FactorySetsFactory SerialFactoryFaults
|
||||
* @summary Check cases where the Filter Factory initialization from properties fails
|
||||
*/
|
||||
|
||||
@Test
|
||||
public class SerialFactoryFaults {
|
||||
|
||||
static {
|
||||
// Enable logging
|
||||
System.setProperty("java.util.logging.config.file",
|
||||
System.getProperty("test.src", ".") + "/logging.properties");
|
||||
}
|
||||
|
||||
public void initFaultTest() {
|
||||
String factoryName = System.getProperty("jdk.serialFilterFactory");
|
||||
ExceptionInInitializerError ex = Assert.expectThrows(ExceptionInInitializerError.class,
|
||||
() -> Config.getSerialFilterFactory());
|
||||
Throwable cause = ex.getCause();
|
||||
|
||||
if (factoryName.equals("ForcedError_NoSuchClass")) {
|
||||
Assert.assertEquals(cause.getClass(),
|
||||
ClassNotFoundException.class, "wrong exception");
|
||||
} else if (factoryName.equals("SerialFactoryFaults$NoPublicConstructor")) {
|
||||
Assert.assertEquals(cause.getClass(),
|
||||
NoSuchMethodException.class, "wrong exception");
|
||||
} else if (factoryName.equals("SerialFactoryFaults$ConstructorThrows")) {
|
||||
Assert.assertEquals(cause.getClass(),
|
||||
IllegalStateException.class, "wrong exception");
|
||||
} else if (factoryName.equals("SerialFactoryFaults$FactorySetsFactory")) {
|
||||
Assert.assertEquals(cause.getClass(),
|
||||
IllegalStateException.class, "wrong exception");
|
||||
Assert.assertEquals(cause.getMessage(),
|
||||
"Cannot replace filter factory: initialization incomplete",
|
||||
"wrong message");
|
||||
} else {
|
||||
Assert.fail("No test for filter factory: " + factoryName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test factory that does not have the required public no-arg constructor.
|
||||
*/
|
||||
public static final class NoPublicConstructor
|
||||
implements BinaryOperator<ObjectInputFilter> {
|
||||
private NoPublicConstructor() {
|
||||
}
|
||||
|
||||
public ObjectInputFilter apply(ObjectInputFilter curr, ObjectInputFilter next) {
|
||||
throw new RuntimeException("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test factory that has a constructor that throws a runtime exception.
|
||||
*/
|
||||
public static final class ConstructorThrows
|
||||
implements BinaryOperator<ObjectInputFilter> {
|
||||
public ConstructorThrows() {
|
||||
throw new IllegalStateException("SerialFactoryFaults$ConstructorThrows");
|
||||
}
|
||||
|
||||
public ObjectInputFilter apply(ObjectInputFilter curr, ObjectInputFilter next) {
|
||||
throw new RuntimeException("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test factory that has a constructor tries to set the filter factory.
|
||||
*/
|
||||
public static final class FactorySetsFactory
|
||||
implements BinaryOperator<ObjectInputFilter> {
|
||||
public FactorySetsFactory() {
|
||||
Config.setSerialFilterFactory(this);
|
||||
}
|
||||
|
||||
public ObjectInputFilter apply(ObjectInputFilter curr, ObjectInputFilter next) {
|
||||
throw new RuntimeException("NYI");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -43,17 +43,16 @@ import java.util.function.BinaryOperator;
|
||||
|
||||
/* @test
|
||||
* @build SerialFilterFactoryTest
|
||||
* @run testng/othervm SerialFilterFactoryTest
|
||||
* @run testng/othervm -Djdk.serialFilter="*" -Djdk.serialFilterFactory=OVERRIDE SerialFilterFactoryTest
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFilterFactoryTest$PropertyFilterFactory SerialFilterFactoryTest
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFilterFactoryTest$NotMyFilterFactory SerialFilterFactoryTest
|
||||
* @run testng/othervm SerialFilterFactoryTest
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFilterFactoryTest$PropertyFilterFactory
|
||||
* -Djava.util.logging.config.file=${test.src}/logging.properties SerialFilterFactoryTest
|
||||
* @run testng/othervm -Djdk.serialFilterFactory=SerialFilterFactoryTest$NotMyFilterFactory
|
||||
* -Djava.util.logging.config.file=${test.src}/logging.properties SerialFilterFactoryTest
|
||||
* @run testng/othervm/policy=security.policy
|
||||
* -Djava.security.properties=${test.src}/java.security-extra-factory
|
||||
* -Djava.security.debug=properties SerialFilterFactoryTest
|
||||
* @run testng/othervm/fail -Djdk.serialFilterFactory=ForcedError_NoSuchClass SerialFilterFactoryTest
|
||||
* @run testng/othervm/policy=security.policy SerialFilterFactoryTest
|
||||
* @run testng/othervm/policy=security.policy.without.globalFilter SerialFilterFactoryTest
|
||||
|
||||
*
|
||||
* @summary Test Context-specific Deserialization Filters
|
||||
*/
|
||||
@ -121,6 +120,7 @@ public class SerialFilterFactoryTest {
|
||||
/**
|
||||
* Returns true if serialFilter actions are ok, either no SM or SM has serialFilter Permission
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
private static boolean hasFilterPerm() {
|
||||
boolean hasSerialPerm = true;
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
@ -163,6 +163,7 @@ public class SerialFilterFactoryTest {
|
||||
* Try to set it again, the second should throw.
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("removal")
|
||||
void testSecondSetShouldThrow() {
|
||||
if (System.getSecurityManager() != null) {
|
||||
// Skip test when running with SM
|
||||
@ -198,6 +199,7 @@ public class SerialFilterFactoryTest {
|
||||
* @throws ClassNotFoundException for class not found (should not occur)
|
||||
*/
|
||||
@Test(dataProvider="FilterCases")
|
||||
@SuppressWarnings("removal")
|
||||
void testCase(MyFilterFactory dynFilterFactory, Validator dynFilter, Validator streamFilter)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
@ -253,7 +255,7 @@ public class SerialFilterFactoryTest {
|
||||
// Test that if the property jdk-serialFilterFactory is set, then initial factory has the same classname
|
||||
@Test
|
||||
void testPropertyFilterFactory() {
|
||||
if (jdkSerialFilterFactoryProp != null && !jdkSerialFilterFactoryProp.equals("OVERRIDE")) {
|
||||
if (jdkSerialFilterFactoryProp != null) {
|
||||
Assert.assertEquals(jdkSerialFilterFactory.getClass().getName(), jdkSerialFilterFactoryProp,
|
||||
"jdk.serialFilterFactory property classname mismatch");
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ import static java.io.ObjectInputFilter.Status.REJECTED;
|
||||
import static java.io.ObjectInputFilter.Status.UNDECIDED;
|
||||
|
||||
/* @test
|
||||
* @run testng/othervm -Djdk.serialFilterTrace=true SerialFilterFunctionTest
|
||||
* @run testng/othervm -Djava.util.logging.config.file=${test.src}/logging.properties
|
||||
* SerialFilterFunctionTest
|
||||
* @summary ObjectInputFilter.Config Function Tests
|
||||
*/
|
||||
@Test
|
||||
|
@ -53,8 +53,9 @@ import org.testng.annotations.DataProvider;
|
||||
/* @test
|
||||
* @bug 8234836
|
||||
* @build SerialFilterTest
|
||||
* @run testng/othervm -Djdk.serialFilterTrace=true SerialFilterTest
|
||||
* @run testng/othervm -Djdk.serialSetFilterAfterRead=true -Djdk.serialFilterTrace=true SerialFilterTest
|
||||
* @run testng/othervm -Djava.util.logging.config.file=${test.src}/logging.properties
|
||||
* SerialFilterTest
|
||||
* @run testng/othervm -Djdk.serialSetFilterAfterRead=true SerialFilterTest
|
||||
*
|
||||
* @summary Test ObjectInputFilters using Builtin Filter Factory
|
||||
*/
|
||||
|
@ -1,2 +1,2 @@
|
||||
# disabled till JDK-8219408 is fixed
|
||||
allowSmartActionArgs=false
|
||||
# Allow substitution of ${test.src}
|
||||
allowSmartActionArgs=true
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Deserialization Input Filter Factory
|
||||
# See conf/security/java.security for pattern synatx
|
||||
# See conf/security/java.security for pattern syntax
|
||||
#
|
||||
jdk.serialFilterFactory=SerialFilterFactoryTest$PropertyFilterFactory
|
||||
|
@ -0,0 +1,10 @@
|
||||
############################################################
|
||||
# Enable logging of all serialization levels to the console
|
||||
############################################################
|
||||
|
||||
handlers= java.util.logging.ConsoleHandler
|
||||
|
||||
java.util.logging.ConsoleHandler.level = ALL
|
||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||
java.util.logging.SimpleFormatter.format=%3$s %4$s %5$s %6$s%n
|
||||
java.io.serialization.level = ALL
|
Loading…
x
Reference in New Issue
Block a user