From b28b78c062f0bf3c79793a25aab8c9b6c12bce6e Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Fri, 3 Jun 2016 13:10:58 +0200 Subject: [PATCH] Introduces new callMethod() function to be used to execute actions --- .../xwork2/DefaultActionInvocation.java | 4 +- .../opensymphony/xwork2/ognl/OgnlUtil.java | 64 +++++++++++++++++++ .../xwork2/ognl/OgnlUtilTest.java | 15 +++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java b/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java index fcf397ec0e..d4c995c72b 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java @@ -427,13 +427,13 @@ protected String invokeAction(Object action, ActionConfig actionConfig) throws E 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 find version with "do" prefix if (e.getReason() instanceof NoSuchMethodException) { try { String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1) + "()"; - methodResult = ognlUtil.getValue(altMethodName, getStack().getContext(), action); + methodResult = ognlUtil.callMethod(altMethodName, getStack().getContext(), action); } catch (MethodFailedException e1) { // if still method doesn't exist, try checking UnknownHandlers if (e1.getReason() instanceof NoSuchMethodException) { 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 40d112b9aa..42132ba16e 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 @@ -290,6 +290,9 @@ public Void execute(Object tree) throws OgnlException { 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; } @@ -309,6 +312,32 @@ private boolean isEvalExpression(Object tree, Map context) throw return false; } + private boolean isArithmeticExpression(Object tree, Map 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 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 context, final Object root) throws OgnlException { return compileAndExecute(name, context, new OgnlTask() { public Object execute(Object tree) throws OgnlException { @@ -317,6 +346,14 @@ public Object execute(Object tree) throws OgnlException { }); } + public Object callMethod(final String name, final Map context, final Object root) throws OgnlException { + return compileAndExecuteMethod(name, context, new OgnlTask() { + public Object execute(Object tree) throws OgnlException { + return Ognl.getValue(tree, context, root); + } + }); + } + public Object getValue(final String name, final Map context, final Object root, final Class resultType) throws OgnlException { return compileAndExecute(name, context, new OgnlTask() { public Object execute(Object tree) throws OgnlException { @@ -351,6 +388,27 @@ private Object compileAndExecute(String expression, Map cont return exec; } + private Object compileAndExecuteMethod(String expression, Map context, OgnlTask 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 context) throws OgnlException { return compileAndExecute(expression,context,new OgnlTask() { public Object execute(Object tree) throws OgnlException { @@ -365,6 +423,12 @@ private void checkEnableEvalExpression(Object tree, Map context) } } + private void checkSimpleMethod(Object tree, Map 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 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 a0d3f2beda..f8ca5a6fd6 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 @@ -765,6 +765,21 @@ public void testBlockSequenceOfExpressions() throws Exception { 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;