WW-4374 Fixes problem with accessing Enum's values() method

This commit is contained in:
Lukasz Lenart
2014-07-29 09:23:44 +02:00
parent 47d1fe04dc
commit bf6b37f2e3
3 changed files with 61 additions and 13 deletions
@@ -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) {
@@ -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
}
@@ -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
}