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 a69782b JEXL-306: attempting behavior harmonization; modified tests
a69782b is described below
commit a69782bea469a766f71f12f76e9d5154b7415be4
Author: henrib <[email protected]>
AuthorDate: Mon Jun 10 18:34:09 2019 +0200
JEXL-306: attempting behavior harmonization; modified tests
---
.../apache/commons/jexl3/internal/Interpreter.java | 41 +++++++++++++++++---
.../org/apache/commons/jexl3/parser/JexlNode.java | 25 ++++++++----
.../org/apache/commons/jexl3/Issues300Test.java | 45 +++++++++++++++++++++-
3 files changed, 98 insertions(+), 13 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 f0aaa66..77dd729 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -864,7 +864,22 @@ public class Interpreter extends InterpreterBase {
@Override
protected Object visit(ASTTernaryNode node, Object data) {
- Object condition = node.jjtGetChild(0).jjtAccept(this, data);
+ Object condition = null;
+ try {
+ condition = node.jjtGetChild(0).jjtAccept(this, data);
+ } catch(JexlException.Property xprop) {
+ if (!jexl.safe) {
+ throw xprop;
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug(node, xprop);
+ }
+ } catch(JexlException.Variable xvar) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(node, xvar);
+ }
+ }
+ // ternary as in "x ? y : z"
if (node.jjtGetNumChildren() == 3) {
if (condition != null && arithmetic.toBoolean(condition)) {
return node.jjtGetChild(1).jjtAccept(this, data);
@@ -872,6 +887,7 @@ public class Interpreter extends InterpreterBase {
return node.jjtGetChild(2).jjtAccept(this, data);
}
}
+ // elvis as in "x ?: z"
if (condition != null && arithmetic.toBoolean(condition)) {
return condition;
} else {
@@ -881,7 +897,22 @@ public class Interpreter extends InterpreterBase {
@Override
protected Object visit(ASTNullpNode node, Object data) {
- Object lhs = node.jjtGetChild(0).jjtAccept(this, data);
+ Object lhs = null;
+ try {
+ lhs = node.jjtGetChild(0).jjtAccept(this, data);
+ } catch(JexlException.Property xprop) {
+ if (!jexl.safe) {
+ throw xprop;
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug(node, xprop);
+ }
+ } catch(JexlException.Variable xvar) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(node, xvar);
+ }
+ }
+ // null elision as in "x ?? z"
return lhs != null? lhs : node.jjtGetChild(1).jjtAccept(this, data);
}
@@ -952,7 +983,7 @@ public class Interpreter extends InterpreterBase {
if (value == null
&& !(node.jjtGetParent() instanceof ASTReference)
&& !(context.has(name))
- && !node.isTernaryProtected()) {
+ /*&& !node.isTernaryProtected()*/) {
return jexl.safe
? null
: unsolvableVariable(node, name, !(node.getSymbol() >=
0 || context.has(name)));
@@ -1025,7 +1056,7 @@ public class Interpreter extends InterpreterBase {
}
@Override
- protected Object visit(ASTReference node, Object data) {
+ protected Object visit(final ASTReference node, Object data) {
cancelCheck(node);
final int numChildren = node.jjtGetNumChildren();
final JexlNode parent = node.jjtGetParent();
@@ -1119,7 +1150,7 @@ public class Interpreter extends InterpreterBase {
}
}
// am I the left-hand side of a safe op ?
- if (object == null && !node.isTernaryProtected()) {
+ if (object == null/* && !node.isTernaryProtected()*/) {
if (ptyNode != null) {
if (ptyNode.isSafeLhs(jexl.safe)) {
return null;
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 092467a..a62aa2f 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
@@ -262,19 +262,30 @@ public abstract class JexlNode extends SimpleNode {
JexlNode node = this;
for (JexlNode walk = node.jjtGetParent(); walk != null; walk =
walk.jjtGetParent()) {
// protect only the condition part of the ternay
- if (walk instanceof ASTTernaryNode && node == walk.jjtGetChild(0))
{
- return true;
- }
- if (walk instanceof ASTNullpNode && node == walk.jjtGetChild(0)) {
- return true;
+ if (walk instanceof ASTTernaryNode || walk instanceof
ASTNullpNode) {
+ if (node.isDescendantOf(walk.jjtGetChild(0))) {
+ return true;
+ }
+ continue;
}
if (!(walk instanceof ASTReference || walk instanceof
ASTArrayAccess)) {
break;
}
- node = walk;
}
return false;
}
-
+ /**
+ * Whether this node is descendant or self of another.
+ * @param asc the (potential) ascendant
+ * @return true if descendant or self, false otherwise
+ */
+ private boolean isDescendantOf(JexlNode asc) {
+ for (JexlNode walk = this; walk != null; walk = walk.jjtGetParent()) {
+ if (walk == asc) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/test/java/org/apache/commons/jexl3/Issues300Test.java
b/src/test/java/org/apache/commons/jexl3/Issues300Test.java
index 65a3b13..78c221b 100644
--- a/src/test/java/org/apache/commons/jexl3/Issues300Test.java
+++ b/src/test/java/org/apache/commons/jexl3/Issues300Test.java
@@ -123,5 +123,48 @@ public class Issues300Test {
String str1 = e.getParsedText();
Assert.assertEquals(str0, str1);
}
-
+
+ @Test
+ public void testIssue306() throws Exception {
+ JexlEngine jexl = new JexlBuilder().create();
+ JexlScript e = jexl.createScript("x.y ?: 2");
+ Object o1 = e.execute(null);
+ Assert.assertEquals(2, o1);
+ Object o2 = e.execute(null);
+ Assert.assertEquals(2, o2);
+ }
+
+ @Test
+ public void testIssue306a() throws Exception {
+ JexlEngine jexl = new JexlBuilder().create();
+ JexlScript e = jexl.createScript("x.y ?: 2", "x");
+ try {
+ Object o = e.execute(null, new Object());
+ Assert.fail(e.toString());
+ } catch (JexlException xany) {
+ Assert.assertTrue(xany.toString().contains("y"));
+ }
+ Object o = e.execute(null);
+ Assert.assertEquals(2, o);
+ }
+
+ @Test
+ public void testIssue306b() throws Exception {
+ JexlEngine jexl = new JexlBuilder().create();
+ JexlScript e = jexl.createScript("x?.y ?: 2", "x");
+ Object o1 = e.execute(null, new Object());
+ Assert.assertEquals(2, o1);
+ Object o2 = e.execute(null);
+ Assert.assertEquals(2, o2);
+ }
+
+ @Test
+ public void testIssue306c() throws Exception {
+ JexlEngine jexl = new JexlBuilder().safe(true).create();
+ JexlScript e = jexl.createScript("x.y ?: 2", "x");
+ Object o = e.execute(null, new Object());
+ Assert.assertEquals(2, o);
+ o = e.execute(null);
+ Assert.assertEquals(2, o);
+ }
}