You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2017/12/04 11:32:55 UTC

svn commit: r1817082 - in /commons/proper/jexl/trunk: ./ src/main/java/org/apache/commons/jexl3/internal/ src/site/xdoc/ src/test/java/org/apache/commons/jexl3/ src/test/java/org/apache/commons/jexl3/scripting/

Author: henrib
Date: Mon Dec  4 11:32:54 2017
New Revision: 1817082

URL: http://svn.apache.org/viewvc?rev=1817082&view=rev
Log:
JEXL-245:
Better handling of null properties during de-referencing

Modified:
    commons/proper/jexl/trunk/RELEASE-NOTES.txt
    commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
    commons/proper/jexl/trunk/src/site/xdoc/changes.xml
    commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java
    commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineOptionalTest.java

Modified: commons/proper/jexl/trunk/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/RELEASE-NOTES.txt?rev=1817082&r1=1817081&r2=1817082&view=diff
==============================================================================
--- commons/proper/jexl/trunk/RELEASE-NOTES.txt (original)
+++ commons/proper/jexl/trunk/RELEASE-NOTES.txt Mon Dec  4 11:32:54 2017
@@ -39,6 +39,8 @@ New Features in 3.2:
 
 Bugs Fixed in 3.2:
 ==================
+
+* JEXL-245:      Engine in strict mode fails to fail on unsolvable variables or properties
 * JEXL-244:      Webapp classloader memory leaks
 * JEXL-241:      NPE when script containing string interpolation executed in multiple threads
 * JEXL-240:      Unable to invoke a call operator using antish style variable resolution

Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java?rev=1817082&r1=1817081&r2=1817082&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java Mon Dec  4 11:32:54 2017
@@ -1015,9 +1015,9 @@ public class Interpreter extends Interpr
         // pass first piece of data in and loop through children
         Object object = null;
         JexlNode objectNode;
+        JexlNode ptyNode = null;
         StringBuilder ant = null;
         boolean antish = !(parent instanceof ASTReference);
-        boolean pty = true;
         int v = 1;
         main:
         for (int c = 0; c < numChildren; c++) {
@@ -1060,7 +1060,7 @@ public class Interpreter extends Interpr
                             break;
                         }
                     } else {
-                        pty = false;
+                        ptyNode = objectNode;
                         break;
                     }
                 }
@@ -1075,7 +1075,9 @@ public class Interpreter extends Interpr
                 }
                 object = context.get(ant.toString());
             } else {
-                break;
+                // the last one may be null
+                ptyNode = c != numChildren - 1? objectNode : null;
+                break; //
             }
         }
         if (object == null && !isTernaryProtected(node)) {
@@ -1083,8 +1085,8 @@ public class Interpreter extends Interpr
                 boolean undefined = !(context.has(ant.toString()) || isLocalVariable(node, 0));
                 // variable unknown in context and not a local
                 return unsolvableVariable(node, ant.toString(), undefined);
-            } else if (!pty) {
-                return unsolvableProperty(node, "<null>.<?>", null);
+            } else if (ptyNode != null) {
+                return unsolvableProperty(node, ptyNode != null? ptyNode.toString() : "<null>.<?>", null);
             }
         }
         return object;

Modified: commons/proper/jexl/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/site/xdoc/changes.xml?rev=1817082&r1=1817081&r2=1817082&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/jexl/trunk/src/site/xdoc/changes.xml Mon Dec  4 11:32:54 2017
@@ -26,6 +26,9 @@
     </properties>
     <body>
         <release version="3.2" date="unreleased">
+            <action dev="henrib" type="fix" issue="JEXL-245" due-to="Ate Douma">
+                Engine in strict mode fails to fail on unsolvable variables or properties
+            </action>
             <action dev="henrib" type="fix" issue="JEXL-244" due-to="Dmitri Blinov">
                 Webapp classloader memory leaks
             </action>

Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java?rev=1817082&r1=1817081&r2=1817082&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/IssuesTest200.java Mon Dec  4 11:32:54 2017
@@ -246,9 +246,7 @@ public class IssuesTest200 extends JexlT
     private static void handle(ExecutorService pool, final JexlScript script, final Map<String, Object> payload) {
        pool.submit(new Runnable() {
             @Override public void run() {
-                System.out.printf("START: %s\n", Thread.currentThread());
-                System.out.println(script.execute(new MapContext(payload)));
-                System.out.printf("STOP: %s\n", Thread.currentThread());
+                script.execute(new MapContext(payload));
             }
         });
     }
