From b36e88ff4b2810776854041dc1e71fd95228aef5 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sun, 12 May 2024 09:47:38 +0200 Subject: [PATCH 1/2] WW-5415 Fixes accessing public constructors via expression --- .../xwork2/ognl/SecurityMemberAccess.java | 2 +- .../xwork2/validator/VisitorFieldValidatorTest.java | 11 +++++++++++ .../xwork2/validator/VisitorValidatorTestAction.java | 11 ++++++++++- .../VisitorValidatorTestAction-validation.xml | 8 ++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java index 43ae992405..8a8c713269 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java @@ -147,7 +147,7 @@ public boolean isAccessible(Map context, Object target, Member member, String pr if (target != null) { // Special case: Target is a Class object but not Class.class if (Class.class.equals(target.getClass()) && !Class.class.equals(target)) { - if (!isStatic(member)) { + if (!isStatic(member) && Arrays.stream(((Class) target).getConstructors()).noneMatch(p -> p.getClass().equals(member.getClass()))) { throw new IllegalArgumentException("Member expected to be static!"); } if (!member.getDeclaringClass().equals(target)) { diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFieldValidatorTest.java index 76c2eac718..de605d2c5f 100644 --- a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFieldValidatorTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorFieldValidatorTest.java @@ -28,6 +28,8 @@ import com.opensymphony.xwork2.conversion.impl.ConversionData; import org.easymock.EasyMock; +import java.sql.Date; +import java.time.LocalDate; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; @@ -142,6 +144,15 @@ public void testCollectionValidation() throws Exception { assertEquals(1, errors.size()); } + public void testDateValidation() throws Exception { + action.setBirthday(Date.valueOf(LocalDate.now().minusYears(20))); + action.setContext("birthday"); + + validate("birthday"); + + assertFalse(action.hasFieldErrors()); + } + public void testContextIsOverriddenByContextParamInValidationXML() throws Exception { validate("visitorValidationAlias"); assertTrue(action.hasFieldErrors()); diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorTestAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorTestAction.java index 2050726f7f..9e672bf489 100644 --- a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorTestAction.java +++ b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorTestAction.java @@ -22,6 +22,7 @@ import com.opensymphony.xwork2.TestBean; import java.util.ArrayList; +import java.util.Date; import java.util.List; @@ -37,7 +38,7 @@ public class VisitorValidatorTestAction extends ActionSupport { private String context; private TestBean bean = new TestBean(); private TestBean[] testBeanArray; - + private Date birthday; public VisitorValidatorTestAction() { testBeanArray = new TestBean[5]; @@ -80,4 +81,12 @@ public void setTestBeanList(List testBeanList) { public List getTestBeanList() { return testBeanList; } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } } diff --git a/core/src/test/resources/com/opensymphony/xwork2/validator/VisitorValidatorTestAction-validation.xml b/core/src/test/resources/com/opensymphony/xwork2/validator/VisitorValidatorTestAction-validation.xml index a8de9f705c..fb2aa80bf2 100644 --- a/core/src/test/resources/com/opensymphony/xwork2/validator/VisitorValidatorTestAction-validation.xml +++ b/core/src/test/resources/com/opensymphony/xwork2/validator/VisitorValidatorTestAction-validation.xml @@ -26,4 +26,12 @@ You must enter a context. + + + + + + From 7c523ac33e3bdade323bc4e414b98de66f268c09 Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Mon, 13 May 2024 12:37:04 +1000 Subject: [PATCH 2/2] WW-5415 Constructor members should be exempted as static members --- .../com/opensymphony/xwork2/ognl/SecurityMemberAccess.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java index 8a8c713269..f882b2c583 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java @@ -29,6 +29,7 @@ import org.apache.struts2.ognl.ThreadAllowlist; import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Modifier; @@ -147,11 +148,11 @@ public boolean isAccessible(Map context, Object target, Member member, String pr if (target != null) { // Special case: Target is a Class object but not Class.class if (Class.class.equals(target.getClass()) && !Class.class.equals(target)) { - if (!isStatic(member) && Arrays.stream(((Class) target).getConstructors()).noneMatch(p -> p.getClass().equals(member.getClass()))) { - throw new IllegalArgumentException("Member expected to be static!"); + if (!isStatic(member) && !Constructor.class.equals(member.getClass())) { + throw new IllegalArgumentException("Member expected to be static or constructor!"); } if (!member.getDeclaringClass().equals(target)) { - throw new IllegalArgumentException("Target class does not match static member!"); + throw new IllegalArgumentException("Target class does not match member!"); } target = null; // This information is not useful to us and conflicts with following logic which expects target to be null or an instance containing the member // Standard case: Member should exist on target