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 2020/01/17 15:48:38 UTC

[commons-jexl] 01/02: JEXL-321: do/while with empty statement contributed fix Task #JEXL-321 - Empty do-while loop is broken

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

commit a70b3d8a75d5805a6daeedcf80ff44bf8b8cb276
Author: henrib <he...@apache.org>
AuthorDate: Fri Jan 17 16:43:00 2020 +0100

    JEXL-321: do/while with empty statement contributed fix
    Task #JEXL-321 - Empty do-while loop is broken
---
 RELEASE-NOTES.txt                                  |  1 +
 .../apache/commons/jexl3/internal/Debugger.java    | 13 +++++----
 .../apache/commons/jexl3/internal/Interpreter.java | 32 +++++++++++-----------
 src/site/xdoc/changes.xml                          |  3 ++
 .../java/org/apache/commons/jexl3/DoWhileTest.java | 32 ++++++++++++++++++++++
 5 files changed, 59 insertions(+), 22 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 7950413..f2aab63 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -74,6 +74,7 @@ New Features in 3.2:
 
 Bugs Fixed in 3.2:
 ==================
+* JEXL-321:      Empty do-while loop is broken
 * JEXL-318:      Annotation processing may fail in lexical mode
 * JEXL-315:      JxltEngine literal string strings ending in \ $ or # throw JxltEngine$Exception
 * JEXL-314:      Comparison NULL values of variables NAME1.NAME2
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
index 43339f9..0312c50 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
@@ -1003,13 +1003,14 @@ public class Debugger extends ParserVisitor implements JexlInfo.Detail {
     @Override
     protected Object visit(ASTDoWhileStatement node, Object data) {
         builder.append("do ");
-
-        acceptStatement(node.jjtGetChild(0), data);
-
+        int nc = node.jjtGetNumChildren();
+        if (nc > 1) {
+            acceptStatement(node.jjtGetChild(0), data);
+        } else {
+            builder.append(";");
+        }
         builder.append(" while (");
-
-        accept(node.jjtGetChild(1), data);
-
+        accept(node.jjtGetChild(nc - 1), data);
         builder.append(")");
         return data;
     }
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 563877f..8b116b0 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -747,9 +747,9 @@ public class Interpreter extends InterpreterBase {
     @Override
     protected Object visit(ASTWhileStatement node, Object data) {
         Object result = null;
-        /* first objectNode is the expression */
-        Node expressionNode = node.jjtGetChild(0);
-        while (arithmetic.toBoolean(expressionNode.jjtAccept(this, data))) {
+        /* first objectNode is the condition */
+        Node condition = node.jjtGetChild(0);
+        while (arithmetic.toBoolean(condition.jjtAccept(this, data))) {
             cancelCheck(node);
             if (node.jjtGetNumChildren() > 1) {
                 try {
@@ -768,22 +768,22 @@ public class Interpreter extends InterpreterBase {
     @Override
     protected Object visit(ASTDoWhileStatement node, Object data) {
         Object result = null;
-        /* last objectNode is the expression */
-        Node expressionNode = node.jjtGetChild(1);
+        int nc = node.jjtGetNumChildren();
+        /* last objectNode is the condition */
+        Node condition = node.jjtGetChild(nc - 1);
         do {
             cancelCheck(node);
-
-            try {
-                // execute statement
-                result = node.jjtGetChild(0).jjtAccept(this, data);
-            } catch (JexlException.Break stmtBreak) {
-                break;
-            } catch (JexlException.Continue stmtContinue) {
-                //continue;
+            if (nc > 1) {
+                try {
+                    // execute statement
+                    result = node.jjtGetChild(0).jjtAccept(this, data);
+                } catch (JexlException.Break stmtBreak) {
+                    break;
+                } catch (JexlException.Continue stmtContinue) {
+                    //continue;
+                }
             }
-
-        } while (arithmetic.toBoolean(expressionNode.jjtAccept(this, data)));
-
+        } while (arithmetic.toBoolean(condition.jjtAccept(this, data)));
         return result;
     }
 
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index 20480fd..db4d582 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -26,6 +26,9 @@
     </properties>
     <body>
         <release version="3.2" date="unreleased">
+            <action dev="henrib" type="fix" issue="JEXL-321" due-to="Dmitri Blinov">
+                Empty do-while loop is broken
+            </action>
             <action dev="henrib" type="fix" issue="JEXL-318" due-to="Dmitri Blinov">
                 Annotation processing may fail in lexical mode
             </action>
diff --git a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
index c29b853..9c017f5 100644
--- a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
+++ b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
@@ -105,4 +105,36 @@ public class DoWhileTest extends JexlTestCase {
         JexlScript e = JEXL.createScript("(x)->{ for (i : 1..2) {  continue; var y = function() { 42; } break; } }");
         Assert.assertNotNull(e);
     }
+    
+    @Test
+    public void testEmptyBody() throws Exception {
+        JexlScript e = JEXL.createScript("var i = 0; do ; while((i+=1) < 10); i");
+        JexlContext jc = new MapContext();
+        Object o = e.execute(jc);
+        Assert.assertEquals(10, o);       
+    }
+    
+    @Test
+    public void testEmptyStmtBody() throws Exception {
+        JexlScript e = JEXL.createScript("var i = 0; do {} while((i+=1) < 10); i");
+        JexlContext jc = new MapContext();
+        Object o = e.execute(jc);
+        Assert.assertEquals(10, o);       
+    } 
+        
+    @Test
+    public void testWhileEmptyBody() throws Exception {
+        JexlScript e = JEXL.createScript("var i = 0; while((i+=1) < 10); i");
+        JexlContext jc = new MapContext();
+        Object o = e.execute(jc);
+        Assert.assertEquals(10, o);       
+    }
+    
+    @Test
+    public void testWhileEmptyStmtBody() throws Exception {
+        JexlScript e = JEXL.createScript("var i = 0; while((i+=1) < 10) {}; i");
+        JexlContext jc = new MapContext();
+        Object o = e.execute(jc);
+        Assert.assertEquals(10, o);       
+    }
 }