From a26823386c5c9d54507bf8b770b2ce06ea2e7dc5 Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Mon, 4 Dec 2023 21:48:22 +1100 Subject: [PATCH] WW-5343 Add integration tests for ConfigurationProvider populating ProviderAllowlist --- .../XmlDocConfigurationProvider.java | 6 +- ...onfigurationProviderOgnlAllowlistTest.java | 96 +++++++++++++++++++ .../providers/xwork-test-allowlist-2.xml | 41 ++++++++ .../config/providers/xwork-test-allowlist.xml | 48 ++++++++++ 4 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java create mode 100644 core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist-2.xml create mode 100644 core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist.xml diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java index ccddb9efc..bae553789 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlDocConfigurationProvider.java @@ -66,7 +66,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; -import java.util.stream.Stream; import static com.opensymphony.xwork2.util.TextParseUtil.commaDelimitedStringToSet; import static java.lang.Boolean.parseBoolean; @@ -149,9 +148,8 @@ public abstract class XmlDocConfigurationProvider implements ConfigurationProvid protected Class allowAndLoadClass(String className) throws ClassNotFoundException { Class clazz = loadClass(className); allowlistClasses.add(clazz); - List> superClasses = ClassUtils.getAllSuperclasses(clazz); - List> interfaces = ClassUtils.getAllInterfaces(clazz); - Stream.concat(superClasses.stream(), interfaces.stream()).forEach(allowlistClasses::add); + allowlistClasses.addAll(ClassUtils.getAllSuperclasses(clazz)); + allowlistClasses.addAll(ClassUtils.getAllInterfaces(clazz)); return clazz; } diff --git a/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java b/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java new file mode 100644 index 000000000..4870ba8fc --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java @@ -0,0 +1,96 @@ +package com.opensymphony.xwork2.config.providers; + +import com.opensymphony.xwork2.XWorkJUnit4TestCase; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import org.apache.struts2.config.StrutsXmlConfigurationProvider; +import org.apache.struts2.ognl.ProviderAllowlist; +import org.junit.Before; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ConfigurationProviderOgnlAllowlistTest extends XWorkJUnit4TestCase { + + private final ConfigurationProvider testXml1 = new StrutsXmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowlist.xml"); + private final ConfigurationProvider testXml2 = new StrutsXmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowlist-2.xml"); + private ProviderAllowlist providerAllowlist; + + @Before + public void setUp() throws Exception { + loadConfigurationProviders(testXml1, testXml2); + providerAllowlist = container.getInstance(ProviderAllowlist.class); + } + + @Test + public void allowlist() throws Exception { + loadConfigurationProviders(testXml1, testXml2); + providerAllowlist = container.getInstance(ProviderAllowlist.class); + + assertThat(providerAllowlist.getProviderAllowlist()).containsExactlyInAnyOrder( + Class.forName("com.opensymphony.xwork2.interceptor.ValidationAware"), + Class.forName("com.opensymphony.xwork2.LocaleProvider"), + Class.forName("java.io.Serializable"), + Class.forName("com.opensymphony.xwork2.mock.MockResult"), + Class.forName("com.opensymphony.xwork2.interceptor.ConditionalInterceptor"), + Class.forName("com.opensymphony.xwork2.ActionSupport"), + Class.forName("com.opensymphony.xwork2.ActionChainResult"), + Class.forName("com.opensymphony.xwork2.TextProvider"), + Class.forName("org.apache.struts2.interceptor.NoOpInterceptor"), + Class.forName("com.opensymphony.xwork2.interceptor.Interceptor"), + Class.forName("java.lang.Object"), + Class.forName("com.opensymphony.xwork2.Validateable"), + Class.forName("com.opensymphony.xwork2.mock.MockInterceptor"), + Class.forName("com.opensymphony.xwork2.Action"), + Class.forName("com.opensymphony.xwork2.interceptor.AbstractInterceptor"), + Class.forName("com.opensymphony.xwork2.Result"), + Class.forName("com.opensymphony.xwork2.SimpleAction") + ); + } + + @Test + public void allowlist_1only() throws Exception { + loadConfigurationProviders(testXml1); + providerAllowlist = container.getInstance(ProviderAllowlist.class); + + assertThat(providerAllowlist.getProviderAllowlist()).containsExactlyInAnyOrder( + Class.forName("com.opensymphony.xwork2.interceptor.ValidationAware"), + Class.forName("com.opensymphony.xwork2.LocaleProvider"), + Class.forName("java.io.Serializable"), + Class.forName("com.opensymphony.xwork2.mock.MockResult"), + Class.forName("com.opensymphony.xwork2.interceptor.ConditionalInterceptor"), + Class.forName("com.opensymphony.xwork2.ActionSupport"), + Class.forName("com.opensymphony.xwork2.TextProvider"), + Class.forName("com.opensymphony.xwork2.interceptor.Interceptor"), + Class.forName("java.lang.Object"), + Class.forName("com.opensymphony.xwork2.Validateable"), + Class.forName("com.opensymphony.xwork2.mock.MockInterceptor"), + Class.forName("com.opensymphony.xwork2.Action"), + Class.forName("com.opensymphony.xwork2.interceptor.AbstractInterceptor"), + Class.forName("com.opensymphony.xwork2.Result"), + Class.forName("com.opensymphony.xwork2.SimpleAction") + ); + } + + @Test + public void allowlist_2only() throws Exception { + loadConfigurationProviders(testXml2); + providerAllowlist = container.getInstance(ProviderAllowlist.class); + + assertThat(providerAllowlist.getProviderAllowlist()).containsExactlyInAnyOrder( + Class.forName("com.opensymphony.xwork2.interceptor.ValidationAware"), + Class.forName("com.opensymphony.xwork2.LocaleProvider"), + Class.forName("java.io.Serializable"), + Class.forName("com.opensymphony.xwork2.interceptor.ConditionalInterceptor"), + Class.forName("com.opensymphony.xwork2.ActionSupport"), + Class.forName("com.opensymphony.xwork2.ActionChainResult"), + Class.forName("com.opensymphony.xwork2.TextProvider"), + Class.forName("org.apache.struts2.interceptor.NoOpInterceptor"), + Class.forName("com.opensymphony.xwork2.interceptor.Interceptor"), + Class.forName("java.lang.Object"), + Class.forName("com.opensymphony.xwork2.Validateable"), + Class.forName("com.opensymphony.xwork2.Action"), + Class.forName("com.opensymphony.xwork2.interceptor.AbstractInterceptor"), + Class.forName("com.opensymphony.xwork2.Result") + ); + } +} diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist-2.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist-2.xml new file mode 100644 index 000000000..f5e9b184d --- /dev/null +++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist-2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist.xml new file mode 100644 index 000000000..1de061efd --- /dev/null +++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowlist.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + fooDefault + + + + + + + + + 18 + 24 + + + + +