You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Henri Biestro (Jira)" <ji...@apache.org> on 2021/06/07 13:15:06 UTC

[jira] [Closed] (JEXL-323) Ant-style variables can throw exception when evaluated for their value

     [ https://issues.apache.org/jira/browse/JEXL-323?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Henri Biestro closed JEXL-323.
------------------------------

> 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)