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 2019/11/07 17:32:37 UTC
[commons-jexl] branch master updated: JEXL-307: clean up lexical
frames after usage, fixed for-loops lexical handling (take 2),
added method to change default options in builder,
updated tests to resist default option switch Task #JEXL-307 - Variable
redeclaration option
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 40fd213 JEXL-307: clean up lexical frames after usage, fixed for-loops lexical handling (take 2), added method to change default options in builder, updated tests to resist default option switch Task #JEXL-307 - Variable redeclaration option
40fd213 is described below
commit 40fd2139424f5e07cf1be149e36d2dbbc1c85436
Author: henrib <he...@apache.org>
AuthorDate: Thu Nov 7 18:31:50 2019 +0100
JEXL-307: clean up lexical frames after usage, fixed for-loops lexical handling (take 2), added method to change default options in builder, updated tests to resist default option switch
Task #JEXL-307 - Variable redeclaration option
---
.../java/org/apache/commons/jexl3/JexlBuilder.java | 41 ++++++++++---------
.../org/apache/commons/jexl3/internal/Engine.java | 13 +++---
.../apache/commons/jexl3/internal/Interpreter.java | 33 +++++++++++++--
.../commons/jexl3/internal/LexicalFrame.java | 3 ++
.../org/apache/commons/jexl3/internal/Options.java | 47 +++++++++++++++++++++-
.../org/apache/commons/jexl3/AnnotationTest.java | 28 +++++--------
.../org/apache/commons/jexl3/AntishCallTest.java | 24 +++++------
.../commons/jexl3/ArithmeticOperatorTest.java | 3 +-
.../org/apache/commons/jexl3/Issues200Test.java | 20 +++++----
.../org/apache/commons/jexl3/JexlTestCase.java | 10 ++++-
.../java/org/apache/commons/jexl3/LambdaTest.java | 3 +-
.../java/org/apache/commons/jexl3/LexicalTest.java | 4 +-
.../java/org/apache/commons/jexl3/VarTest.java | 1 +
.../org/apache/commons/jexl3/internal/Util.java | 2 +-
.../commons/jexl3/introspection/SandboxTest.java | 28 ++++++-------
15 files changed, 171 insertions(+), 89 deletions(-)
diff --git a/src/main/java/org/apache/commons/jexl3/JexlBuilder.java b/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
index aa2677e..35c8d5f 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
@@ -74,21 +74,9 @@ public class JexlBuilder {
/** The Log to which all JexlEngine messages will be logged. */
private Log logger = null;
- /**
- * Whether expressions evaluated by this engine will throw exceptions (false) or
- * return null (true) on errors. Default is false.
- */
- private Boolean silent = null;
-
- /** Whether this engine is in lenient or strict mode; if unspecified, use the arithmetic lenient property. */
- private Boolean strict = null;
-
- /** Whether this engine is in tolerant mode. */
- private Boolean safe = false;
-
/** Whether error messages will carry debugging information. */
private Boolean debug = null;
-
+
/** Whether interrupt throws JexlException.Cancel. */
private Boolean cancellable = null;
@@ -121,7 +109,23 @@ public class JexlBuilder {
/** The features. */
private JexlFeatures features = null;
-
+
+ /**
+ * Sets the default (static, shared) option flags.
+ * <p>
+ * Whenever possible, we recommend using JexlBuilder methods to unambiguously instantiate a JEXL
+ * engine; this method should only be used for testing / validation.
+ * <p>A '+flag' or 'flag' will set the option named 'flag' as true, '-flag' set as false.
+ * The possible flag names are:
+ * cancellable, strict, silent, safe, lexical, antish, lexicalShade
+ * <p>Calling JexlBuilder.setDefaultOptions("+safe") once before JEXL engine creation
+ * may ease validating JEXL3.2 in your environment.
+ * @param flags the flags to set
+ */
+ public static void setDefaultOptions(String...flags) {
+ Options.setDefaultFlags(flags);
+ }
+
/**
* Sets the JexlUberspect instance the engine will use.
*
@@ -328,14 +332,13 @@ public class JexlBuilder {
* @return this builder
*/
public JexlBuilder silent(boolean flag) {
- this.silent = flag;
options.setSilent(flag);
return this;
}
/** @return the silent error handling flag */
public Boolean silent() {
- return this.silent;
+ return options.isSilent();
}
/**
@@ -346,14 +349,13 @@ public class JexlBuilder {
* @return this builder
*/
public JexlBuilder strict(boolean flag) {
- this.strict = flag;
options.setStrict(flag);
return this;
}
/** @return true if strict, false otherwise */
public Boolean strict() {
- return this.strict;
+ return options.isStrict();
}
/**
@@ -366,14 +368,13 @@ public class JexlBuilder {
* @return this builder
*/
public JexlBuilder safe(boolean flag) {
- this.safe = flag;
options.setSafe(flag);
return this;
}
/** @return true if safe, false otherwise */
public Boolean safe() {
- return this.safe;
+ return options.isSafe();
}
/**
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Engine.java b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
index 23d14ed..4f19bb5 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Engine.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
@@ -171,9 +171,10 @@ public class Engine extends JexlEngine {
*/
public Engine(JexlBuilder conf) {
// options:
- this.strict = option(conf.strict(), true);
- this.safe = option(conf.safe(), false);
- this.silent = option(conf.silent(), false);
+ JexlOptions opts = conf.options();
+ this.strict = opts.isStrict();
+ this.safe = opts.isSafe();
+ this.silent = opts.isSilent();
this.cancellable = option(conf.cancellable(), !silent && strict);
this.debug = option(conf.debug(), true);
this.collectAll = option(conf.collectAll(), true);
@@ -205,7 +206,7 @@ public class Engine extends JexlEngine {
throw new IllegalArgumentException("uberspect can not be null");
}
// capture options
- this.options = conf.options().copy().set(this);
+ this.options = opts.copy().set(this);
}
@@ -403,7 +404,7 @@ public class Engine extends JexlEngine {
final JexlNode node = script.jjtGetChild(0);
final Frame frame = script.createFrame(bean);
final Interpreter interpreter = createInterpreter(context, frame);
- return node.jjtAccept(interpreter, null);
+ return interpreter.visitLexicalNode(node, null);
} catch (JexlException xjexl) {
if (silent) {
logger.warn(xjexl.getMessage(), xjexl.getCause());
@@ -432,7 +433,7 @@ public class Engine extends JexlEngine {
final JexlNode node = script.jjtGetChild(0);
final Frame frame = script.createFrame(bean, value);
final Interpreter interpreter = createInterpreter(context, frame);
- node.jjtAccept(interpreter, null);
+ interpreter.visitLexicalNode(node, null);
} catch (JexlException xjexl) {
if (silent) {
logger.warn(xjexl.getMessage(), xjexl.getCause());
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 0dbbcfa..ed7efa7 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -671,11 +671,13 @@ public class Interpreter extends InterpreterBase {
ASTReference loopReference = (ASTReference) node.jjtGetChild(0);
ASTIdentifier loopVariable = (ASTIdentifier) loopReference.jjtGetChild(0);
final int symbol = loopVariable.getSymbol();
- final boolean lexical = options.isLexical() && symbol >= 0;
+ final boolean lexical = options.isLexical();// && node.getSymbolCount() > 0;
+ final boolean loopSymbol = symbol >= 0 && loopVariable instanceof ASTVar;
if (lexical) {
// create lexical frame
LexicalFrame locals = new LexicalFrame(frame, block);
- if (!locals.declareSymbol(symbol)) {
+ // it may be a local previously declared
+ if (loopSymbol && !locals.declareSymbol(symbol)) {
return redefinedVariable(node, loopVariable.getName());
}
block = locals;
@@ -694,8 +696,18 @@ public class Interpreter extends InterpreterBase {
? (Iterator<?>) forEach
: uberspect.getIterator(iterableValue);
if (itemsIterator != null) {
+ int cnt = 0;
while (itemsIterator.hasNext()) {
cancelCheck(node);
+ // reset loop varaible
+ if (lexical && cnt++ > 0) {
+ // clean up but remain current
+ block.pop();
+ // unlikely to fail
+ if (loopSymbol && !block.declareSymbol(symbol)) {
+ return redefinedVariable(node, loopVariable.getName());
+ }
+ }
// set loopVariable to value of iterator
Object value = itemsIterator.next();
if (symbol < 0) {
@@ -972,7 +984,22 @@ public class Interpreter extends InterpreterBase {
return true;
}
}
-
+
+ /**
+ * Runs a node.
+ * @param node the node
+ * @param data the usual data
+ * @return the return value
+ */
+ protected Object visitLexicalNode(JexlNode node, Object data) {
+ block = new LexicalFrame(frame, null);
+ try {
+ return node.jjtAccept(this, data);
+ } finally {
+ block = block.pop();
+ }
+ }
+
/**
* Runs a closure.
* @param closure the closure
diff --git a/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java b/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java
index d2b341e..4af5bff 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java
@@ -81,10 +81,12 @@ public class LexicalFrame extends LexicalScope {
clean &= ~(1L << s);
frame.set(s, Scope.UNDEFINED);
}
+ symbols = 0L;
if (moreSymbols != null) {
for (int s = moreSymbols.nextSetBit(0); s != -1; s = moreSymbols.nextSetBit(s + 1)) {
frame.set(s, Scope.UNDEFINED);
}
+ moreSymbols.clear();
}
// restore values of hoisted symbols that were overwritten
if (stack != null) {
@@ -101,4 +103,5 @@ public class LexicalFrame extends LexicalScope {
}
return (LexicalFrame) previous;
}
+
}
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Options.java b/src/main/java/org/apache/commons/jexl3/internal/Options.java
index e2c7529..535a4a0 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Options.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Options.java
@@ -43,8 +43,12 @@ public class Options implements JexlOptions {
protected static final int STRICT = 1;
/** The cancellable bit. */
protected static final int CANCELLABLE = 0;
+ /** The flags names ordered. */
+ private static final String[] NAMES = {
+ "cancellable", "strict", "silent", "safe", "lexical", "antish", "lexicalShade"
+ };
/** Default mask .*/
- protected static final int DEFAULT = 1 /*<< CANCELLABLE*/ | 1 << STRICT | 1 << ANTISH_VAR;
+ protected static int DEFAULT = 1 /*<< CANCELLABLE*/ | 1 << STRICT | 1 << ANTISH_VAR | 1 << SAFE;
/** The arithmetic math context. */
private MathContext mathContext = null;
/** The arithmetic math scale. */
@@ -79,6 +83,47 @@ public class Options implements JexlOptions {
* Default ctor.
*/
public Options() {}
+
+ /**
+ * Sets the default flags.
+ * <p>Used by tests to force default options.
+ * @param flags the flags to set
+ */
+ public static void setDefaultFlags(String...flags) {
+ DEFAULT = parseFlags(DEFAULT, flags);
+ }
+
+ /**
+ * Parses flags by name.
+ * <p>A '+flag' or 'flag' will set flag as true, '-flag' set as false.
+ * The possible flag names are:
+ * cancellable, strict, silent, safe, lexical, antish, lexicalShade
+ * @param mask the initial mask state
+ * @param flags the flags to set
+ * @return the flag mask updated
+ */
+ public static int parseFlags(int mask, String...flags) {
+ for(String name : flags) {
+ boolean b = true;
+ if (name.charAt(0) == '+') {
+ name = name.substring(1);
+ } else if (name.charAt(0) == '-') {
+ name = name.substring(1);
+ b = false;
+ }
+ for(int flag = 0; flag < NAMES.length; ++flag) {
+ if (NAMES[flag].equals(name)) {
+ if (b) {
+ mask |= (1 << flag);
+ } else {
+ mask &= ~(1 << flag);
+ }
+ break;
+ }
+ }
+ }
+ return mask;
+ }
/**
* Set options from engine.
diff --git a/src/test/java/org/apache/commons/jexl3/AnnotationTest.java b/src/test/java/org/apache/commons/jexl3/AnnotationTest.java
index b41eda5..a4aebb5 100644
--- a/src/test/java/org/apache/commons/jexl3/AnnotationTest.java
+++ b/src/test/java/org/apache/commons/jexl3/AnnotationTest.java
@@ -37,8 +37,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void test197a() throws Exception {
JexlContext jc = new MapContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("@synchronized { return 42; }");
+ JexlScript e = JEXL.createScript("@synchronized { return 42; }");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
}
@@ -121,11 +120,10 @@ public class AnnotationTest extends JexlTestCase {
public void testVarStmt() throws Exception {
OptAnnotationContext jc = new OptAnnotationContext();
JexlOptions options = jc.getEngineOptions();
- JexlEngine jexl = new JexlBuilder().strict(true).silent(false).create();
- jc.getEngineOptions().set(jexl);
+ jc.getEngineOptions().set(JEXL);
JexlScript e;
Object r;
- e = jexl.createScript("(s, v)->{ @strict(s) @silent(v) var x = y ; 42; }");
+ e = JEXL.createScript("(s, v)->{ @strict(s) @silent(v) var x = y ; 42; }");
// wont make an error
try {
@@ -163,7 +161,7 @@ public class AnnotationTest extends JexlTestCase {
}
//Assert.assertEquals(42, r);
Assert.assertTrue(options.isStrict());
- e = jexl.createScript("@scale(5) 42;");
+ e = JEXL.createScript("@scale(5) 42;");
r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertTrue(options.isStrict());
@@ -173,8 +171,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void testNoArg() throws Exception {
AnnotationContext jc = new AnnotationContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("@synchronized { return 42; }");
+ JexlScript e = JEXL.createScript("@synchronized { return 42; }");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertEquals(1, jc.getCount());
@@ -184,8 +181,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void testNoArgExpression() throws Exception {
AnnotationContext jc = new AnnotationContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("@synchronized 42");
+ JexlScript e = JEXL.createScript("@synchronized 42");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertEquals(1, jc.getCount());
@@ -195,8 +191,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void testNoArgStatement() throws Exception {
AnnotationContext jc = new AnnotationContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("@synchronized if (true) 2 * 3 * 7; else -42;");
+ JexlScript e = JEXL.createScript("@synchronized if (true) 2 * 3 * 7; else -42;");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertEquals(1, jc.getCount());
@@ -206,8 +201,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void testHoistingStatement() throws Exception {
AnnotationContext jc = new AnnotationContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("var t = 1; @synchronized for(var x : [2,3,7]) t *= x; t");
+ JexlScript e = JEXL.createScript("var t = 1; @synchronized for(var x : [2,3,7]) t *= x; t");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertEquals(1, jc.getCount());
@@ -217,8 +211,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void testOneArg() throws Exception {
AnnotationContext jc = new AnnotationContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("@one(1) { return 42; }");
+ JexlScript e = JEXL.createScript("@one(1) { return 42; }");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertEquals(1, jc.getCount());
@@ -229,8 +222,7 @@ public class AnnotationTest extends JexlTestCase {
@Test
public void testMultiple() throws Exception {
AnnotationContext jc = new AnnotationContext();
- JexlEngine jexl = new JexlBuilder().create();
- JexlScript e = jexl.createScript("@one(1) @synchronized { return 42; }");
+ JexlScript e = JEXL.createScript("@one(1) @synchronized { return 42; }");
Object r = e.execute(jc);
Assert.assertEquals(42, r);
Assert.assertEquals(2, jc.getCount());
diff --git a/src/test/java/org/apache/commons/jexl3/AntishCallTest.java b/src/test/java/org/apache/commons/jexl3/AntishCallTest.java
index 058abb4..5f23b11 100644
--- a/src/test/java/org/apache/commons/jexl3/AntishCallTest.java
+++ b/src/test/java/org/apache/commons/jexl3/AntishCallTest.java
@@ -131,20 +131,19 @@ public class AntishCallTest extends JexlTestCase {
@Test
public void testAntishContextVar() throws Exception {
- JexlEngine jexl = new JexlBuilder().cache(512).strict(true).silent(false).create();
Map<String,Object> lmap = new TreeMap<String,Object>();
- JexlContext jc = new CallSupportContext(lmap).engine(jexl);
- runTestCall(jexl, jc);
+ JexlContext jc = new CallSupportContext(lmap).engine(JEXL);
+ runTestCall(JEXL, jc);
lmap.put("java.math.BigInteger", new ClassReference(java.math.BigInteger.class));
- runTestCall(jexl, jc);
+ runTestCall(JEXL, jc);
lmap.remove("java.math.BigInteger");
- runTestCall(jexl, jc);
+ runTestCall(JEXL, jc);
}
@Test
public void testAntishArithmetic() throws Exception {
CallSupportArithmetic ja = new CallSupportArithmetic(true);
- JexlEngine jexl = new JexlBuilder().cache(512).strict(true).silent(false).arithmetic(ja).create();
+ JexlEngine jexl = new JexlBuilder().cache(512).arithmetic(ja).create();
Map<String,Object> lmap = new TreeMap<String,Object>();
JexlContext jc = new MapContext(lmap);
lmap.put("java.math.BigInteger", java.math.BigInteger.class);
@@ -174,24 +173,23 @@ public class AntishCallTest extends JexlTestCase {
// JEXL-300
@Test
public void testSafeAnt() throws Exception {
- JexlEngine jexl = new JexlBuilder().strict(true).safe(false).create();
JexlContext ctxt = new MapContext();
ctxt.set("x.y.z", 42);
JexlScript script;
Object result;
- script = jexl.createScript("x.y.z");
+ script = JEXL.createScript("x.y.z");
result = script.execute(ctxt);
Assert.assertEquals(42, result);
Assert.assertEquals(42, ctxt.get("x.y.z"));
result = null;
- script = jexl.createScript("x?.y?.z");
+ script = JEXL.createScript("x?.y?.z");
result = script.execute(ctxt);
Assert.assertNull(result); // safe navigation, null
result = null;
- script = jexl.createScript("x?.y?.z = 3");
+ script = JEXL.createScript("x?.y?.z = 3");
try {
result = script.execute(ctxt);
Assert.fail("not antish assign");
@@ -200,7 +198,7 @@ public class AntishCallTest extends JexlTestCase {
}
result = null;
- script = jexl.createScript("x.y?.z");
+ script = JEXL.createScript("x.y?.z");
try {
result = script.execute(ctxt);
Assert.fail("x not defined");
@@ -209,7 +207,7 @@ public class AntishCallTest extends JexlTestCase {
}
result = null;
- script = jexl.createScript("x.y?.z = 3");
+ script = JEXL.createScript("x.y?.z = 3");
try {
result = script.execute(ctxt);
Assert.fail("not antish assign");
@@ -218,7 +216,7 @@ public class AntishCallTest extends JexlTestCase {
}
result = null;
- script = jexl.createScript("x.`'y'`.z = 3");
+ script = JEXL.createScript("x.`'y'`.z = 3");
try {
result = script.execute(ctxt);
Assert.fail("not antish assign");
diff --git a/src/test/java/org/apache/commons/jexl3/ArithmeticOperatorTest.java b/src/test/java/org/apache/commons/jexl3/ArithmeticOperatorTest.java
index c7c051b..342e6d0 100644
--- a/src/test/java/org/apache/commons/jexl3/ArithmeticOperatorTest.java
+++ b/src/test/java/org/apache/commons/jexl3/ArithmeticOperatorTest.java
@@ -33,6 +33,7 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
+import java.util.TimeZone;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -373,7 +374,7 @@ public class ArithmeticOperatorTest extends JexlTestCase {
}
protected Object setDateValue(Date date, String key, Object value) throws Exception {
- Calendar cal = Calendar.getInstance();
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(date);
if ("yyyy".equals(key)) {
cal.set(Calendar.YEAR, toInteger(value));
diff --git a/src/test/java/org/apache/commons/jexl3/Issues200Test.java b/src/test/java/org/apache/commons/jexl3/Issues200Test.java
index 71c0324..80114e4 100644
--- a/src/test/java/org/apache/commons/jexl3/Issues200Test.java
+++ b/src/test/java/org/apache/commons/jexl3/Issues200Test.java
@@ -754,13 +754,17 @@ public class Issues200Test extends JexlTestCase {
+ " $out.add(c);\n"
+ "}\n"
+ " \n"
- + "for(c: ['j','k','l']) {\n"
- + " $out.add(c);\n"
+ + "for(var dc: ['j','k','l']) {\n"
+ + " $out.add(dc);\n"
+ "}"
+ " \n"
+ "$out.size()";
- JexlEngine jexl = new JexlBuilder().safe(false).strict(true).create();
+ JexlFeatures features = new JexlFeatures();
+ features.lexical(true);
+ JexlEngine jexl = new JexlBuilder()
+ //.features(features)
+ .safe(false).strict(true).lexical(true).create();
JexlScript script = jexl.createScript(src);
Object result = script.execute(ctxt, (Object) null);
Assert.assertEquals(6, result);
@@ -778,7 +782,7 @@ public class Issues200Test extends JexlTestCase {
+ "for(b: ['j','k','l']) { $out.add(b);}\n"
+ "$out.size()";
- JexlEngine jexl = new JexlBuilder().safe(false).strict(true).create();
+ JexlEngine jexl = new JexlBuilder().safe(false).strict(true).lexical(false).create();
JexlScript script = jexl.createScript(src);
Object result = script.execute(ctxt, (Object) null);
Assert.assertEquals(6, result);
@@ -813,7 +817,8 @@ public class Issues200Test extends JexlTestCase {
@Test
public void test287() {
- JexlContext ctxt = new MapContext();
+ JexlEvalContext ctxt = new JexlEvalContext();
+ JexlOptions options = ctxt.getEngineOptions();
JexlEngine jexl = new JexlBuilder().strict(true).create();
String src;
JexlScript script;
@@ -834,20 +839,21 @@ public class Issues200Test extends JexlTestCase {
result = script.execute(ctxt);
Assert.assertEquals(42, result);
// definition using shadowed global
+ options.setLexical(false);
src = "(x)->{ if (x==1) { var y = 2; } else if (x==2) { var y = 3; }; y }";
script = jexl.createScript(src);
result = script.execute(ctxt, 1);
Assert.assertEquals(2, result);
result = script.execute(ctxt, 2);
Assert.assertEquals(3, result);
+ options.setSafe(false);
try {
result = script.execute(ctxt, 0);
Assert.fail("should have failed!");
} catch (JexlException.Variable xvar) {
Assert.assertTrue(xvar.getMessage().contains("y"));
}
- jexl = new JexlBuilder().strict(true).safe(true).create();
- script = jexl.createScript(src);
+ options.setSafe(true);
try {
result = script.execute(ctxt, 0);
} catch (JexlException xvar) {
diff --git a/src/test/java/org/apache/commons/jexl3/JexlTestCase.java b/src/test/java/org/apache/commons/jexl3/JexlTestCase.java
index 2662fc7..f8d00d3 100644
--- a/src/test/java/org/apache/commons/jexl3/JexlTestCase.java
+++ b/src/test/java/org/apache/commons/jexl3/JexlTestCase.java
@@ -31,6 +31,12 @@ import org.junit.Assert;
* Eases the implementation of main methods to debug.
*/
public class JexlTestCase {
+ // The default options: all tests where engine must lexicality is
+ // important can be identified by the builder calling lexical(...).
+ static {
+ //JexlBuilder.setDefaultOptions("+safe", "-lexical");
+ JexlBuilder.setDefaultOptions("-safe", "+lexical");
+ }
/** No parameters signature for test run. */
private static final Class<?>[] NO_PARMS = {};
/** String parameter signature for test run. */
@@ -40,7 +46,7 @@ public class JexlTestCase {
protected final JexlEngine JEXL;
public JexlTestCase(String name) {
- this(name, new JexlBuilder().strict(true).silent(false).cache(32).create());
+ this(name, new JexlBuilder().cache(128).create());
}
protected JexlTestCase(String name, JexlEngine jexl) {
@@ -62,7 +68,7 @@ public class JexlTestCase {
}
public static JexlEngine createEngine(boolean lenient) {
- return new JexlBuilder().arithmetic(new JexlArithmetic(!lenient)).cache(512).create();
+ return new JexlBuilder().arithmetic(new JexlArithmetic(!lenient)).cache(128).create();
}
/**
diff --git a/src/test/java/org/apache/commons/jexl3/LambdaTest.java b/src/test/java/org/apache/commons/jexl3/LambdaTest.java
index 03d9339..eb8bf7e 100644
--- a/src/test/java/org/apache/commons/jexl3/LambdaTest.java
+++ b/src/test/java/org/apache/commons/jexl3/LambdaTest.java
@@ -148,7 +148,8 @@ public class LambdaTest extends JexlTestCase {
@Test
public void testHoistLambda() throws Exception {
JexlEngine jexl = createEngine();
- JexlContext ctx = null;
+ JexlEvalContext ctx = new JexlEvalContext();
+ ctx.getEngineOptions().setLexical(false);
JexlScript s42;
Object result;
JexlScript s15;
diff --git a/src/test/java/org/apache/commons/jexl3/LexicalTest.java b/src/test/java/org/apache/commons/jexl3/LexicalTest.java
index 43c59bd..cf8943e 100644
--- a/src/test/java/org/apache/commons/jexl3/LexicalTest.java
+++ b/src/test/java/org/apache/commons/jexl3/LexicalTest.java
@@ -324,7 +324,7 @@ public class LexicalTest {
@Test
public void testLexical6c() throws Exception {
String str = "i = 0; for (var i : [42]) i; i";
- JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create();
+ JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).lexicalShade(false).create();
JexlScript e = jexl.createScript(str);
JexlContext ctxt = new MapContext();
Object o = e.execute(ctxt);
@@ -333,7 +333,7 @@ public class LexicalTest {
@Test
public void testLexical6d() throws Exception {
- String str = "i = 0; for (var i : [42]) i;; i";
+ String str = "i = 0; for (var i : [42]) i; i";
JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).lexicalShade(true).create();
JexlScript e = jexl.createScript(str);
JexlContext ctxt = new MapContext();
diff --git a/src/test/java/org/apache/commons/jexl3/VarTest.java b/src/test/java/org/apache/commons/jexl3/VarTest.java
index 23982b8..7586e77 100644
--- a/src/test/java/org/apache/commons/jexl3/VarTest.java
+++ b/src/test/java/org/apache/commons/jexl3/VarTest.java
@@ -45,6 +45,7 @@ public class VarTest extends JexlTestCase {
JexlContext ctxt = new ReadonlyContext(env, options);
options.setStrict(true);
options.setSilent(false);
+ options.setSafe(false);
JexlScript e;
e = JEXL.createScript("x");
diff --git a/src/test/java/org/apache/commons/jexl3/internal/Util.java b/src/test/java/org/apache/commons/jexl3/internal/Util.java
index 378567b..b7b45a2 100644
--- a/src/test/java/org/apache/commons/jexl3/internal/Util.java
+++ b/src/test/java/org/apache/commons/jexl3/internal/Util.java
@@ -82,7 +82,7 @@ public class Util {
/**
* Creates a list of all descendants of a script including itself.
- * @param script the script to flatten
+ * @param node the script to flatten
* @return the descendants-and-self list
*/
protected static ArrayList<JexlNode> flatten(JexlNode node) {
diff --git a/src/test/java/org/apache/commons/jexl3/introspection/SandboxTest.java b/src/test/java/org/apache/commons/jexl3/introspection/SandboxTest.java
index b6e3116..e50722b 100644
--- a/src/test/java/org/apache/commons/jexl3/introspection/SandboxTest.java
+++ b/src/test/java/org/apache/commons/jexl3/introspection/SandboxTest.java
@@ -131,7 +131,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.black(Foo.class.getName()).execute("");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
script = sjexl.createScript(expr);
try {
@@ -154,7 +154,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.black(Foo.class.getName()).execute("Quux");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
script = sjexl.createScript(expr, "foo");
try {
@@ -177,7 +177,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.black(Foo.class.getName()).read("alias");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
script = sjexl.createScript(expr, "foo");
try {
@@ -200,7 +200,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.black(Foo.class.getName()).write("alias");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
script = sjexl.createScript(expr, "foo", "$0");
try {
@@ -221,7 +221,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox(false);
sandbox.white(Foo.class.getName());
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
jc.set("foo", new CantSeeMe());
script = sjexl.createScript(expr);
@@ -244,7 +244,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.white(Foo.class.getName()).execute("");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
script = sjexl.createScript(expr);
result = script.execute(null);
@@ -260,7 +260,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.white(Foo.class.getName()).execute("Quux");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();
script = sjexl.createScript(expr, "foo");
result = script.execute(null, foo);
@@ -281,7 +281,7 @@ public class SandboxTest extends JexlTestCase {
JexlScript script;
Object result;
- JexlEngine sjexl = new JexlBuilder().strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().strict(true).safe(false).create();
for (String expr : exprs) {
script = sjexl.createScript(expr, "foo");
try {
@@ -307,7 +307,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.white(Foo.class.getName()).read("alias");
sandbox.get(Foo.class.getName()).read().alias("alias", "ALIAS");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).safe(false).strict(true).create();
script = sjexl.createScript(expr, "foo");
result = script.execute(null, foo);
@@ -327,7 +327,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox();
sandbox.white(Foo.class.getName()).write("alias");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).safe(false).strict(true).create();
script = sjexl.createScript(expr, "foo", "$0");
result = script.execute(null, foo, "43");
@@ -345,7 +345,7 @@ public class SandboxTest extends JexlTestCase {
// can not create a new file
sandbox.black(java.io.File.class.getName()).execute("");
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).safe(false).strict(true).create();
String expr;
JexlScript script;
@@ -389,7 +389,7 @@ public class SandboxTest extends JexlTestCase {
JexlSandbox sandbox = new JexlSandbox(false, true);
sandbox.white(java.util.List.class.getName());
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).safe(false).strict(true).create();
JexlScript method = sjexl.createScript("foo.add(y)", "foo", "y");
JexlScript set = sjexl.createScript("foo[x] = y", "foo", "x", "y");
JexlScript get = sjexl.createScript("foo[x]", "foo", "x");
@@ -443,7 +443,7 @@ public class SandboxTest extends JexlTestCase {
sandbox.white(Operation.class.getName());
sandbox.black(Operation.class.getName()).execute("nonCallable");
//sandbox.black(Foo.class.getName()).execute();
- JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).safe(false).strict(true).create();
JexlScript someOp = sjexl.createScript("foo.someOp(y)", "foo", "y");
result = someOp.execute(ctxt, foo, 30);
Assert.assertEquals(42, result);
@@ -482,7 +482,7 @@ public class SandboxTest extends JexlTestCase {
public void testNoJexl312() throws Exception {
JexlContext ctxt = new MapContext();
- JexlEngine sjexl = new JexlBuilder().strict(true).create();
+ JexlEngine sjexl = new JexlBuilder().safe(false).strict(true).create();
JexlScript foo = sjexl.createScript("x.getFoo()", "x");
try {
foo.execute(ctxt, new Foo44());