Skip to content

Commit

Permalink
avoid infinite loop on ASM optimizer
Browse files Browse the repository at this point in the history
Caused when accessing the element of an element of a null collection.
See the new unit tests testInfiniteLoopWithASMOptimizer() and
testInfiniteLoopWithASMOptimizerAO() for details
  • Loading branch information
jlopez committed Oct 14, 2015
1 parent 430bc8a commit a7b64ed
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1357,15 +1357,9 @@ private Object getCollectionProperty(Object ctx, String prop)
}

currType = null;
if (ctx == null) return null;

assert debug("\n ** ENTER -> {collection:<<" + prop + ">>; ctx=" + ctx + "}");

if (first) {
assert debug("ALOAD 1");
mv.visitVarInsn(ALOAD, 1);
}

int start = ++cursor;

skipWhitespace();
Expand All @@ -1380,6 +1374,12 @@ private Object getCollectionProperty(Object ctx, String prop)

assert debug("{collection token: [" + tk + "]}");

if (ctx == null) return null;
if (first) {
assert debug("ALOAD 1");
mv.visitVarInsn(ALOAD, 1);
}

ExecutableStatement compiled = (ExecutableStatement) subCompileExpression(tk.toCharArray(), pCtx);
Object item = compiled.getValue(ctx, variableFactory);

Expand Down Expand Up @@ -1514,7 +1514,6 @@ private Object getCollectionPropertyAO(Object ctx, String prop)
}

currType = null;
if (ctx == null) return null;

assert debug("\n ** ENTER -> {collection:<<" + prop + ">>; ctx=" + ctx + "}");

Expand All @@ -1532,6 +1531,8 @@ private Object getCollectionPropertyAO(Object ctx, String prop)

assert debug("{collection token:<<" + tk + ">>}");

if (ctx == null) return null;

ExecutableStatement compiled = (ExecutableStatement) subCompileExpression(tk.toCharArray());
Object item = compiled.getValue(ctx, variableFactory);

Expand Down
37 changes: 36 additions & 1 deletion src/test/java/org/mvel2/tests/core/PropertyAccessTests.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.mvel2.tests.core;

import org.mvel2.CompileException;
import org.mvel2.MVEL;
import org.mvel2.ParserContext;
import org.mvel2.integration.PropertyHandler;
Expand All @@ -18,6 +19,13 @@


public class PropertyAccessTests extends AbstractTest {
protected void setUp() throws Exception {
super.setUp();
// Ensure MVEL settings are not leaked across tests
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false;
OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC);
}

public void testSingleProperty() {
assertEquals(false, test("fun"));
}
Expand Down Expand Up @@ -358,6 +366,7 @@ public Map<String, Object> getMap() {
}

public void testMVEL226() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
A226 a = new A226();
Map m = Collections.singletonMap("a", a);
Map<String, Object> nestMap = Collections.<String, Object>singletonMap("foo", "bar");
Expand All @@ -380,6 +389,27 @@ public void testMVEL226() {
a.map = nestMap;
assertEquals("bar", MVEL.executeExpression(s, m));
}

private void infiniteLoop() {
try {
Serializable compiled = MVEL.compileExpression("a['b']['c']");
Map<String, Object> vars = Collections.singletonMap("a", (Object)Collections.emptyMap());
MVEL.executeExpression(compiled, vars);
fail("expected exception");
} catch(CompileException t) {
}
}

public void testInfiniteLoopWithASMOptimizer() {
OptimizerFactory.setDefaultOptimizer("ASM");
infiniteLoop();
}

public void testInfiniteLoopWithASMOptimizerAO() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
OptimizerFactory.setDefaultOptimizer("ASM");
infiniteLoop();
}

public void testInfiniteLoop() {
A226 a = new A226();
Expand All @@ -393,7 +423,12 @@ public void testInfiniteLoop() {
// ignore
}
}


public void testInfiniteLoopAO() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
testInfiniteLoop();
}

public void testNonHashMapImplMapPutMVEL302() {
test("map=new java.util.Hashtable();map.foo='bar'");
}
Expand Down

0 comments on commit a7b64ed

Please sign in to comment.