(struts) 01/01: WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a commit to branch WW-5534-proxyutil
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 4316c6e6280a15b37f0a3d71d169061ba826c41e
Author: Kusal Kithul-Godage 
AuthorDate: Fri Feb 28 04:07:25 2025 +1100

WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent
---
 core/pom.xml   |   8 +-
 .../struts2/interceptor/ChainingInterceptor.java   |  24 +--
 .../java/org/apache/struts2/ognl/OgnlCache.java|  50 --
 .../org/apache/struts2/ognl/OgnlCaffeineCache.java |   4 +-
 .../org/apache/struts2/ognl/OgnlDefaultCache.java  |  17 +-
 .../java/org/apache/struts2/ognl/OgnlLRUCache.java |   4 +-
 .../java/org/apache/struts2/ognl/OgnlUtil.java |  31 ++--
 .../java/org/apache/struts2/util/ProxyUtil.java| 180 +++--
 .../java/org/apache/struts2/ognl/OgnlUtilTest.java |  28 ++--
 .../org/apache/struts2/json/DefaultJSONWriter.java |   6 +-
 10 files changed, 169 insertions(+), 183 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index 2e10aafcc..a70b30133 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -187,13 +187,19 @@
 commons-text
 
 
-
 
+
 org.hibernate
 hibernate-core
 5.6.15.Final
 true
 
+
+
+org.springframework
+spring-aop
+true
+
 
 
 org.springframework
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java 
b/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java
index c114d65e1..2837d4c10 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java
@@ -20,11 +20,11 @@ package org.apache.struts2.interceptor;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.struts2.result.ActionChainResult;
 import org.apache.struts2.ActionInvocation;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.Unchainable;
 import org.apache.struts2.inject.Inject;
+import org.apache.struts2.result.ActionChainResult;
 import org.apache.struts2.result.Result;
 import org.apache.struts2.util.CompoundRoot;
 import org.apache.struts2.util.ProxyUtil;
