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


The following commit(s) were added to refs/heads/master by this push:
     new d1c0a05  JEXL-361: added a JEXL 3.2 compatibility engine
d1c0a05 is described below

commit d1c0a050e1374f5d7ddf8efba163b11a94a6467e
Author: henrib <[email protected]>
AuthorDate: Mon Mar 14 15:57:16 2022 +0100

    JEXL-361: added a JEXL 3.2 compatibility engine
---
 .../apache/commons/jexl3/internal/Engine32.java    | 143 +++++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/src/main/java/org/apache/commons/jexl3/internal/Engine32.java 
b/src/main/java/org/apache/commons/jexl3/internal/Engine32.java
new file mode 100644
index 0000000..66235b4
--- /dev/null
+++ b/src/main/java/org/apache/commons/jexl3/internal/Engine32.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl3.internal;
+
+
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.JexlOptions;
+import org.apache.commons.jexl3.parser.ASTArrayAccess;
+import org.apache.commons.jexl3.parser.ASTAssignment;
+import org.apache.commons.jexl3.parser.ASTEQNode;
+import org.apache.commons.jexl3.parser.ASTIdentifier;
+import org.apache.commons.jexl3.parser.ASTNENode;
+import org.apache.commons.jexl3.parser.ASTNullpNode;
+import org.apache.commons.jexl3.parser.ASTReference;
+import org.apache.commons.jexl3.parser.ASTTernaryNode;
+import org.apache.commons.jexl3.parser.JexlNode;
+
+/**
+ * An Engine that behaves like JEXL 3.2, bugs included.
+ */
+public class Engine32 extends Engine {
+    public Engine32(final JexlBuilder conf) {
+        super(conf);
+    }
+
+    public Engine32() {
+        super();
+    }
+
+    /**
+     * Static delegation of isTernaryProtected.
+     * @param ii the interpreter (unused)
+     * @param node the node
+     * @return true if node is navigation-safe, false otherwise
+     */
+    static boolean isTernaryProtected(Interpreter ii, JexlNode node) {
+        for (JexlNode walk = node.jjtGetParent(); walk != null; walk = 
walk.jjtGetParent()) {
+            // protect only the condition part of the ternary
+            if (walk instanceof ASTTernaryNode
+                    || walk instanceof ASTNullpNode
+                    || walk instanceof ASTEQNode
+                    || walk instanceof ASTNENode) {
+                return node == walk.jjtGetChild(0);
+            }
+            if (!(walk instanceof ASTReference || walk instanceof 
ASTArrayAccess)) {
+                break;
+            }
+            node = walk;
+        }
+        return false;
+    }
+
+    /**
+     * Static delegation of getVariable.
+     * @param ii the interpreter
+     * @param frame the frame
+     * @param block the scope
+     * @param identifier the variable identifier
+     * @return the variable value
+     */
+    static Object getVariable(Interpreter ii, Frame frame, LexicalScope block, 
ASTIdentifier identifier) {
+        int symbol = identifier.getSymbol();
+        // if we have a symbol, we have a scope thus a frame
+        if (ii.options.isLexicalShade() && identifier.isShaded()) {
+            return ii.undefinedVariable(identifier, identifier.getName());
+        }
+        if (symbol >= 0) {
+            if (frame.has(symbol)) {
+                Object value = frame.get(symbol);
+                if (value != Scope.UNDEFINED) {
+                    return value;
+                }
+            }
+        }
+        String name = identifier.getName();
+        Object value = ii.context.get(name);
+        if (value == null && !ii.context.has(name)) {
+            boolean ignore = (ii.isSafe()
+                    && (symbol >= 0
+                    || identifier.jjtGetParent() instanceof ASTAssignment))
+                    || (identifier.jjtGetParent() instanceof ASTReference);
+            if (!ignore) {
+                return ii.unsolvableVariable(identifier, name, true); // 
undefined
+            }
+        }
+        return value;
+    }
+
+    @Override
+    protected Interpreter createInterpreter(final JexlContext context, final 
Frame frame, final JexlOptions opts) {
+        return new Interpreter(this, opts, context, frame) {
+            @Override
+            protected boolean isStrictOperand(JexlNode node) {
+                return false;
+            }
+
+            @Override
+            protected boolean isTernaryProtected( JexlNode node) {
+                return Engine32.isTernaryProtected(this, node);
+            }
+
+            @Override
+            protected Object getVariable(Frame frame, LexicalScope block, 
ASTIdentifier identifier) {
+                return Engine32.getVariable(this, frame, block, identifier);
+            }
+        };
+    }
+
+    @Override
+    protected Interpreter 
createTemplateInterpreter(TemplateInterpreter.Arguments args) {
+        return new TemplateInterpreter(args) {
+            @Override
+            protected boolean isStrictOperand(JexlNode node) {
+                return false;
+            }
+
+            @Override
+            protected boolean isTernaryProtected( JexlNode node) {
+                return Engine32.isTernaryProtected(this, node);
+            }
+
+            @Override
+            protected Object getVariable(Frame frame, LexicalScope block, 
ASTIdentifier identifier) {
+                return Engine32.getVariable(this, frame, block, identifier);
+            }
+        };
+    }
+}

Reply via email to