@@ -300,4 +298,49 @@ public class IssuesTest200 extends JexlT
             // ok
         }
     }
+
+    public static class Foo245 {
+        private Object bar = null;
+
+        void setBar(Object bar) {
+            this.bar = bar;
+        }
+
+        public Object getBar() {
+            return bar;
+        }
+    }
+
+    @Test
+    public void test245() throws Exception {
+        MapContext ctx = new MapContext();
+        Foo245 foo245 = new Foo245();
+        ctx.set("foo", foo245);
+
+        JexlEngine engine = new JexlBuilder().strict(true).silent(false).create();
+        JexlExpression foobar = engine.createExpression("foo.bar");
+        JexlExpression foobaz = engine.createExpression("foo.baz");
+        JexlExpression foobarbaz = engine.createExpression("foo.bar.baz");
+        // add ambiguity with null & not-null
+        Object[] args = { null, 245 };
+        for(Object arg : args ){
+            foo245.setBar(arg);
+            // ok
+            Assert.assertEquals(foo245.getBar(), foobar.evaluate(ctx));
+            // fail level 1
+            try {
+                foobaz.evaluate(ctx);
+                Assert.fail("foo.baz is not solvable");
+            } catch(JexlException xp) {
+                Assert.assertTrue(xp instanceof JexlException.Property);
+            }
+            // fail level 2
+            try {
+                foobarbaz.evaluate(ctx);
+                Assert.fail("foo.bar.baz is not solvable");
+            } catch(JexlException xp) {
+                Assert.assertTrue(xp instanceof JexlException.Property);
+            }
+        }
+    }
 }

Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineOptionalTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineOptionalTest.java?rev=1817082&r1=1817081&r2=1817082&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineOptionalTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/scripting/JexlScriptEngineOptionalTest.java Mon Dec  4 11:32:54 2017
@@ -24,37 +24,41 @@ import javax.script.CompiledScript;
 
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
-import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
 
-public class JexlScriptEngineOptionalTest extends TestCase {
+public class JexlScriptEngineOptionalTest {
     private final JexlScriptEngineFactory factory = new JexlScriptEngineFactory();
     private final ScriptEngineManager manager = new ScriptEngineManager();
     private final ScriptEngine engine = manager.getEngineByName("jexl");
 
+    @Test
     public void testOutput() throws Exception {
         String output = factory.getOutputStatement("foo\u00a9bar");
-        assertEquals("JEXL.out.print('foo\\u00a9bar')", output);
+        Assert.assertEquals("JEXL.out.print('foo\\u00a9bar')", output);
         // redirect output to capture evaluation result
         final StringWriter outContent = new StringWriter();
         engine.getContext().setWriter(outContent);
         engine.eval(output);
-        assertEquals("foo\u00a9bar", outContent.toString());
+        Assert.assertEquals("foo\u00a9bar", outContent.toString());
     }
 
+    @Test
     public void testError() throws Exception {
         String error = "JEXL.err.print('ERROR')";
         // redirect error to capture evaluation result
         final StringWriter outContent = new StringWriter();
         engine.getContext().setErrorWriter(outContent);
         engine.eval(error);
-        assertEquals("ERROR", outContent.toString());
+        Assert.assertEquals("ERROR", outContent.toString());
     }
 
+    @Test
     public void testCompilable() throws Exception {
-        assertTrue("Engine should implement Compilable", engine instanceof Compilable);
+        Assert.assertTrue("Engine should implement Compilable", engine instanceof Compilable);
         Compilable cengine = (Compilable) engine;
         CompiledScript script = cengine.compile("40 + 2");
-        assertEquals(Integer.valueOf(42), script.eval());
-        assertEquals(Integer.valueOf(42), script.eval());
+        Assert.assertEquals(Integer.valueOf(42), script.eval());
+        Assert.assertEquals(Integer.valueOf(42), script.eval());
     }
 }