[prev in list] [next in list] [prev in thread] [next in thread] 

List:       jakarta-commons-dev
Subject:    [jira] [Commented] (JEXL-323) Ant-style variables can throw exception when evaluated for their value
From:       "Henri Biestro (Jira)" <jira () apache ! org>
Date:       2020-01-29 17:14:00
Message-ID: JIRA.13281766.1580146062000.67502.1580318040286 () Atlassian ! JIRA
[Download RAW message or body]


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

Henri Biestro commented on JEXL-323:
------------------------------------

About the default flags, I'm sorry for the confusion.
 As stated in JexlOptions.setDefaultFlags(...) javadoc, JEXL builders should be \
explicit and not rely on default flags since those may change with versions (sic). \
That static method (setDefaultFlags) - called by JexlTestCase - ensures some default \
flags but this is pretty fragile.  Before you create the builder, If you call:
{code:java}
    static {
        JexlOptions.setDefaultFlags("-safe", "+lexical", "+lexicalShade");
    }
{code}
The 3 asserts on builder should succeed; again though, brittle. :)

> 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
> Priority: Minor
> 
> 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)


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic