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);
+ }
+ };
+ }
+}