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/07 14:10:57 UTC

[commons-jexl] branch master updated: JEXL-307: fix usage of outer defined var in inner block 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 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 <he...@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");
+        }
+    }
 }