Merge branch 'pr/8'
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 9ef3f8b..67ddfea 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -60,6 +60,8 @@
Bugs Fixed in 3.2:
==================
+* JEXL-281: MethodExecutor incorrectly tests for empty parameters list
+* JEXL-279: Null variables property access do not throw exceptions
* JEXL-278: Ambiguous exceptions should point to actual statement ambiguity
* JEXL-272: Dereferencing null property not reported on method call
* JEXL-271: Hoisted variable is lost when currying lambda
diff --git a/src/main/java/org/apache/commons/jexl3/JexlInfo.java b/src/main/java/org/apache/commons/jexl3/JexlInfo.java
index c0abe07..19a4a72 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlInfo.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlInfo.java
@@ -90,7 +90,8 @@
if (!className.equals(cname)) {
// go deeper if called from jexl implementation classes
if (className.startsWith(pkgname + ".internal.")
- || className.startsWith(pkgname + ".Jexl")) {
+ || className.startsWith(pkgname + ".Jexl")
+ || className.startsWith(pkgname + ".parser")) {
cname = className;
} else {
break;
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
index b9a90cb..9812819 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -2194,6 +2194,13 @@
} else {
antish = false;
}
+ } else if (objectNode instanceof ASTArrayAccess) {
+ if (object == null) {
+ ptyNode = objectNode;
+ break;
+ } else {
+ antish = false;
+ }
}
// attempt to evaluate the property within the object (visit(ASTIdentifierAccess node))
object = objectNode.jjtAccept(this, object);
@@ -2206,14 +2213,10 @@
JexlNode first = node.jjtGetChild(0);
if (first instanceof ASTIdentifier) {
ASTIdentifier afirst = (ASTIdentifier) first;
- if (afirst.getSymbol() < 0) {
- ant = new StringBuilder(afirst.getName());
- } else {
- break main;
- }
+ ant = new StringBuilder(afirst.getName());
} else {
ptyNode = objectNode;
- break main;
+ break;
}
}
for (; v <= c; ++v) {
diff --git a/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java b/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java
index d154ba0..295f446 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodExecutor.java
@@ -70,13 +70,11 @@
super(c, m, k);
int vastart = -1;
Class<?> vaclass = null;
- if (method != null) {
- Class<?>[] formal = method.getParameterTypes();
+ if (MethodKey.isVarArgs(method)) {
// if the last parameter is an array, the method is considered as vararg
- if (formal.length > 0 && MethodKey.isVarArgs(method)) {
- vastart = formal.length - 1;
- vaclass = formal[vastart].getComponentType();
- }
+ Class<?>[] formal = method.getParameterTypes();
+ vastart = formal.length - 1;
+ vaclass = formal[vastart].getComponentType();
}
vaStart = vastart;
vaClass = vaclass;
@@ -153,5 +151,3 @@
return actual;
}
}
-
-
diff --git a/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java b/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
index b0c3cae..1977d14 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/introspection/MethodKey.java
@@ -201,7 +201,7 @@
}
// before climbing up the hierarchy, verify that the last parameter is an array
final Class<?>[] ptypes = method.getParameterTypes();
- if (ptypes.length > 0 && ptypes[ptypes.length - 1].getComponentType() == null) {
+ if (ptypes.length == 0 || ptypes[ptypes.length - 1].getComponentType() == null) {
return false;
}
final String mname = method.getName();
@@ -383,9 +383,11 @@
/* Primitive conversion check. */
if (formal.isPrimitive()) {
Class<?>[] clist = strict ? STRICT_CONVERTIBLES.get(formal) : CONVERTIBLES.get(formal);
- for(int c = 0; c < clist.length; ++c) {
- if (actual == clist[c]) {
- return true;
+ if (clist != null) {
+ for (int c = 0; c < clist.length; ++c) {
+ if (actual == clist[c]) {
+ return true;
+ }
}
}
return false;
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index e2316d4..3dfadb1 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -26,6 +26,12 @@
</properties>
<body>
<release version="3.2" date="unreleased">
+ <action dev="henrib" type="fix" issue="JEXL-281" due-to="Mirek Hankus">
+ MethodExecutor incorrectly tests for empty parameters list
+ </action>
+ <action dev="henrib" type="fix" issue="JEXL-279">
+ Null variables property access do not throw exceptions
+ </action>
<action dev="henrib" type="fix" issue="JEXL-278">
Ambiguous exceptions should point to actual statement ambiguity
</action>
diff --git a/src/test/java/org/apache/commons/jexl3/Issues200Test.java b/src/test/java/org/apache/commons/jexl3/Issues200Test.java
index a6f5011..5b2d2a4 100644
--- a/src/test/java/org/apache/commons/jexl3/Issues200Test.java
+++ b/src/test/java/org/apache/commons/jexl3/Issues200Test.java
@@ -631,4 +631,39 @@
Assert.assertEquals(src, ctls[i], value);
}
}
+
+ @Test
+ public void test279() throws Exception {
+ Object result;
+ JexlScript script;
+ JexlContext ctxt = new MapContext();
+ ctxt.set("y.z", null);
+ ctxt.set("z", null);
+ String[] srcs = new String[]{
+ "var x = null; x[0];",
+ "var x = null; x.0;",
+ "z[0]",
+ "z.0",
+ "y.z[0]",
+ "y.z.0",
+ };
+ for(boolean strict : new boolean[]{ true, false} ) {
+ JexlEngine jexl = new JexlBuilder().safe(false).strict(strict).create();
+ for (String src : srcs) {
+ script = jexl.createScript(src);
+ try {
+ result = script.execute(ctxt);
+ if (strict) {
+ Assert.fail("should have failed: " + src);
+ }
+ // not reachable
+ Assert.assertNull("non-null result ?!", result);
+ } catch (JexlException xany) {
+ if (!strict) {
+ Assert.fail(src + ", should not have thrown " + xany);
+ }
+ }
+ }
+ }
+ }
}