diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java b/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java index d0862e7de..a172237f4 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/SecurityMemberAccess.java @@ -53,6 +53,13 @@ public class SecurityMemberAccess extends DefaultMemberAccess { @Override public boolean isAccessible(Map context, Object target, Member member, String propertyName) { + if (checkEnumAccess(target, member)) { + if (LOG.isTraceEnabled()) { + LOG.trace("Allowing access to enum #0", target); + } + return true; + } + if (isPackageExcluded(target.getClass().getPackage(), member.getDeclaringClass().getPackage())) { if (LOG.isWarnEnabled()) { LOG.warn("Package of target [#0] or package of member [#1] are excluded!", target, member); @@ -68,17 +75,11 @@ public class SecurityMemberAccess extends DefaultMemberAccess { } boolean allow = true; - int modifiers = member.getModifiers(); - if (Modifier.isStatic(modifiers)) { - if (member instanceof Method && !getAllowStaticMethodAccess()) { - allow = false; - if (target instanceof Class) { - Class clazz = (Class) target; - Method method = (Method) member; - if (Enum.class.isAssignableFrom(clazz) && method.getName().equals("values")) - allow = true; - } + if (!checkStaticMethodAccess(member)) { + if (LOG.isTraceEnabled()) { + LOG.warn("Access to static [#0] is blocked!", member); } + allow = false; } //failed static test @@ -86,10 +87,26 @@ public class SecurityMemberAccess extends DefaultMemberAccess { return false; // Now check for standard scope rules - if (!super.isAccessible(context, target, member, propertyName)) - return false; + return super.isAccessible(context, target, member, propertyName) + && isAcceptableProperty(propertyName); + } - return isAcceptableProperty(propertyName); + protected boolean checkStaticMethodAccess(Member member) { + int modifiers = member.getModifiers(); + if (Modifier.isStatic(modifiers)) { + return allowStaticMethodAccess; + } else { + return true; + } + } + + protected boolean checkEnumAccess(Object target, Member member) { + if (target instanceof Class) { + Class clazz = (Class) target; + if (Enum.class.isAssignableFrom(clazz) && member.getName().equals("values")) + return true; + } + return false; } protected boolean isPackageExcluded(Package targetPackage, Package memberPackage) { diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java index cb7108134..e0e949cec 100644 --- a/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java +++ b/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java @@ -235,6 +235,17 @@ public class OgnlValueStackTest extends XWorkTestCase { assertEquals("fido", vs.findValue("@com.opensymphony.xwork2.util.Dog@getDeity()", String.class)); } + /** + * Allow access Enums without enabling access to static methods + */ + public void testEnum() throws Exception { + OgnlValueStack vs = createValueStack(); + + assertEquals("ONE", vs.findValue("@com.opensymphony.xwork2.ognl.MyNumbers@values()[0]", String.class)); + assertEquals("TWO", vs.findValue("@com.opensymphony.xwork2.ognl.MyNumbers@values()[1]", String.class)); + assertEquals("THREE", vs.findValue("@com.opensymphony.xwork2.ognl.MyNumbers@values()[2]", String.class)); + } + public void testStaticMethodDisallow() { OgnlValueStack vs = createValueStack(false); @@ -1026,3 +1037,7 @@ public class OgnlValueStackTest extends XWorkTestCase { } } } + +enum MyNumbers { + ONE, TWO, THREE +} \ No newline at end of file diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/SecurityMemberAccessTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/SecurityMemberAccessTest.java index 748d5a959..61a91a057 100644 --- a/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/SecurityMemberAccessTest.java +++ b/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/SecurityMemberAccessTest.java @@ -190,6 +190,18 @@ public class SecurityMemberAccessTest extends TestCase { assertFalse("stringField is accessible!", actual); } + public void testAccessEnum() throws Exception { + // given + SecurityMemberAccess sma = new SecurityMemberAccess(false); + + // when + Member values = MyValues.class.getMethod("values"); + boolean actual = sma.isAccessible(context, MyValues.class, values, null); + + // then + assertTrue("Access to enums is blocked!", actual); + } + } class FooBar implements FooBarInterface { @@ -233,4 +245,8 @@ interface BarInterface { interface FooBarInterface extends FooInterface, BarInterface { +} + +enum MyValues { + ONE, TWO, THREE } \ No newline at end of file