> classes = findActions();
+ buildConfiguration(classes);
}
protected ClassLoaderInterface getClassLoaderInterface() {
@@ -765,7 +780,10 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
} else if (actionAnnotation != null)
createActionConfig(defaultPackageConfig, actionClass, defaultActionName, methodName, actionAnnotation, allowedMethods);
}
+
+ allowlistClasses.addAll(ConfigurationUtil.getAllClassTypes(actionClass));
}
+ providerAllowlist.registerAllowlist(this, allowlistClasses);
buildIndexActions(packageConfigs);
@@ -1153,10 +1171,13 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
}
}
+ @Override
public void destroy() {
loadedFileUrls.clear();
+ providerAllowlist.clearAllowlist(this);
}
+ @Override
public boolean needsReload() {
if (devMode && reload) {
for (String url : loadedFileUrls) {
diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
index c44ca335a..1643ce7ae 100644
--- a/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
+++ b/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
@@ -18,9 +18,21 @@
*/
package org.apache.struts2.convention;
-import com.opensymphony.xwork2.*;
+import com.opensymphony.xwork2.ActionChainResult;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.FileManager;
+import com.opensymphony.xwork2.FileManagerFactory;
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.entities.*;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
+import com.opensymphony.xwork2.config.entities.InterceptorConfig;
+import com.opensymphony.xwork2.config.entities.InterceptorMapping;
+import com.opensymphony.xwork2.config.entities.InterceptorStackConfig;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.config.entities.ResultConfig;
+import com.opensymphony.xwork2.config.entities.ResultTypeConfig;
import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
import com.opensymphony.xwork2.factory.DefaultInterceptorFactory;
import com.opensymphony.xwork2.factory.DefaultResultFactory;
@@ -32,12 +44,20 @@ import com.opensymphony.xwork2.util.fs.DefaultFileManager;
import com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory;
import com.opensymphony.xwork2.util.reflection.ReflectionException;
import junit.framework.TestCase;
-
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.actions.DefaultResultPathAction;
import org.apache.struts2.convention.actions.NoAnnotationAction;
import org.apache.struts2.convention.actions.Skip;
-import org.apache.struts2.convention.actions.action.*;
+import org.apache.struts2.convention.actions.action.ActionNameAction;
+import org.apache.struts2.convention.actions.action.ActionNamesAction;
+import org.apache.struts2.convention.actions.action.ClassLevelAnnotationAction;
+import org.apache.struts2.convention.actions.action.ClassLevelAnnotationDefaultMethodAction;
+import org.apache.struts2.convention.actions.action.ClassLevelAnnotationsAction;
+import org.apache.struts2.convention.actions.action.ClassLevelAnnotationsDefaultMethodAction;
+import org.apache.struts2.convention.actions.action.ClassNameAction;
+import org.apache.struts2.convention.actions.action.SingleActionNameAction;
+import org.apache.struts2.convention.actions.action.TestAction;
+import org.apache.struts2.convention.actions.action.TestExtends;
import org.apache.struts2.convention.actions.allowedmethods.ClassLevelAllowedMethodsAction;
import org.apache.struts2.convention.actions.allowedmethods.PackageLevelAllowedMethodsAction;
import org.apache.struts2.convention.actions.allowedmethods.sub.PackageLevelAllowedMethodsChildAction;
@@ -61,7 +81,15 @@ import org.apache.struts2.convention.actions.parentpackage.ClassLevelParentPacka
import org.apache.struts2.convention.actions.parentpackage.PackageLevelParentPackageAction;
import org.apache.struts2.convention.actions.parentpackage.sub.ClassLevelParentPackageChildAction;
import org.apache.struts2.convention.actions.parentpackage.sub.PackageLevelParentPackageChildAction;
-import org.apache.struts2.convention.actions.result.*;
+import org.apache.struts2.convention.actions.result.ActionLevelResultAction;
+import org.apache.struts2.convention.actions.result.ActionLevelResultsAction;
+import org.apache.struts2.convention.actions.result.ActionLevelResultsNamesAction;
+import org.apache.struts2.convention.actions.result.ClassLevelResultAction;
+import org.apache.struts2.convention.actions.result.ClassLevelResultsAction;
+import org.apache.struts2.convention.actions.result.GlobalResultAction;
+import org.apache.struts2.convention.actions.result.GlobalResultOverrideAction;
+import org.apache.struts2.convention.actions.result.InheritedResultExtends;
+import org.apache.struts2.convention.actions.result.OverrideResultAction;
import org.apache.struts2.convention.actions.resultpath.ClassLevelResultPathAction;
import org.apache.struts2.convention.actions.resultpath.PackageLevelResultPathAction;
import org.apache.struts2.convention.actions.skip.Index;
@@ -69,15 +97,24 @@ import org.apache.struts2.convention.actions.transactions.TransNameAction;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.dontfind.DontFindMeAction;
+import org.apache.struts2.ognl.ProviderAllowlist;
import org.apache.struts2.result.ServletDispatcherResult;
import org.easymock.EasyMock;
import javax.servlet.ServletContext;
import java.net.MalformedURLException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import static org.apache.struts2.convention.ReflectionTools.getAnnotation;
-import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.checkOrder;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.verify;
/**
*
@@ -388,6 +425,7 @@ public class PackageBasedActionConfigBuilderTest extends TestCase {
fileManagerFactory.setFileManager(new DefaultFileManager());
builder.setFileManagerFactory(fileManagerFactory);
builder.setPackageLocatorsBase("org.apache.struts2.convention.actions");
+ builder.setProviderAllowlist(new ProviderAllowlist());
builder.buildActionConfigs();
verify(resultMapBuilder);
From 27e4d0d47aded060f12fd2121273d6a4eb69c206 Mon Sep 17 00:00:00 2001
From: Kusal Kithul-Godage
Date: Sat, 13 Jul 2024 23:25:31 +1000
Subject: [PATCH 08/12] WW-5440 Fix inconsistent indenting
---
.../showcase/action/AbstractCRUDAction.java | 92 +++++++++----------
1 file changed, 46 insertions(+), 46 deletions(-)
diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java
index 2880f3658..e5204a1fa 100644
--- a/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java
+++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java
@@ -34,62 +34,62 @@ import java.util.Collection;
public abstract class AbstractCRUDAction extends ActionSupport {
- private static final Logger log = LogManager.getLogger(AbstractCRUDAction.class);
+ private static final Logger log = LogManager.getLogger(AbstractCRUDAction.class);
- private Collection availableItems;
- private String[] toDelete;
+ private Collection availableItems;
+ private String[] toDelete;
- protected abstract Dao getDao();
+ protected abstract Dao getDao();
- public Collection getAvailableItems() {
- return availableItems;
- }
+ public Collection getAvailableItems() {
+ return availableItems;
+ }
- public String[] getToDelete() {
- return toDelete;
- }
+ public String[] getToDelete() {
+ return toDelete;
+ }
- @StrutsParameter
- public void setToDelete(String[] toDelete) {
- this.toDelete = toDelete;
- }
+ @StrutsParameter
+ public void setToDelete(String[] toDelete) {
+ this.toDelete = toDelete;
+ }
- public String list() throws Exception {
- this.availableItems = getDao().findAll();
- if (log.isDebugEnabled()) {
- log.debug("AbstractCRUDAction - [list]: " + (availableItems != null ? "" + availableItems.size() : "no") + " items found");
- }
- return execute();
- }
+ public String list() throws Exception {
+ this.availableItems = getDao().findAll();
+ if (log.isDebugEnabled()) {
+ log.debug("AbstractCRUDAction - [list]: " + (availableItems != null ? "" + availableItems.size() : "no") + " items found");
+ }
+ return execute();
+ }
- public String delete() throws Exception {
- if (toDelete != null) {
- int count = 0;
+ public String delete() throws Exception {
+ if (toDelete != null) {
+ int count = 0;
for (String s : toDelete) {
count = count + getDao().delete(s);
}
- if (log.isDebugEnabled()) {
+ if (log.isDebugEnabled()) {
log.debug("AbstractCRUDAction - [delete]: {} items deleted.", count);
- }
- }
- return SUCCESS;
- }
+ }
+ }
+ return SUCCESS;
+ }
- /**
- * Utility method for fetching already persistent object from storage for usage in params-prepare-params cycle.
- *
- * @param tryId The id to try to get persistent object for
- * @param tryObject The object, induced by first params invocation, possibly containing id to try to get persistent
- * object for
- * @return The persistent object, if found. null otherwise.
- */
- protected IdEntity fetch(Serializable tryId, IdEntity tryObject) {
- IdEntity result = null;
- if (tryId != null) {
- result = getDao().get(tryId);
- } else if (tryObject != null) {
- result = getDao().get(tryObject.getId());
- }
- return result;
- }
+ /**
+ * Utility method for fetching already persistent object from storage for usage in params-prepare-params cycle.
+ *
+ * @param tryId The id to try to get persistent object for
+ * @param tryObject The object, induced by first params invocation, possibly containing id to try to get persistent
+ * object for
+ * @return The persistent object, if found. null otherwise.
+ */
+ protected IdEntity fetch(Serializable tryId, IdEntity tryObject) {
+ IdEntity result = null;
+ if (tryId != null) {
+ result = getDao().get(tryId);
+ } else if (tryObject != null) {
+ result = getDao().get(tryObject.getId());
+ }
+ return result;
+ }
}
From b7b5bff13afc1a5b8dd818d0fbe8b9f64e14e62c Mon Sep 17 00:00:00 2001
From: Kusal Kithul-Godage
Date: Sat, 13 Jul 2024 23:59:16 +1000
Subject: [PATCH 09/12] WW-5442 Enforce allowlist for OgnlReflectionProvider
---
.../providers/XmlDocConfigurationProvider.java | 12 ++++++------
.../java/com/opensymphony/xwork2/ognl/OgnlUtil.java | 11 +----------
2 files changed, 7 insertions(+), 16 deletions(-)
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 6de202460..5c1d1f395 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
@@ -109,6 +109,11 @@ public abstract class XmlDocConfigurationProvider implements ConfigurationProvid
this.valueSubstitutor = valueSubstitutor;
}
+ @Inject
+ public void setProviderAllowlist(ProviderAllowlist providerAllowlist) {
+ this.providerAllowlist = providerAllowlist;
+ }
+
public XmlDocConfigurationProvider(Document... documents) {
this.documents = Arrays.asList(documents);
}
@@ -135,11 +140,6 @@ public abstract class XmlDocConfigurationProvider implements ConfigurationProvid
this.configuration = configuration;
}
- private void registerAllowlist() {
- providerAllowlist = configuration.getContainer().getInstance(ProviderAllowlist.class);
- providerAllowlist.registerAllowlist(this, allowlistClasses);
- }
-
@Override
public void destroy() {
if (providerAllowlist != null) {
@@ -152,6 +152,7 @@ public abstract class XmlDocConfigurationProvider implements ConfigurationProvid
allowlistClasses.add(clazz);
allowlistClasses.addAll(ClassUtils.getAllSuperclasses(clazz));
allowlistClasses.addAll(ClassUtils.getAllInterfaces(clazz));
+ providerAllowlist.registerAllowlist(this, allowlistClasses);
return clazz;
}
@@ -333,7 +334,6 @@ public abstract class XmlDocConfigurationProvider implements ConfigurationProvid
}
declaredPackages.clear();
- registerAllowlist();
configuration = null;
}
diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
index 78cada96d..52475b8d5 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java
@@ -859,11 +859,6 @@ public class OgnlUtil {
return createDefaultContext(root, null);
}
- /**
- * Note that the allowlist capability is not enforced by the {@link OgnlContext} returned by this method. Currently,
- * this context is only leveraged by some public methods on {@link OgnlUtil} which are called by
- * {@link OgnlReflectionProvider}.
- */
protected Map createDefaultContext(Object root, ClassResolver resolver) {
if (resolver == null) {
resolver = container.getInstance(RootAccessor.class);
@@ -871,11 +866,7 @@ public class OgnlUtil {
throw new IllegalStateException("Cannot find ClassResolver");
}
}
-
- SecurityMemberAccess memberAccess = container.getInstance(SecurityMemberAccess.class);
- memberAccess.useEnforceAllowlistEnabled(Boolean.FALSE.toString());
-
- return Ognl.createDefaultContext(root, memberAccess, resolver, defaultConverter);
+ return Ognl.createDefaultContext(root, container.getInstance(SecurityMemberAccess.class), resolver, defaultConverter);
}
@FunctionalInterface
From 5372aff1ddeeab46c05e77686e3eed610512a5c6 Mon Sep 17 00:00:00 2001
From: Kusal Kithul-Godage
Date: Sun, 14 Jul 2024 14:16:37 +1000
Subject: [PATCH 10/12] WW-5443 Bump Spring dependencies to 5.3.37
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 854f75632..e53b0cbfb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,7 +114,7 @@
2.23.1
3.3.5
2.0.13
- 5.3.31
+ 5.3.37
3.0.8
1.0.7
3.2.5
From 1f46802ba2553397f499532f803324359fb5a334 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 15 Jul 2024 01:14:23 +0000
Subject: [PATCH 11/12] Bump jackson.version from 2.17.1 to 2.17.2
Bumps `jackson.version` from 2.17.1 to 2.17.2.
Updates `com.fasterxml.jackson.core:jackson-core` from 2.17.1 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.17.1...jackson-core-2.17.2)
Updates `com.fasterxml.jackson.core:jackson-databind` from 2.17.1 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson/commits)
Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-xml` from 2.17.1 to 2.17.2
- [Commits](https://github.com/FasterXML/jackson-dataformat-xml/compare/jackson-dataformat-xml-2.17.1...jackson-dataformat-xml-2.17.2)
---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-core
dependency-type: direct:production
update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.core:jackson-databind
dependency-type: direct:production
update-type: version-update:semver-patch
- dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-xml
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index e53b0cbfb..b918d3121 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,7 +110,7 @@
9.7
- 2.17.1
+ 2.17.2
2.23.1
3.3.5
2.0.13
From 6d0fc2aa28ae92593f64139021ab9680ad49d4c7 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 15 Jul 2024 01:14:29 +0000
Subject: [PATCH 12/12] Bump maven-surefire-plugin.version from 3.2.5 to 3.3.1
Bumps `maven-surefire-plugin.version` from 3.2.5 to 3.3.1.
Updates `org.apache.maven.surefire:surefire-junit47` from 3.2.5 to 3.3.1
Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.2.5 to 3.3.1
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.5...surefire-3.3.1)
---
updated-dependencies:
- dependency-name: org.apache.maven.surefire:surefire-junit47
dependency-type: direct:production
update-type: version-update:semver-minor
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index e53b0cbfb..71a452859 100644
--- a/pom.xml
+++ b/pom.xml
@@ -117,7 +117,7 @@
5.3.37
3.0.8
1.0.7
- 3.2.5
+ 3.3.1
6.2.4.Final
2.3.33