Introduces new callMethod() function to be used to execute actions (cherry picked from commit b28b78c062f0bf3c79793a25aab8c9b6c12bce6e)
Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/7da4ef39 Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/7da4ef39 Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/7da4ef39 Branch: refs/heads/master Commit: 7da4ef39023bb5d86509d65565a04b533e8b4c55 Parents: ce294b4 Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Sun Jun 12 13:03:39 2016 +0200 Committer: Lukasz Lenart <lukaszlen...@apache.org> Committed: Sun Jun 12 13:03:39 2016 +0200 ---------------------------------------------------------------------- .../xwork2/DefaultActionInvocation.java | 2 +- .../com/opensymphony/xwork2/ognl/OgnlUtil.java | 64 ++++++++++++++++++++ .../opensymphony/xwork2/ognl/OgnlUtilTest.java | 15 +++++ 3 files changed, 80 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/7da4ef39/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java index 167159c..639bf95 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java @@ -419,7 +419,7 @@ public class DefaultActionInvocation implements ActionInvocation { Object methodResult; try { - methodResult = ognlUtil.getValue(methodName + "()", getStack().getContext(), action); + methodResult = ognlUtil.callMethod(methodName + "()", getStack().getContext(), action); } catch (MethodFailedException e) { // if reason is missing method, try checking UnknownHandlers if (e.getReason() instanceof NoSuchMethodException) { http://git-wip-us.apache.org/repos/asf/struts/blob/7da4ef39/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java index 562b6fc..86e9c53 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java @@ -289,6 +289,9 @@ public class OgnlUtil { if (isEvalExpression(tree, context)) { throw new OgnlException("Eval expression/chained expressions cannot be used as parameter name"); } + if (isArithmeticExpression(tree, context)) { + throw new OgnlException("Arithmetic expressions cannot be used as parameter name"); + } Ognl.setValue(tree, context, root, value); return null; } @@ -308,6 +311,32 @@ public class OgnlUtil { return false; } + private boolean isArithmeticExpression(Object tree, Map<String, Object> context) throws OgnlException { + if (tree instanceof SimpleNode) { + SimpleNode node = (SimpleNode) tree; + OgnlContext ognlContext = null; + + if (context!=null && context instanceof OgnlContext) { + ognlContext = (OgnlContext) context; + } + return node.isOperation(ognlContext); + } + return false; + } + + private boolean isSimpleMethod(Object tree, Map<String, Object> context) throws OgnlException { + if (tree instanceof SimpleNode) { + SimpleNode node = (SimpleNode) tree; + OgnlContext ognlContext = null; + + if (context!=null && context instanceof OgnlContext) { + ognlContext = (OgnlContext) context; + } + return node.isSimpleMethod(ognlContext) && !node.isChain(ognlContext); + } + return false; + } + public Object getValue(final String name, final Map<String, Object> context, final Object root) throws OgnlException { return compileAndExecute(name, context, new OgnlTask<Object>() { public Object execute(Object tree) throws OgnlException { @@ -316,6 +345,14 @@ public class OgnlUtil { }); } + public Object callMethod(final String name, final Map<String, Object> context, final Object root) throws OgnlException { + return compileAndExecuteMethod(name, context, new OgnlTask<Object>() { + public Object execute(Object tree) throws OgnlException { + return Ognl.getValue(tree, context, root); + } + }); + } + public Object getValue(final String name, final Map<String, Object> context, final Object root, final Class resultType) throws OgnlException { return compileAndExecute(name, context, new OgnlTask<Object>() { public Object execute(Object tree) throws OgnlException { @@ -350,6 +387,27 @@ public class OgnlUtil { return exec; } + private <T> Object compileAndExecuteMethod(String expression, Map<String, Object> context, OgnlTask<T> task) throws OgnlException { + Object tree; + if (enableExpressionCache) { + tree = expressions.get(expression); + if (tree == null) { + tree = Ognl.parseExpression(expression); + checkSimpleMethod(tree, context); + } + } else { + tree = Ognl.parseExpression(expression); + checkSimpleMethod(tree, context); + } + + final T exec = task.execute(tree); + // if cache is enabled and it's a valid expression, puts it in + if(enableExpressionCache) { + expressions.putIfAbsent(expression, tree); + } + return exec; + } + 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 { @@ -364,6 +422,12 @@ public class OgnlUtil { } } + private void checkSimpleMethod(Object tree, Map<String, Object> context) throws OgnlException { + if (!isSimpleMethod(tree, context)) { + throw new OgnlException("It isn't a simple method which can be called!"); + } + } + /** * Copies the properties in the object "from" and sets them in the object "to" * using specified type converter, or {@link com.opensymphony.xwork2.conversion.impl.XWorkConverter} if none http://git-wip-us.apache.org/repos/asf/struts/blob/7da4ef39/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java index 339d603..4fdf742 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java @@ -759,6 +759,21 @@ public class OgnlUtilTest extends XWorkTestCase { assertEquals(expected.getMessage(), "Eval expressions/chained expressions have been disabled!"); } + public void testCallMethod() throws Exception { + Foo foo = new Foo(); + + Exception expected = null; + try { + ognlUtil.callMethod("#booScope=@myclass@DEFAULT_SCOPE,#bootScope.init()", ognlUtil.createDefaultContext(foo), foo); + fail(); + } catch (OgnlException e) { + expected = e; + } + assertNotNull(expected); + assertSame(OgnlException.class, expected.getClass()); + assertEquals(expected.getMessage(), "It isn't a simple method which can be called!"); + } + public static class Email { String address;