Repository: struts Updated Branches: refs/heads/feature/exclude-object-class [created] aff3a3a62
Defines new logic to allow exclude some properties (eg. getClass) Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/25503840 Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/25503840 Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/25503840 Branch: refs/heads/feature/exclude-object-class Commit: 255038405549562593227c221c04a6cb096a0c05 Parents: 9519cd1 Author: Lukasz Lenart <[email protected]> Authored: Fri Apr 25 14:57:07 2014 +0200 Committer: Lukasz Lenart <[email protected]> Committed: Fri Apr 25 14:57:07 2014 +0200 ---------------------------------------------------------------------- .../com/opensymphony/xwork2/ognl/OgnlUtil.java | 26 ++++++ .../opensymphony/xwork2/ognl/OgnlUtilTest.java | 91 +++++++++++++++++++- 2 files changed, 116 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/25503840/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java index fa907e3..a0231bc 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java @@ -19,6 +19,7 @@ import com.opensymphony.xwork2.XWorkConstants; import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.CompoundRoot; +import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; import com.opensymphony.xwork2.util.reflection.ReflectionException; @@ -36,7 +37,9 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -58,6 +61,8 @@ public class OgnlUtil { private boolean enableExpressionCache = true; private boolean enableEvalExpression; + private Set<String> excludedProperties = new HashSet<String>(); + @Inject public void setXWorkConverter(XWorkConverter conv) { this.defaultConverter = new OgnlTypeConverterWrapper(conv); @@ -82,6 +87,11 @@ public class OgnlUtil { } } + @Inject(value = XWorkConstants.OGNL_EXCLUDED_PROPERTIES, required = false) + public void setExcludedProperties(String commaDelimitedProperties) { + excludedProperties = TextParseUtil.commaDelimitedStringToSet(commaDelimitedProperties); + } + /** * Sets the object's properties using the default type converter, defaulting to not throw * exceptions for problems setting the properties. @@ -279,11 +289,13 @@ public class OgnlUtil { if (tree == null) { tree = Ognl.parseExpression(expression); checkEnableEvalExpression(tree, context); + checkExcludedPropertiesAccess(tree, null); expressions.putIfAbsent(expression, tree); } } else { tree = Ognl.parseExpression(expression); checkEnableEvalExpression(tree, context); + checkExcludedPropertiesAccess(tree, null); } @@ -293,6 +305,20 @@ public class OgnlUtil { return exec; } + private void checkExcludedPropertiesAccess(Object tree, SimpleNode parent) throws OgnlException { + if (tree instanceof SimpleNode) { + SimpleNode node = (SimpleNode) tree; + for (String excludedPattern : excludedProperties) { + if (excludedPattern.equalsIgnoreCase(node.toString())) { + throw new OgnlException("Tree [" + (parent != null ? parent : tree) + "] trying access excluded pattern [" + excludedPattern + "]"); + } + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + checkExcludedPropertiesAccess(node.jjtGetChild(i), node); + } + } + } + } + public Object compile(String expression, Map<String, Object> context) throws OgnlException { return compileAndExecute(expression,context,new OgnlTask<Object>() { public Object execute(Object tree) throws OgnlException { http://git-wip-us.apache.org/repos/asf/struts/blob/25503840/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java index 8bd5e23..d471183 100644 --- a/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java +++ b/xwork-core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java @@ -630,7 +630,96 @@ public class OgnlUtilTest extends XWorkTestCase { stack.setValue("1114778947765", foo); stack.setValue("1234", foo); } - + + public void testAvoidCallingMethodsOnObjectClass() throws Exception { + Foo foo = new Foo(); + OgnlUtil util = new OgnlUtil(); + util.setEnableExpressionCache("false"); + util.setExcludedProperties("class"); + + Exception expected = null; + try { + util.setValue("class.classLoader.defaultAssertionStatus", ActionContext.getContext().getContextMap(), foo, true); + fail(); + } catch (OgnlException e) { + expected = e; + } + assertNotNull(expected); + assertSame(expected.getClass(), OgnlException.class); + assertEquals(expected.getMessage(), "Tree [class.classLoader.defaultAssertionStatus] trying access excluded pattern [class]"); + } + + public void testAvoidCallingMethodsOnObjectClassUpperCased() throws Exception { + Foo foo = new Foo(); + OgnlUtil util = new OgnlUtil(); + util.setEnableExpressionCache("false"); + util.setExcludedProperties("class"); + + Exception expected = null; + try { + util.setValue("Class.ClassLoader.DefaultAssertionStatus", ActionContext.getContext().getContextMap(), foo, true); + fail(); + } catch (OgnlException e) { + expected = e; + } + assertNotNull(expected); + assertSame(expected.getClass(), OgnlException.class); + assertEquals(expected.getMessage(), "Tree [Class.ClassLoader.DefaultAssertionStatus] trying access excluded pattern [class]"); + } + + public void testAvoidCallingMethodsOnObjectClassAsMap() throws Exception { + Foo foo = new Foo(); + OgnlUtil util = new OgnlUtil(); + util.setEnableExpressionCache("false"); + util.setExcludedProperties("class"); + + Exception expected = null; + try { + util.setValue("class['classLoader']['defaultAssertionStatus']", ActionContext.getContext().getContextMap(), foo, true); + fail(); + } catch (OgnlException e) { + expected = e; + } + assertNotNull(expected); + assertSame(expected.getClass(), OgnlException.class); + assertEquals(expected.getMessage(), "Tree [class[\"classLoader\"][\"defaultAssertionStatus\"]] trying access excluded pattern [class]"); + } + + public void testAvoidCallingMethodsOnObjectClassAsMapWithQuotes() throws Exception { + Foo foo = new Foo(); + OgnlUtil util = new OgnlUtil(); + util.setEnableExpressionCache("false"); + util.setExcludedProperties("class"); + + Exception expected = null; + try { + util.setValue("class[\"classLoader\"]['defaultAssertionStatus']", ActionContext.getContext().getContextMap(), foo, true); + fail(); + } catch (OgnlException e) { + expected = e; + } + assertNotNull(expected); + assertSame(expected.getClass(), OgnlException.class); + assertEquals(expected.getMessage(), "Tree [class[\"classLoader\"][\"defaultAssertionStatus\"]] trying access excluded pattern [class]"); + } + + public void testAvoidCallingToString() throws Exception { + Foo foo = new Foo(); + OgnlUtil util = new OgnlUtil(); + util.setEnableExpressionCache("false"); + util.setExcludedProperties("toString"); + + Exception expected = null; + try { + util.setValue("toString", ActionContext.getContext().getContextMap(), foo, true); + fail(); + } catch (OgnlException e) { + expected = e; + } + assertNotNull(expected); + assertSame(expected.getClass(), OgnlException.class); + assertEquals(expected.getMessage(), "Tree [toString] trying access excluded pattern [toString]"); + } public static class Email { String address;