@@ -167,17 +167,18 @@ public class ChainingInterceptor extends 
AbstractInterceptor {
 }
 
 private void copyStack(ActionInvocation invocation, CompoundRoot root) {
-List list = prepareList(root);
+List list = prepareList(root);
 Map ctxMap = 
invocation.getInvocationContext().getContextMap();
 for (Object object : list) {
-if (shouldCopy(object)) {
-Object action = invocation.getAction();
-Class editable = null;
-if(ProxyUtil.isProxy(action)) {
-editable = ProxyUtil.ultimateTargetClass(action);
-}
-reflectionProvider.copy(object, action, ctxMap, 
prepareExcludes(), includes, editable);
+if (!shouldCopy(object)) {
+continue;
+}
+Object action = invocation.getAction();
+Class editable = null;
+if (ProxyUtil.isProxy(action)) {
+editable = ProxyUtil.ultimateTargetClass(action);
 }
+reflectionProvider.copy(object, action, ctxMap, prepareExcludes(), 
includes, editable);
 }
 }
 
@@ -204,9 +205,8 @@ public class ChainingInterceptor extends 
AbstractInterceptor {
 return o != null && !(o instanceof Unchainable);
 }
 
-@SuppressWarnings("unchecked")
-private List prepareList(CompoundRoot root) {
-List list = new ArrayList(root);
+private List prepareList(CompoundRoot root) {
+var list = new ArrayList<>(root);
 list.remove(0);
 Collections.reverse(list);
 return list;
diff --git a/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java
index ec2d002e9..3c3e1d9b4 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java
@@ -15,21 +15,53 @@
  */
 package org.apache.struts2.ognl;
 
+import java.util.function.Function;
+
+import static java.util.Objects.requireNonNull;
+
 /**
- * A basic cache interface for use with OGNL processing (such as Expression, 
BeanInfo).
- * All OGNL caches will have an eviction limit, but setting an extremely high 
value can
- * simulate an "effectively unlimited" cache.
+ * A basic cache interface for use with OGNL processing (such as Expression, 
BeanInfo). Implementation must be
+ * thread-safe. All OGNL caches will have an eviction limit, but setting an 
extremely high value can simulate an
+ * "effectively un

(struts) branch WW-5534-proxyutil created (now 4316c6e62)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-proxyutil
in repository https://gitbox.apache.org/repos/asf/struts.git


  at 4316c6e62 WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

This branch includes the following new commits:

 new 4316c6e62 WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(struts) 01/01: WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a commit to branch WW-5534-proxyutil
in repository https://gitbox.apache.org/repos/asf/struts.git

commit bcf569b37bf625dfdccbe84fa624f9a12ca40e0b
Author: Kusal Kithul-Godage 
AuthorDate: Fri Feb 28 04:07:25 2025 +1100

WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent
---
 core/pom.xml   |   8 +-
 .../struts2/interceptor/ChainingInterceptor.java   |  24 +--
 .../java/org/apache/struts2/ognl/OgnlCache.java|  34 ++--
 .../org/apache/struts2/ognl/OgnlCaffeineCache.java |   7 +
 .../org/apache/struts2/ognl/OgnlDefaultCache.java  |  16 +-
 .../java/org/apache/struts2/ognl/OgnlLRUCache.java |   6 +
 .../java/org/apache/struts2/ognl/OgnlUtil.java |  31 ++--
 .../java/org/apache/struts2/util/ProxyUtil.java| 180 +++--
 .../java/org/apache/struts2/ognl/OgnlUtilTest.java |  26 +--
 .../org/apache/struts2/json/DefaultJSONWriter.java |   6 +-
 10 files changed, 162 insertions(+), 176 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index 2e10aafcc..a70b30133 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -187,13 +187,19 @@
 commons-text
 
 
-
 
+
 org.hibernate
 hibernate-core
 5.6.15.Final
 true
 
+
+
+org.springframework
+spring-aop
+true
+
 
 
 org.springframework
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java 
b/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java
index c114d65e1..2837d4c10 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/ChainingInterceptor.java
@@ -20,11 +20,11 @@ package org.apache.struts2.interceptor;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.struts2.result.ActionChainResult;
 import org.apache.struts2.ActionInvocation;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.Unchainable;
 import org.apache.struts2.inject.Inject;
+import org.apache.struts2.result.ActionChainResult;
 import org.apache.struts2.result.Result;
 import org.apache.struts2.util.CompoundRoot;
 import org.apache.struts2.util.ProxyUtil;
@@ -167,17 +167,18 @@ public class ChainingInterceptor extends 
AbstractInterceptor {
 }
 
 private void copyStack(ActionInvocation invocation, CompoundRoot root) {
-List list = prepareList(root);
+List list = prepareList(root);
 Map ctxMap = 
invocation.getInvocationContext().getContextMap();
 for (Object object : list) {
-if (shouldCopy(object)) {
-Object action = invocation.getAction();
-Class editable = null;
-if(ProxyUtil.isProxy(action)) {
-editable = ProxyUtil.ultimateTargetClass(action);
-}
-reflectionProvider.copy(object, action, ctxMap, 
prepareExcludes(), includes, editable);
+if (!shouldCopy(object)) {
+continue;
+}
+Object action = invocation.getAction();
+Class editable = null;
+if (ProxyUtil.isProxy(action)) {
+editable = ProxyUtil.ultimateTargetClass(action);
 }
+reflectionProvider.copy(object, action, ctxMap, prepareExcludes(), 
includes, editable);
 }
 }
 
@@ -204,9 +205,8 @@ public class ChainingInterceptor extends 
AbstractInterceptor {
 return o != null && !(o instanceof Unchainable);
 }
 
-@SuppressWarnings("unchecked")
-private List prepareList(CompoundRoot root) {
-List list = new ArrayList(root);
+private List prepareList(CompoundRoot root) {
+var list = new ArrayList<>(root);
 list.remove(0);
 Collections.reverse(list);
 return list;
diff --git a/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java 
b/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java
index ec2d002e9..d7c88b336 100644
--- a/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java
+++ b/core/src/main/java/org/apache/struts2/ognl/OgnlCache.java
@@ -15,21 +15,37 @@
  */
 package org.apache.struts2.ognl;
 
+import java.util.function.Function;
+
+import static java.util.Objects.requireNonNull;
+
 /**
- * A basic cache interface for use with OGNL processing (such as Expression, 
BeanInfo).
- * All OGNL caches will have an eviction limit, but setting an extremely high 
value can
- * simulate an "effectively unlimited" cache.
+ * A basic cache interface for use with OGNL processing (such as Expression, 
BeanInfo). Implementation must be
+ * thread-safe. All OGNL caches will have an eviction limit, but setting an 
extremely high value can simulate an
+ * "effectively unlimit

(struts) branch WW-5534-proxyutil updated (4316c6e62 -> bcf569b37)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-proxyutil
in repository https://gitbox.apache.org/repos/asf/struts.git


 discard 4316c6e62 WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent
 new bcf569b37 WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (4316c6e62)
\
 N -- N -- N   refs/heads/WW-5534-proxyutil (bcf569b37)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/struts2/ognl/OgnlCache.java| 26 +-
 .../org/apache/struts2/ognl/OgnlCaffeineCache.java | 11 +++--
 .../org/apache/struts2/ognl/OgnlDefaultCache.java  | 15 -
 .../java/org/apache/struts2/ognl/OgnlLRUCache.java | 10 +++--
 .../java/org/apache/struts2/ognl/OgnlUtilTest.java |  2 +-
 5 files changed, 32 insertions(+), 32 deletions(-)



(struts) branch WW-5534-proxyutil updated (bcf569b37 -> 74ec63cde)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-proxyutil
in repository https://gitbox.apache.org/repos/asf/struts.git


 discard bcf569b37 WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent
 add 74ec63cde WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (bcf569b37)
\
 N -- N -- N   refs/heads/WW-5534-proxyutil (74ec63cde)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

No new revisions were added by this update.

Summary of changes:
 core/src/test/java/org/apache/struts2/ognl/OgnlUtilTest.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



(struts) branch WW-5534-proxyutil updated (74ec63cde -> 8579a10f5)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-proxyutil
in repository https://gitbox.apache.org/repos/asf/struts.git


 discard 74ec63cde WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent
 add 8579a10f5 WW-5534 Simplify ProxyUtil, add OgnlCache#computeIfAbsent

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (74ec63cde)
\
 N -- N -- N   refs/heads/WW-5534-proxyutil (8579a10f5)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

No new revisions were added by this update.

Summary of changes:
 .../java/org/apache/struts2/ognl/OgnlUtilTest.java | 24 +++---
 1 file changed, 12 insertions(+), 12 deletions(-)



(struts) branch WW-5534-annotation-allowlist-proxy created (now ccd06612a)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-annotation-allowlist-proxy
in repository https://gitbox.apache.org/repos/asf/struts.git


  at ccd06612a WW-5534 Allow @StrutsParameter recognition and OGNL 
allowlist for Spring proxies

This branch includes the following new commits:

 new ccd06612a WW-5534 Allow @StrutsParameter recognition and OGNL 
allowlist for Spring proxies

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.




(struts) 01/01: WW-5534 Allow @StrutsParameter recognition and OGNL allowlist for Spring proxies

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a commit to branch WW-5534-annotation-allowlist-proxy
in repository https://gitbox.apache.org/repos/asf/struts.git

commit ccd06612abde48e90995d166881829f2c24bd51f
Author: Kusal Kithul-Godage 
AuthorDate: Fri Feb 28 04:42:36 2025 +1100

WW-5534 Allow @StrutsParameter recognition and OGNL allowlist for Spring 
proxies
---
 .../parameter/ParametersInterceptor.java   | 34 +++--
 .../apache/struts2/ognl/SecurityMemberAccess.java  | 35 +++---
 2 files changed, 36 insertions(+), 33 deletions(-)

diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
index 92449415e..4cd1c3faa 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
@@ -33,12 +33,14 @@ import org.apache.struts2.dispatcher.HttpParameters;
 import org.apache.struts2.dispatcher.Parameter;
 import org.apache.struts2.inject.Inject;
 import org.apache.struts2.interceptor.MethodFilterInterceptor;
+import org.apache.struts2.ognl.OgnlUtil;
 import org.apache.struts2.ognl.ThreadAllowlist;
 import org.apache.struts2.security.AcceptedPatternsChecker;
 import org.apache.struts2.security.DefaultAcceptedPatternsChecker;
 import org.apache.struts2.security.ExcludedPatternsChecker;
 import org.apache.struts2.util.ClearableValueStack;
 import org.apache.struts2.util.MemberAccessValueStack;
+import org.apache.struts2.util.ProxyUtil;
 import org.apache.struts2.util.TextParseUtil;
 import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.util.ValueStackFactory;
@@ -46,7 +48,6 @@ import 
org.apache.struts2.util.reflection.ReflectionContextState;
 
 import java.beans.BeanInfo;
 import java.beans.IntrospectionException;
-import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Field;
@@ -93,6 +94,7 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
 protected boolean requireAnnotationsTransitionMode = false;
 
 private ValueStackFactory valueStackFactory;
+private OgnlUtil ognlUtil;
 protected ThreadAllowlist threadAllowlist;
 private ExcludedPatternsChecker excludedPatterns;
 private AcceptedPatternsChecker acceptedPatterns;
@@ -104,6 +106,11 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
 this.valueStackFactory = valueStackFactory;
 }
 
+@Inject
+public void setOgnlUtil(OgnlUtil ognlUtil) {
+this.ognlUtil = ognlUtil;
+}
+
 @Inject
 public void setThreadAllowlist(ThreadAllowlist threadAllowlist) {
 this.threadAllowlist = threadAllowlist;
@@ -395,6 +402,7 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
 }
 
 protected boolean hasValidAnnotatedPropertyDescriptor(Object action, 
PropertyDescriptor propDesc, long paramDepth) {
+Class actionClass = ultimateClass(action);
 Method relevantMethod = paramDepth == 0 ? propDesc.getWriteMethod() : 
propDesc.getReadMethod();
 if (relevantMethod == null) {
 return false;
@@ -412,7 +420,7 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
 return false;
 }
 LOG.debug("Success: Matching annotated method [{}] found for property 
[{}] of depth [{}] on Action [{}]",
-relevantMethod.getName(), propDesc.getName(), paramDepth, 
action.getClass().getSimpleName());
+relevantMethod.getName(), propDesc.getName(), paramDepth, 
actionClass.getSimpleName());
 if (paramDepth >= 1) {
 allowlistClass(propDesc.getPropertyType());
 }
@@ -451,24 +459,25 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
 }
 
 protected boolean hasValidAnnotatedField(Object action, String fieldName, 
long paramDepth) {
+Class actionClass = ultimateClass(action);
 LOG.debug("No matching annotated method found for property [{}] of 
depth [{}] on Action [{}], now also checking for public field",
-fieldName, paramDepth, action.getClass().getSimpleName());
+fieldName, paramDepth, actionClass.getSimpleName());
 Field field;
 try {
-field = action.getClass().getDeclaredField(fieldName);
+field = actionClass.getDeclaredField(fieldName);
 } catch (NoSuchFieldException e) {
-LOG.debug("Matching field for property [{}] not found on Action 
[{}]", fieldName, action.getClass().getSimpleName());
+LOG.debug("Matching field for property [{}] not found on Action 
[{}]", fieldName, actionClass.getSimpleName());
 return false;
 }
 if

(struts) branch WW-5534-annotation-allowlist-proxy updated (ccd06612a -> 2df54ead5)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-annotation-allowlist-proxy
in repository https://gitbox.apache.org/repos/asf/struts.git


 discard ccd06612a WW-5534 Allow @StrutsParameter recognition and OGNL 
allowlist for Spring proxies
 add 2df54ead5 WW-5534 Allow @StrutsParameter recognition and OGNL 
allowlist for Spring proxies

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (ccd06612a)
\
 N -- N -- N   refs/heads/WW-5534-annotation-allowlist-proxy 
(2df54ead5)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

No new revisions were added by this update.

Summary of changes:
 .../parameter/StrutsParameterAnnotationTest.java| 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)



(struts) branch WW-5534-annotation-allowlist-proxy updated (2df54ead5 -> b075b6740)

2025-02-27 Thread kusal
This is an automated email from the ASF dual-hosted git repository.

kusal pushed a change to branch WW-5534-annotation-allowlist-proxy
in repository https://gitbox.apache.org/repos/asf/struts.git


omit 2df54ead5 WW-5534 Allow @StrutsParameter recognition and OGNL 
allowlist for Spring proxies
 add b075b6740 WW-5534 Allow @StrutsParameter recognition and OGNL 
allowlist for Spring proxies

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (2df54ead5)
\
 N -- N -- N   refs/heads/WW-5534-annotation-allowlist-proxy 
(b075b6740)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

No new revisions were added by this update.

Summary of changes:
 .../interceptor/parameter/StrutsParameterAnnotationTest.java   | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)