[ 
https://issues.apache.org/jira/browse/JEXL-323?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17028425#comment-17028425
 ] 

Dmitri Blinov commented on JEXL-323:
------------------------------------

Not sure whether its worth creating a separate issue for this, but the 
following test case fails, because we are mixing null values with undefined 
variables when resolving antish variables.
{code:java}
    @Test
    public void testBadAnt() throws Exception {
        JexlEvalContext ctxt = new JexlEvalContext();
        JexlOptions options = ctxt.getEngineOptions();
        ctxt.set("x.y", 42);
        JexlScript script = JEXL.createScript("var x = null; x.y");
        try {
            Object result = script.execute(ctxt);
            Assert.fail("antish var shall not be resolved");
        } catch(JexlException xother) {
            Assert.assertTrue(xother != null);
        }
    }
{code}

> Ant-style variables can throw exception when evaluated for their value
> ----------------------------------------------------------------------
>
>                 Key: JEXL-323
>                 URL: https://issues.apache.org/jira/browse/JEXL-323
>             Project: Commons JEXL
>          Issue Type: Bug
>    Affects Versions: 3.1
>            Reporter: David Costanzo
>            Assignee: Henri Biestro
>            Priority: Minor
>             Fix For: 3.2
>
>
> When try to evaluate an expression that is the name of a variable and the 
> value is null, I get the value null. This is good. However, when I do the 
> same thing with an ant-style variable name, a JexlException$Variable is 
> thrown claiming that the variable is null. I think this is a bug because I 
> would expect all variables to behave the same, regardless of their name.
> The reason for this behavior is evident in Interpreter.visit() and 
> InterpreterBase.unsolvableVariable().  There is already special-case logic to 
> detect when an ant variable is null versus when it's undefined, and this 
> information is given to unsolvableVariable(), but it still throws an 
> exception.
>  
> {code:java}
>     if (object == null && !isTernaryProtected(node)) {
>         if (antish && ant != null) {
>             // V--- NOTE: context.has() returns true, so undefined is false
>             boolean undefined = !(context.has(ant.toString()) || 
> isLocalVariable(node, 0));
>             // variable unknown in context and not a local
>             return unsolvableVariable(node, ant.toString(), undefined); // 
> <-- still throws exception
>         } else if (!pty) {
>             return unsolvableProperty(node, "<null>.<?>", null);
>         }
>     }
>  {code}
> In in unsolvableVariable():
>  
> {code:java}
> protected Object unsolvableVariable(JexlNode node, String var, boolean undef) 
> {
>     // V-- NOTE: both my engine and arithmetic are strict, so this evaluates 
> to true
>     if (isStrictEngine() && (undef || arithmetic.isStrict())) {
>         throw new JexlException.Variable(node, var, undef);
>     } else if (logger.isDebugEnabled()) {
>         logger.debug(JexlException.variableError(node, var, undef));
>     }
>     return null;
> }
>  {code}
>  
>  
> h3. Steps to Reproduce:
>  
> {code:java}
> @Test
> public void testNullAntVariable() throws IOException {
>     // Create or retrieve an engine
>     JexlEngine jexl = new JexlBuilder().create();
>     // on recent code: JexlEngine jexl = new 
> JexlBuilder().safe(false).create();
>     // Populate to identical global variables
>     JexlContext jc = new MapContext();
>     jc.set("NormalVariable", null);
>     jc.set("ant.variable", null);
>     // Evaluate the value of the normal variable
>     JexlExpression expression1 = jexl.createExpression("NormalVariable");
>     Object o1 = expression1.evaluate(jc);
>     Assert.assertEquals(null, o1);
>     // Evaluate the value of the ant-style variable
>     JexlExpression expression2 = jexl.createExpression("ant.variable");
>     Object o2 = expression2.evaluate(jc); // <-- BUG: throws exception 
> instead of returning null
>     Assert.assertEquals(null, o2);
> }
> {code}
>  
>  
> h3. What Happens:
> "expression2.evaluate(jc)" throws an JexlException$Variable exception with 
> text like "variable 'ant.variable' is null".
> h3. Expected Result:
> expression2.evaluate(jc) returns the value of 'ant.variable', which is null.
> h3.  
> Note:
> This was found on JEXL 3.1, the latest official release. I reproduced it on a 
> snapshot of JEXL 3.2 built from github source, but had to disable "safe".
> h3.  
> Impact:
> My organization uses JEXL to build datasets for clinical trials. In our 
> domain, it's very common to have an expression that is simply the name of a 
> variable whose value is desired. In our domain, we want any sloppy 
> expressions to be a hard error, so we we use strict engines and will use 
> "safe=false" when we update to JEXL 3.2. In our domain, "null" has a specific 
> meaning (it means "missing").  A missing value is distinct from an "undefined 
> variable", which is always an error to reference. Because of this bug, we had 
> to ban using "." in names of "global" variables (variables populated in the 
> JexlContext).



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to