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 c6fa248  JEXL-306: homogenous behavior for ternary (??, ?:) protected 
conditions; unsolvable or null variable or properties will not generate errors.
c6fa248 is described below

commit c6fa248e6c51c36a61be9d7bc6b6b15d4013875e
Author: Henri Biestro <[email protected]>
AuthorDate: Mon Jun 10 23:07:29 2019 +0200

    JEXL-306: homogenous behavior for ternary (??, ?:) protected conditions; 
unsolvable or null variable or properties will not generate errors.
---
 .../apache/commons/jexl3/internal/Interpreter.java |  6 --
 .../org/apache/commons/jexl3/parser/JexlNode.java  | 40 ----------
 .../org/apache/commons/jexl3/Issues300Test.java    | 38 +++++----
 .../apache/commons/jexl3/PropertyAccessTest.java   | 91 +++++++++-------------
 4 files changed, 56 insertions(+), 119 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 77dd729..6f6fe3c 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -868,9 +868,6 @@ public class Interpreter extends InterpreterBase {
         try {
             condition = node.jjtGetChild(0).jjtAccept(this, data);
         } catch(JexlException.Property xprop) {
-            if (!jexl.safe) {
-                throw xprop;
-            }
             if (logger.isDebugEnabled()) {
                 logger.debug(node, xprop);
             }
@@ -901,9 +898,6 @@ public class Interpreter extends InterpreterBase {
         try {
             lhs = node.jjtGetChild(0).jjtAccept(this, data);
         } catch(JexlException.Property xprop) {
-            if (!jexl.safe) {
-                throw xprop;
-            }
             if (logger.isDebugEnabled()) {
                 logger.debug(node, xprop);
             }
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 a62aa2f..0862965 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
@@ -248,44 +248,4 @@ public abstract class JexlNode extends SimpleNode {
         }
         return false;
     }
-
-    /**
-     * Check if a null evaluated expression is protected by a ternary 
expression.
-     * <p>
-     * The rationale is that the ternary / elvis expressions are meant for the 
user to explictly take control
-     * over the error generation; ie, ternaries can return null even if the 
engine in strict mode
-     * would normally throw an exception.
-     * </p>
-     * @return true if nullable variable, false otherwise
-     */
-    public boolean isTernaryProtected() {
-        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 || walk instanceof 
ASTNullpNode) {
-                if (node.isDescendantOf(walk.jjtGetChild(0))) {
-                    return true;
-                }
-                continue;
-            }
-            if (!(walk instanceof ASTReference || walk instanceof 
ASTArrayAccess)) {
-                break;
-            }
-        }
-        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 78c221b..44ac793 100644
--- a/src/test/java/org/apache/commons/jexl3/Issues300Test.java
+++ b/src/test/java/org/apache/commons/jexl3/Issues300Test.java
@@ -65,7 +65,7 @@ public class Issues300Test {
             }
         }
     }
- 
+
      @Test
     public void testIssue302() throws Exception {
         JexlContext jc = new MapContext();
@@ -82,8 +82,8 @@ public class Issues300Test {
         int oo = ((Number) o).intValue() % 2;
         Assert.assertEquals("Block result is wrong " + str, 0, oo);
         }
-    }  
-    
+    }
+
     @Test
     public void testIssue304() {
         JexlEngine jexlEngine = new JexlBuilder().strict(false).create();
@@ -99,19 +99,19 @@ public class Issues300Test {
         JexlContext context = new MapContext(map);
         Object value = e304.evaluate(context);
         assertEquals("4711", value); // fails
-        
+
         map.clear();
         map.put("overview.limit.var", 42);
         value = e304.evaluate(context);
-        assertEquals(42, value); 
-        
+        assertEquals(42, value);
+
         String allkw = 
"e304.if.else.do.while.new.true.false.null.var.function.empty.size.not.and.or.ne.eq.le.lt.gt.ge";
         map.put(allkw, 42);
         e304 = jexlEngine.createExpression(allkw);
         value = e304.evaluate(context);
-        assertEquals(42, value); 
+        assertEquals(42, value);
     }
-    
+
     @Test
     public void testIssue305() throws Exception {
         JexlEngine jexl = new JexlBuilder().create();
@@ -123,31 +123,29 @@ public class Issues300Test {
         String str1 = e.getParsedText();
         Assert.assertEquals(str0, str1);
     }
-    
+
     @Test
     public void testIssue306() throws Exception {
+        JexlContext ctxt = new MapContext();
         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);
+        ctxt.set("x.y", null);
+        Object o2 = e.execute(ctxt);
         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);
+        Object o = e.execute(null, new Object());
+        Assert.assertEquals(2, o);
+        o = e.execute(null);
         Assert.assertEquals(2, o);
     }
