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 0d0e583 JEXL-307: fix usage of outer defined var in inner block Task #JEXL-307 - Variable redeclaration option 0d0e583 is described below commit 0d0e58305b87cfe8fe26aa8c8abcf8c351917abd Author: henrib <hen...@apache.org> AuthorDate: Tue Jan 7 15:08:45 2020 +0100 JEXL-307: fix usage of outer defined var in inner block Task #JEXL-307 - Variable redeclaration option --- .../commons/jexl3/internal/InterpreterBase.java | 8 ++- .../java/org/apache/commons/jexl3/LexicalTest.java | 58 +++++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java index 3f4f2d0..75b2d12 100644 --- a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java +++ b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java @@ -254,9 +254,13 @@ public abstract class InterpreterBase extends ParserVisitor { // if we have a symbol, we have a scope thus a frame if (symbol >= 0) { if (frame.has(symbol)) { - if (options.isLexical()) { + if (options.isLexical() && options.isLexicalShade()) { // if not in lexical block, undefined if (in its symbol) shade - if (!block.hasSymbol(symbol) && options.isLexicalShade()) { + LexicalScope b = block; + while(b != null && !b.hasSymbol(symbol)) { + b = b.previous; + } + if (b == null) { return undefinedVariable(identifier, identifier.getName()); } } diff --git a/src/test/java/org/apache/commons/jexl3/LexicalTest.java b/src/test/java/org/apache/commons/jexl3/LexicalTest.java index a87b88b..9b84e04 100644 --- a/src/test/java/org/apache/commons/jexl3/LexicalTest.java +++ b/src/test/java/org/apache/commons/jexl3/LexicalTest.java @@ -580,7 +580,7 @@ public class LexicalTest { return options; } } - + @Test public void testInternalLexicalFeatures() throws Exception { String str = "42"; @@ -636,4 +636,60 @@ public class LexicalTest { JexlOptions.setDefaultFlags("-safe", "+lexical"); } } + + @Test + public void testVarLoop0() throws Exception { + String src = "var count = 10;\n" + + "for (var i : 0 .. count) {\n" + + " $out.println(\"i:\" + i);\n" + + "}"; + runVarLoop(src); + } + + @Test + public void testVarLoop1() throws Exception { + String src = "var count = [0,1];\n" + + "for (var i : count) {\n" + + " $out.println(\"i:\" + i);\n" + + "}"; + runVarLoop(src); + } + + public static class Out { + StringBuilder strb = null; + + public void println(Object o) { + if (o != null) { + if (strb == null) { + strb = new StringBuilder(); + } + strb.append(o.toString()); + } + } + + @Override + public String toString() { + return strb != null ? strb.toString() : ""; + } + } + + private void runVarLoop(String src) throws Exception { + try { + //JexlOptions.setDefaultFlags("-safe", "+lexical", "+lexicalShade"); + VarContext vars = new VarContext(); + JexlOptions options = vars.getEngineOptions(); + options.setLexical(true); + options.setLexicalShade(true); + options.setSafe(false); + JexlEngine jexl = new JexlBuilder().create(); + JexlScript script = jexl.createScript(src); + Out out = new Out(); + vars.set("$out", out); + Object result = script.execute(vars); + } catch(JexlException xany) { + throw xany; + } finally { + //JexlOptions.setDefaultFlags("+safe", "-lexical", "-lexicalSafe"); + } + } }