Merge pull request #504 from davoustp/master

Cache all OGNL expressions (when enabled) irrespective of their execution status [Fixes WW-5147]
Close #503
This commit is contained in:
Lukasz Lenart
2021-11-16 09:37:52 +01:00
committed by GitHub
2 changed files with 44 additions and 12 deletions
@@ -536,18 +536,14 @@ public class OgnlUtil {
if (tree == null) {
tree = Ognl.parseExpression(expression);
checkEnableEvalExpression(tree, context);
expressions.putIfAbsent(expression, tree);
}
} else {
tree = Ognl.parseExpression(expression);
checkEnableEvalExpression(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;
return task.execute(tree);
}
private <T> Object compileAndExecuteMethod(String expression, Map<String, Object> context, OgnlTask<T> task) throws OgnlException {
@@ -557,18 +553,14 @@ public class OgnlUtil {
if (tree == null) {
tree = Ognl.parseExpression(expression);
checkSimpleMethod(tree, context);
expressions.putIfAbsent(expression, tree);
}
} 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;
return task.execute(tree);
}
public Object compile(String expression, Map<String, Object> context) throws OgnlException {
@@ -128,6 +128,46 @@ public class OgnlUtilTest extends XWorkTestCase {
assertSame(expr0, expr2);
}
public void testExpressionIsCachedIrrespectiveOfItsExecutionStatus() throws OgnlException {
Foo foo = new Foo();
OgnlContext context = (OgnlContext) ognlUtil.createDefaultContext(foo);
// Expression which executes with success
try {
ognlUtil.getValue("@com.opensymphony.xwork2.ognl.OgnlUtilTest@STATIC_FINAL_PUBLIC_ATTRIBUTE", context, foo);
assertEquals("Successfully executed expression must have been cached", ognlUtil.expressionCacheSize(), 1);
} catch (Exception ex) {
fail("Expression execution should have succeeded here. Exception: " + ex);
}
// Expression which executes with failure
try {
ognlUtil.getValue("@com.opensymphony.xwork2.ognl.OgnlUtilTest@STATIC_PRIVATE_ATTRIBUTE", context, foo);
fail("Expression execution should have failed here");
} catch (Exception ex) {
assertEquals("Expression with failed execution must have been cached nevertheless", ognlUtil.expressionCacheSize(), 2);
}
}
public void testMethodExpressionIsCachedIrrespectiveOfItsExecutionStatus() throws Exception {
Foo foo = new Foo();
OgnlContext context = (OgnlContext) ognlUtil.createDefaultContext(foo);
// Method expression which executes with success
try {
ognlUtil.callMethod("getBar()", context, foo);
assertTrue("Successfully executed method expression must have been cached", ognlUtil.expressionCacheSize() == 1);
} catch (Exception ex) {
fail("Method expression execution should have succeeded here. Exception: " + ex);
}
// Method expression which executes with failure
try {
ognlUtil.callMethod("getNonExistingMethod()", context, foo);
fail("Expression execution should have failed here");
} catch (Exception ex) {
assertEquals("Method expression with failed execution must have been cached nevertheless", ognlUtil.expressionCacheSize(), 2);
}
}
public void testClearExpressionCache() throws OgnlException {
ognlUtil.setEnableExpressionCache("true");
// Test that the expression cache is functioning as expected.