Skip to content

Commit

Permalink
JEXL-369: detect undefined const use;
Browse files Browse the repository at this point in the history
  • Loading branch information
henrib committed May 17, 2022
1 parent 4ddf183 commit 67d2510
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 11 deletions.
24 changes: 14 additions & 10 deletions src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
Expand Up @@ -334,12 +334,10 @@ protected String checkVariable(final ASTIdentifier identifier, final String name
}
}
if (declared) {
// track if const is defined or not
if (unit.isConstant(symbol)) {
identifier.setConstant(true);
if (!unit.isDefined(symbol)) {
throw new JexlException.Parsing(info, name + ": variable is not defined").clean();
}
identifier.setDefined(true);
identifier.setDefined(unit.isDefined(symbol));
}
} else if (info instanceof JexlNode.Info) {
declared = isSymbolDeclared((JexlNode.Info) info, symbol);
Expand Down Expand Up @@ -569,12 +567,6 @@ protected void Identifier(final boolean top) throws ParseException {
*/
protected abstract Token getToken(int index);

/**
* Overridden in actual parser to access tokens stack.
* @return the next token on the stack
*/
protected abstract Token getNextToken();

/**
* The set of assignment operators as classes.
*/
Expand Down Expand Up @@ -644,6 +636,18 @@ protected void jjtreeCloseNodeScope(final JexlNode node) {
}
}
}
} else {
// control that a const is defined before usage
int nchildren = node.jjtGetNumChildren();
for(int c = 0; c < nchildren; ++c) {
JexlNode child = node.jjtGetChild(c);
if (child instanceof ASTIdentifier) {
ASTIdentifier var = (ASTIdentifier) child;
if (var.isConstant() && !var.isDefined()) {
throw new JexlException.Parsing(info, var.getName() + ": constant is not defined").clean();
}
}
}
}
// heavy check
featureController.controlNode(node);
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/apache/commons/jexl3/JXLTTest.java
Expand Up @@ -267,7 +267,7 @@ public void testImmediate() throws Exception {
}

@Test
public void testConstant() throws Exception {
public void testConstant0() throws Exception {
final JexlContext none = null;
final String source = "Hello World!";
final JxltEngine.Expression expr = JXLT.createExpression(source);
Expand Down
21 changes: 21 additions & 0 deletions src/test/java/org/apache/commons/jexl3/LambdaTest.java
Expand Up @@ -461,6 +461,27 @@ public void testConst1() {
}
}

@Test
public void testConst2() {
final JexlFeatures f = new JexlFeatures();
final JexlEngine jexl = new JexlBuilder().strict(true).create();
final JexlScript script = jexl.createScript( "const x; x = 1");
Object result = script.execute(null);
Assert.assertEquals(1, result);
}

@Test
public void testConst3() {
final JexlFeatures f = new JexlFeatures();
final JexlEngine jexl = new JexlBuilder().strict(true).create();
try {
final JexlScript script = jexl.createScript( "const x; x = 1; x = 2;");
Assert.fail("should fail, x is not defined");
} catch(JexlException.Parsing xparse) {
Assert.assertTrue(xparse.getMessage().contains("x"));
}
}

@Test public void testNamedFuncIsConst() {
String src = "function foo(x) { x + x }; var foo ='nonononon'";
JexlEngine jexl = createEngine();
Expand Down

0 comments on commit 67d2510

Please sign in to comment.