This is an automated email from the ASF dual-hosted git repository. henrib pushed a commit to branch JEXL-369 in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/JEXL-369 by this push: new e227afaf JEXL-369: disable single-statement variable declarations in lexical mode e227afaf is described below commit e227afaf124b29e959d0a881a97ae6d79e08b714 Author: henrib <hen...@apache.org> AuthorDate: Sun May 8 19:16:48 2022 +0200 JEXL-369: disable single-statement variable declarations in lexical mode --- .../org/apache/commons/jexl3/parser/Parser.jjt | 21 ++++-- .../java/org/apache/commons/jexl3/LexicalTest.java | 75 +++++++++++++++++++--- 2 files changed, 81 insertions(+), 15 deletions(-) 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 04c22a79..05eca5ad 100644 --- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt +++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt @@ -348,6 +348,13 @@ void AnnotatedStatement() #AnnotatedStatement : {} } void Statement() #void : {} +{ + LOOKAHEAD(<LET>|<CONST>|<VAR>) Var() + | + StatementNoVar() +} + +void StatementNoVar() #void : {} { <SEMICOL> | LOOKAHEAD(<ANNOTATION>) AnnotatedStatement() @@ -360,7 +367,7 @@ void Statement() #void : {} | ReturnStatement() | Continue() | Break() - | Var() + | LOOKAHEAD(<VAR>, {!getFeatures().isLexical()} ) Var() | Pragma() } @@ -378,19 +385,19 @@ void ExpressionStatement() #void : {} void IfStatement() : {} { - <IF> <LPAREN> Expression() <RPAREN> (LOOKAHEAD(1) Block() | Statement()) - ( LOOKAHEAD(2) <ELSE> <IF> <LPAREN> Expression() <RPAREN> (LOOKAHEAD(1) Block() | Statement()) )* - ( LOOKAHEAD(1) <ELSE> (LOOKAHEAD(1) Block() | Statement()) )? + <IF> <LPAREN> Expression() <RPAREN> (LOOKAHEAD(1) Block() | StatementNoVar()) + ( LOOKAHEAD(2) <ELSE> <IF> <LPAREN> Expression() <RPAREN> (LOOKAHEAD(1) Block() | StatementNoVar()) )* + ( LOOKAHEAD(1) <ELSE> (LOOKAHEAD(1) Block() | StatementNoVar()) )? } void WhileStatement() : {} { - <WHILE> <LPAREN> Expression() <RPAREN> { loopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) { loopCount -= 1; } + <WHILE> <LPAREN> Expression() <RPAREN> { loopCount += 1; } (LOOKAHEAD(1) Block() | StatementNoVar()) { loopCount -= 1; } } void DoWhileStatement() : {} { - <DO> { loopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) <WHILE> <LPAREN> Expression() <RPAREN> { loopCount -= 1; } + <DO> { loopCount += 1; } (LOOKAHEAD(1) Block() | StatementNoVar()) <WHILE> <LPAREN> Expression() <RPAREN> { loopCount -= 1; } } void ReturnStatement() : {} @@ -417,7 +424,7 @@ void ForeachStatement() : {} { pushUnit(jjtThis); } <FOR> <LPAREN> ForEachVar() <COLON> Expression() <RPAREN> { loopCount += 1; } - (LOOKAHEAD(1) Block() | Statement()) + (LOOKAHEAD(1) Block() | StatementNoVar()) { loopCount -= 1; popUnit(jjtThis); } } diff --git a/src/test/java/org/apache/commons/jexl3/LexicalTest.java b/src/test/java/org/apache/commons/jexl3/LexicalTest.java index bb354c05..058050fe 100644 --- a/src/test/java/org/apache/commons/jexl3/LexicalTest.java +++ b/src/test/java/org/apache/commons/jexl3/LexicalTest.java @@ -820,13 +820,13 @@ public class LexicalTest { @Test public void testLetSucceed() { List<String> srcs = Arrays.asList( - "var x = 1; var x = 0;", + "var x = 1; var x = 0;", "{ let x = 0; } var x = 1;", - "var x = 0; var f = () -> { let x = 1; } f()", - //"let x = 0; function f() { let x = 1; }; f()" , - "var x = 0; var f = (let x) -> { x = 1; } f()", - "var x = 0; let f = (let x) -> { x = 1; } f()", - "var x = 0; const f = (let x) -> { x = 1; } f()", + "var x = 0; var f = () -> { let x = 1; } f()", + //"let x = 0; function f() { let x = 1; }; f()" , + "var x = 0; var f = (let x) -> { x = 1; } f()", + "var x = 0; let f = (let x) -> { x = 1; } f()", + "var x = 0; const f = (let x) -> { x = 1; } f()", "" ); checkParse(srcs, true); @@ -846,6 +846,23 @@ public class LexicalTest { checkParse(srcs, false); } + @Test + public void testVarFail() { + List<String> srcs = Arrays.asList( + "var x = 0; var x = 1;", + "var x = 0; let x = 1;", + "let x = 0; var x = 1;", + "var x = 0; const f = (var x) -> { let x = 1; } f()", + "var x = 0; const f = (let x) -> { var x = 1; } f()", + "var x = 0; const f = (var x) -> { var x = 1; } f()", + "" + ); + JexlFeatures f= new JexlFeatures(); + f.lexical(true).lexicalShade(true); + checkParse(f, srcs, false); + } + + @Test public void testConstFail() { List<String> srcs = Arrays.asList( @@ -859,8 +876,50 @@ public class LexicalTest { checkParse(srcs, false); } + @Test + public void testSingleStatementDeclFail() { + List<String> srcs = Arrays.asList( + "if (true) let x ;", + "if (true) let x = 1;", + "if (true) var x = 1;", + "if (true) { 1 } else let x ;", + "if (true) { 1 } else let x = 1;", + "if (true) { 1 } else var x = 1;", + "while (true) let x ;", + "while (true) let x = 1;", + "while (true) var x = 1;", + "do let x ; while (true)", + "do let x = 1; while (true)", + "do var x = 1; while (true)", + "for (let i:ii) let x ;", + "for (let i:ii) let x = 1;", + "for (let i:ii) var x = 1;", + "" + ); + JexlFeatures f= new JexlFeatures(); + f.lexical(true).lexicalShade(true); + checkParse(f, srcs, false); + } + + @Test + public void testSingleStatementVarSucceed() { + List<String> srcs = Arrays.asList( + "if (true) var x = 1;", + "if (true) { 1 } else var x = 1;", + "while (true) var x = 1;", + "do var x = 1 while (true)", + "for (let i:ii) var x = 1;", + "" + ); + checkParse(srcs, true); + } + private void checkParse(List<String> srcs, boolean expected) { - final JexlEngine jexl = new JexlBuilder().strict(true).create(); + checkParse(null, srcs, expected); + } + + private void checkParse(JexlFeatures f, List<String> srcs, boolean expected) { + final JexlEngine jexl = new JexlBuilder().features(f).strict(true).create(); for(String src : srcs) { if (!src.isEmpty()) try { final JexlScript script = jexl.createScript(src); @@ -871,7 +930,7 @@ public class LexicalTest { if (expected) { Assert.fail(src); } - Assert.assertTrue(xlexical.detailedMessage().contains("x")); + //Assert.assertTrue(xlexical.detailedMessage().contains("x")); } }