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 2018/12/18 14:02:16 UTC
[commons-jexl] branch master updated: JEXL-280: added stack of loop
counters in parser and tests
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 1a9f28f JEXL-280: added stack of loop counters in parser and tests
1a9f28f is described below
commit 1a9f28fb6992c641af1c12531716e18dcde4fad6
Author: henrib <he...@apache.org>
AuthorDate: Tue Dec 18 15:01:52 2018 +0100
JEXL-280: added stack of loop counters in parser and tests
---
RELEASE-NOTES.txt | 1 +
.../apache/commons/jexl3/parser/JexlParser.java | 19 +++++++++++++++++
.../org/apache/commons/jexl3/parser/Parser.jjt | 14 +++++++------
src/site/xdoc/changes.xml | 3 +++
.../java/org/apache/commons/jexl3/DoWhileTest.java | 24 +++++++++++++++++++++-
5 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 4ae8c28..97ba55c 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -62,6 +62,7 @@ Bugs Fixed in 3.2:
* JEXL-282: Pragmas with antish names are broken
* JEXL-281: MethodExecutor incorrectly tests for empty parameters list
+* JEXL-280: break/continue statements outside of the loop
* JEXL-279: Null variables property access do not throw exceptions
* JEXL-278: Ambiguous exceptions should point to actual statement ambiguity
* JEXL-272: Dereferencing null property not reported on method call
diff --git a/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java b/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
index 61756ea..39c2cee 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
@@ -28,8 +28,10 @@ import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
@@ -65,6 +67,15 @@ public abstract class JexlParser extends StringParser {
* The list of pragma declarations.
*/
protected Map<String, Object> pragmas = null;
+ /**
+ * The number of imbricated loops.
+ */
+ protected int loopCount = 0;
+ /**
+ * Stack of parsing loop counts.
+ */
+ protected Queue<Integer> loopCounts = null;
+
/**
* Utility function to create '.' separated string from a list of string.
@@ -156,6 +167,11 @@ public abstract class JexlParser extends StringParser {
frames.push(frame);
}
frame = new Scope(frame, (String[]) null);
+ if (loopCounts == null) {
+ loopCounts = new LinkedList<Integer>();
+ }
+ loopCounts.add(loopCount);
+ loopCount = 0;
}
/**
@@ -167,6 +183,9 @@ public abstract class JexlParser extends StringParser {
} else {
frame = null;
}
+ if (loopCounts != null && !loopCounts.isEmpty()) {
+ loopCount = loopCounts.remove();
+ }
}
/**
diff --git a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
index d2589e2..c54f2ce 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
+++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
@@ -44,8 +44,6 @@ import org.apache.commons.jexl3.internal.Scope;
public final class Parser extends JexlParser
{
- private int loopCount = 0;
-
public ASTJexlScript parse(JexlInfo jexlInfo, JexlFeatures jexlFeatures, String jexlSrc, Scope scope) {
JexlFeatures previous = getFeatures();
try {
@@ -364,14 +362,18 @@ void ReturnStatement() : {}
<RETURN> ExpressionStatement()
}
-void Continue() #Continue : {}
+void Continue() #Continue : {
+ Token t;
+}
{
- <CONTINUE> { if (loopCount == 0) { throwParsingException(jjtThis); } }
+ t=<CONTINUE> { if (loopCount == 0) { throwParsingException(null, t); } }
}
-void Break() #Break : {}
+void Break() #Break : {
+ Token t;
+}
{
- <BREAK> { if (loopCount == 0) { throwParsingException(jjtThis); } }
+ t=<BREAK> { if (loopCount == 0) { throwParsingException(null, t); } }
}
void ForeachStatement() : {}
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index 0de4bc0..91a8d08 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -32,6 +32,9 @@
<action dev="henrib" type="fix" issue="JEXL-281" due-to="Mirek Hankus">
MethodExecutor incorrectly tests for empty parameters list
</action>
+ <action dev="henrib" type="fix" issue="JEXL-280" due-to="Dmitri Blinov">
+ break/continue statements outside of the loop
+ </action>
<action dev="henrib" type="fix" issue="JEXL-279">
Null variables property access do not throw exceptions
</action>
diff --git a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
index b712821..7260363 100644
--- a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
+++ b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.jexl3;
+import org.apache.commons.jexl3.internal.Debugger;
import org.junit.Assert;
import org.junit.Test;
@@ -77,5 +78,26 @@ public class DoWhileTest extends JexlTestCase {
Assert.assertEquals("x is wrong", new Integer(10), jc.get("x"));
Assert.assertEquals("y is wrong", new Integer(512), jc.get("y"));
}
-
+
+ @Test
+ public void testForEachBreakInsideFunction() throws Exception {
+ try {
+ JexlScript e = JEXL.createScript("for (i : 1..2) { y = function() { break; } }");
+ Assert.fail("break is out of loop!");
+ } catch (JexlException.Parsing xparse) {
+ String str = xparse.detailedMessage();
+ Assert.assertTrue(str.contains("break"));
+ }
+ }
+
+ @Test
+ public void testForEachContinueInsideFunction() throws Exception {
+ try {
+ JexlScript e = JEXL.createScript("for (i : 1..2) { y = function() { continue; } }");
+ Assert.fail("continue is out of loop!");
+ } catch (JexlException.Parsing xparse) {
+ String str = xparse.detailedMessage();
+ Assert.assertTrue(str.contains("continue"));
+ }
+ }
}