-    
+
     @Test
     public void testIssue306b() throws Exception {
         JexlEngine jexl = new JexlBuilder().create();
@@ -157,7 +155,7 @@ public class Issues300Test {
         Object o2 = e.execute(null);
         Assert.assertEquals(2, o2);
     }
-    
+
     @Test
     public void testIssue306c() throws Exception {
         JexlEngine jexl = new JexlBuilder().safe(true).create();
diff --git a/src/test/java/org/apache/commons/jexl3/PropertyAccessTest.java 
b/src/test/java/org/apache/commons/jexl3/PropertyAccessTest.java
index 4af7a5a..23977c1 100644
--- a/src/test/java/org/apache/commons/jexl3/PropertyAccessTest.java
+++ b/src/test/java/org/apache/commons/jexl3/PropertyAccessTest.java
@@ -322,23 +322,18 @@ public class PropertyAccessTest extends JexlTestCase {
     public void testErroneousIdentifier() throws Exception {
         MapContext ctx = new MapContext();
         JexlEngine engine = new 
JexlBuilder().strict(true).silent(false).create();
-        
+
         // base succeeds
-        String stmt = "(x)->{ x?.class1 ?? 'oops' }";
+        String stmt = "(x)->{ x?.class ?? 'oops' }";
         JexlScript script = engine.createScript(stmt);
         Object result = script.execute(ctx, "querty");
-        Assert.assertEquals("oops", result);
+        Assert.assertEquals("querty".getClass(), result);
 
         // fail with unknown property
-        try {
-            stmt = "(x)->{ x.class1 ?? 'oops' }";
-            script = engine.createScript(stmt);
-            result = script.execute(ctx, "querty");
-            Assert.fail("should have failed!");
-            Assert.assertNull(result); // unreachable
-        } catch (JexlException.Property xjexl) {
-            Assert.assertTrue(xjexl.getMessage().contains("class1"));
-        }
+        stmt = "(x)->{ x.class1 ?? 'oops' }";
+        script = engine.createScript(stmt);
+        result = script.execute(ctx, "querty");
+        Assert.assertEquals("oops", result);
 
         // succeeds with jxlt & strict navigation
         ctx.set("al", "la");
@@ -360,15 +355,10 @@ public class PropertyAccessTest extends JexlTestCase {
         Assert.assertEquals("oops", result);
 
         // fails with jxlt & strict navigation
-        try {
-            stmt = "(x)->{ x.`c${la}ss` ?? 'oops' }";
-            script = engine.createScript(stmt);
-            result = script.execute(ctx, "querty");
-            Assert.assertEquals("oops", result);
-            Assert.fail("should have failed!");
-        } catch (JexlException.Property xjexl) {
-            Assert.assertTrue(xjexl.getMessage().contains("c${la}ss"));
-        }
+        stmt = "(x)->{ x.`c${la}ss` ?? 'oops' }";
+        script = engine.createScript(stmt);
+        result = script.execute(ctx, "querty");
+        Assert.assertEquals("oops", result);
 
         // fails with jxlt & lenient navigation
         stmt = "(x)->{ x?.`c${la--ss` ?? 'oops' }";
@@ -377,17 +367,12 @@ public class PropertyAccessTest extends JexlTestCase {
         Assert.assertEquals("oops", result);
 
         // fails with jxlt & strict navigation
-        try {
-            stmt = "(x)->{ x.`c${la--ss` ?? 'oops' }";
-            script = engine.createScript(stmt);
-            result = script.execute(ctx, "querty");
-            Assert.assertEquals("oops", result);
-            Assert.fail("should have failed!");
-        } catch (JexlException.Property xjexl) {
-            Assert.assertTrue(xjexl.getMessage().contains("c${la--ss"));
-        }
+        stmt = "(x)->{ x.`c${la--ss` ?? 'oops' }";
+        script = engine.createScript(stmt);
+        result = script.execute(ctx, "querty");
+        Assert.assertEquals("oops", result);
     }
-    
+
     @Test
     public void test250() throws Exception {
         MapContext ctx = new MapContext();
@@ -453,17 +438,17 @@ public class PropertyAccessTest extends JexlTestCase {
 
     public static class Prompt {
         private final Map<String, PromptValue> values = new HashMap<String, 
PromptValue>();
-        
+
         public Object get(String name) {
             PromptValue v = values.get(name);
             return v != null? v.getValue() : null;
         }
-        
+
         public void set(String name, Object value) {
             values.put(name, new PromptValue(value));
         }
     }
-    
+
     /**
      * A valued prompt.
      */
@@ -484,7 +469,7 @@ public class PropertyAccessTest extends JexlTestCase {
             this.value = value;
         }
     }
-    
+
     @Test
     public void test275a() throws Exception {
         JexlEngine jexl = new JexlBuilder().strict(true).safe(false).create();
@@ -493,45 +478,45 @@ public class PropertyAccessTest extends JexlTestCase {
         Object result = null;
         Prompt p0 = new Prompt();
         p0.set("stuff", 42);
-        ctxt.set("$in", p0); 
-        
+        ctxt.set("$in", p0);
+
         // unprotected navigation
         script = jexl.createScript("$in[p].intValue()", "p");
         try {
             result = script.execute(ctxt, "fail");
             Assert.fail("should have thrown a " + 
JexlException.Property.class);
         } catch (JexlException xany) {
-            Assert.assertEquals(JexlException.Property.class, 
xany.getClass());            
+            Assert.assertEquals(JexlException.Property.class, xany.getClass());
         }
         Assert.assertEquals(null, result);
         result = script.execute(ctxt, "stuff");
         Assert.assertEquals(42, result);
-       
+
         // protected navigation
         script = jexl.createScript("$in[p]?.intValue()", "p");
         result = script.execute(ctxt, "fail");
         Assert.assertEquals(null, result);
         result = script.execute(ctxt, "stuff");
-        Assert.assertEquals(42, result); 
-        
+        Assert.assertEquals(42, result);
+
         // unprotected navigation
         script = jexl.createScript("$in.`${p}`.intValue()", "p");
         try {
             result = script.execute(ctxt, "fail");
             Assert.fail("should have thrown a " + 
JexlException.Property.class);
         } catch (JexlException xany) {
-            Assert.assertEquals(JexlException.Property.class, 
xany.getClass());            
+            Assert.assertEquals(JexlException.Property.class, xany.getClass());
         }
         result = script.execute(ctxt, "stuff");
         Assert.assertEquals(42, result);
-        
+
         // protected navigation
         script = jexl.createScript("$in.`${p}`?.intValue()", "p");
         result = script.execute(ctxt, "fail");
         Assert.assertEquals(null, result);
         result = script.execute(ctxt, "stuff");
-        Assert.assertEquals(42, result); 
-        
+        Assert.assertEquals(42, result);
+
     }
      @Test
     public void test275b() throws Exception {
@@ -541,31 +526,31 @@ public class PropertyAccessTest extends JexlTestCase {
         Object result = null;
         Prompt p0 = new Prompt();
         p0.set("stuff", 42);
-        ctxt.set("$in", p0); 
-        
+        ctxt.set("$in", p0);
+
         // unprotected navigation
         script = jexl.createScript("$in[p].intValue()", "p");
             result = script.execute(ctxt, "fail");
         Assert.assertEquals(null, result);
-        
+
         result = script.execute(ctxt, "stuff");
         Assert.assertEquals(42, result);
-      
-        
+
+
         // unprotected navigation
         script = jexl.createScript("$in.`${p}`.intValue()", "p");
         result = script.execute(ctxt, "fail");
         Assert.assertEquals(null, result);
         result = script.execute(ctxt, "stuff");
         Assert.assertEquals(42, result);
-        
+
         // protected navigation
         script = jexl.createScript("$in.`${p}`?.intValue()", "p");
         result = script.execute(ctxt, "fail");
         Assert.assertEquals(null, result);
         result = script.execute(ctxt, "stuff");
-        Assert.assertEquals(42, result); 
-        
+        Assert.assertEquals(42, result);
+
     }
 
 }
\ No newline at end of file

Reply via email to