This is an automated email from the ASF dual-hosted git repository.

henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git

commit d60c3f610420c5326adbbaa885aceabaf19a4363
Author: henrib <[email protected]>
AuthorDate: Thu Jan 10 15:21:31 2019 +0100

    JEXL-279: safe navigation was not working on function call followed by 
array dereference (call()[0])
---
 .../apache/commons/jexl3/internal/Interpreter.java | 23 ++++++++++++++++------
 .../commons/jexl3/internal/InterpreterBase.java    |  2 +-
 .../internal/introspection/MapSetExecutor.java     |  4 ++--
 .../org/apache/commons/jexl3/parser/JexlNode.java  |  3 +++
 4 files changed, 23 insertions(+), 9 deletions(-)

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 ac48721..17a404a 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -1041,6 +1041,16 @@ public class Interpreter extends InterpreterBase {
     }
     
     /**
+     * Checks whether a reference child node holds a function call.
+     * @param node  the reference node
+     * @return true if child is function call, false otherwise
+     */
+    protected boolean isFunctionCall(ASTReference node) {
+        return (node.jjtGetNumChildren() > 0
+                && node.jjtGetChild(0) instanceof ASTFunctionNode);
+    }
+    
+    /**
      * Evaluates an access identifier based on the 2 main implementations;
      * static (name or numbered identifier) or dynamic (jxlt).
      * @param node the identifier access node
@@ -1090,7 +1100,7 @@ public class Interpreter extends InterpreterBase {
         final JexlNode parent = node.jjtGetParent();
         // pass first piece of data in and loop through children
         Object object = null;
-        JexlNode objectNode;
+        JexlNode objectNode = null;
         JexlNode ptyNode = null;
         StringBuilder ant = null;
         boolean antish = !(parent instanceof ASTReference);
@@ -1127,7 +1137,7 @@ public class Interpreter extends InterpreterBase {
                 } else {
                     antish = false;
                 }
-            }
+            } 
             // attempt to evaluate the property within the object 
(visit(ASTIdentifierAccess node))
             object = objectNode.jjtAccept(this, object);
             cancelCheck(node);
@@ -1179,15 +1189,16 @@ public class Interpreter extends InterpreterBase {
                 // am I the left-hand side of a safe op ?
                 return ptyNode.isSafeLhs(jexl.safe)
                        ? null
-                       : unsolvableProperty(node, stringifyProperty(ptyNode), 
false, null);
+                       : unsolvableProperty(node, stringifyProperty(ptyNode), 
ptyNode == objectNode, null);
             }
             if (antish) {
-                String aname = ant != null? ant.toString() : 
stringifyProperty(node);
-                boolean undefined = !(context.has(aname) || 
isLocalVariable(node, 0));
+                String pstr = stringifyProperty(node);
+                String aname = ant != null? ant.toString() : pstr;
+                boolean undefined = !(context.has(aname) || 
isLocalVariable(node, 0) || isFunctionCall(node));
                 // variable unknown in context and not a local
                 return node.isSafeLhs(jexl.safe)
                         ? null
-                        : unsolvableVariable(node, undefined? 
stringifyProperty(node) : aname, undefined);
+                        : unsolvableVariable(node, undefined? pstr : aname, 
undefined);
             }
         }
         return object;
diff --git 
a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java 
b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
index b5d44fc..cc3e975 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
@@ -252,7 +252,7 @@ public abstract class InterpreterBase extends ParserVisitor 
{
             return ((ASTIdentifier) node).getName();
         }
         if (node instanceof ASTReference) {
-            return stringifyPropertyValue(node.jjtGetChild(0));
+            return stringifyProperty(node.jjtGetChild(0));
         }
         return stringifyPropertyValue(node);
     }
diff --git 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java
 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java
index 6a881f8..77180d8 100644
--- 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java
+++ 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/MapSetExecutor.java
@@ -55,10 +55,10 @@ public final class MapSetExecutor extends 
AbstractExecutor.Set {
      * @param key the key to use as 1st argument to the set method
      * @param value the value to use as 2nd argument to the set method
      */
-    private MapSetExecutor(Class<?> clazz, java.lang.reflect.Method method, 
Object key, Object arg) {
+    private MapSetExecutor(Class<?> clazz, java.lang.reflect.Method method, 
Object key, Object value) {
         super(clazz, method);
         property = key;
-        valueClass = classOf(arg);
+        valueClass = classOf(value);
     }
 
     @Override
diff --git a/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java 
b/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
index 2a91f5e..7033178 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
@@ -227,6 +227,9 @@ public abstract class JexlNode extends SimpleNode {
                 && (((ASTIdentifierAccess) rsibling).isSafe() || safe)) {
                 return true;
             }
+            if (rsibling instanceof ASTArrayAccess) {
+                return safe;
+            }
         }
         return false;
     }

Reply via email to