Vincent Bussol created JEXL-456:
-----------------------------------
Summary: Change in template parser behavior
Key: JEXL-456
URL: https://issues.apache.org/jira/browse/JEXL-456
Project: Commons JEXL
Issue Type: Bug
Affects Versions: 3.6.2
Reporter: Vincent Bussol
h3. Jexl 3.5.0
The template parser allows to write:
{code:java}
$$ var foo = 'foo'; $$ var bar = 'bar';
${foo + bar}{code}
Depending on the configuration, the result (evaluation) may be different.
* strict = true
* strict = false
* strict = true/false with a global variable '$$'
{code:java}
@Test
void testIssue350_456_strict() {
final JexlEngine jexl = new JexlBuilder().strict(true).create();
final JxltEngine jxlt = jexl.createJxltEngine();
// creation/parse is OK
final JxltEngine.Template template = jxlt.createTemplate("$$ var foo =
'foo'; $$ var bar = 'bar';\n${foo + bar}");
final StringWriter writer = new StringWriter();
try {
template.evaluate(null, writer);
} catch (JexlException xjexl) {
// variable '$$' is undefined
System.out.println(xjexl.getMessage());
}
}
@Test
void testIssue350_456_notStrict() {
final JexlEngine jexl = new JexlBuilder().strict(false).create();
final JxltEngine jxlt = jexl.createJxltEngine();
// creation/parse is OK
final JxltEngine.Template template = jxlt.createTemplate("$$ var foo =
'foo'; $$ var bar = 'bar';\n${foo + bar}");
final StringWriter writer = new StringWriter();
template.evaluate(null, writer);
Assertions.assertEquals("foobar", writer.toString());
}
@Test
void testIssue350_456_strictWithVariable() {
final JexlEngine jexl = new JexlBuilder().strict(true).create();
final JxltEngine jxlt = jexl.createJxltEngine();
// creation/parse is OK
final JxltEngine.Template template = jxlt.createTemplate("$$ var foo =
'foo'; $$ var bar = 'bar';\n${foo + bar}");
// add a '$$' global context variable
JexlContext ctxt = new MapContext();
ctxt.set("$$", "");
final StringWriter writer = new StringWriter();
template.evaluate(ctxt, writer);
Assertions.assertEquals("foobar", writer.toString());
} {code}
h3. Jexl 3.6.x
The previous syntax is no longer allowed by the template parser.
{code:java}
@Test
void testIssue36x_456() {
final JexlEngine jexl = new JexlBuilder().create();
final JxltEngine jxlt = jexl.createJxltEngine();
// creation/parse is KO
try {
jxlt.createTemplate("$$ var foo = 'foo'; $$ var bar = 'bar';\n${foo +
bar}");
} catch (JexlException xjexl) {
// parsing error in 'var'
System.out.println(xjexl.getMessage());
}
} {code}
This can be considered the expected behavior.
However, when a parser error occurs, it would seem that a state persists. Some
scripts or templates are strangely encountering errors.
For example:
{code:java}
@Test
void testIssue36x_456_var() {
final JexlEngine jexl = new JexlBuilder().create();
final JxltEngine jxlt = jexl.createJxltEngine();
// OK
jexl.createScript("var foo = 0;\nfoo = 42;");
try {
jxlt.createTemplate("$$ var foo = 'foo'; if (true) { var foo = 'bar';
var err =&; }");
} catch (JexlException xjexl) {
// parsing error in '&'
System.out.println(xjexl.getMessage());
}
// java.lang.NullPointerException: Cannot invoke
"org.apache.commons.jexl3.internal.Scope.getCaptureDeclaration(int)" because
"blockScope" is null
jexl.createScript("var foo = 0;\nfoo = 42;");
// same error with the template creation below
//jxlt.createTemplate("$$ var foo = 'foo'; foo = 'bar';");
}
@Test
void testIssue36x_456_let() {
final JexlEngine jexl = new Engine32(new JexlBuilder().strict(true));
// OK
jexl.createScript("let foo = 0;\nfoo = 42;");
final JxltEngine jxlt = jexl.createJxltEngine();
try {
jxlt.createTemplate("$$ var err =&;");
} catch (JexlException xjexl) {
// parsing error in '&'
System.out.println(xjexl.getMessage());
}
// parsing error in 'foo: variable is already declared'
jexl.createScript("let foo = 0;\nfoo = 42;");
// same error with the template creation below
//jxlt.createTemplate("$$ let foo = 0;\nfoo = 42;");
} {code}
Note that when a script error occurs, the next call is correct again. This is
not the case for a template.
{code:java}
@Test
void testIssue36x_456_let_script() {
final JexlEngine jexl = new Engine32(new JexlBuilder().strict(true));
// OK
jexl.createScript("let foo = 0;\nfoo = 42;");
final JxltEngine jxlt = jexl.createJxltEngine();
try {
jxlt.createTemplate("$$ var err =&;");
} catch (JexlException xjexl) {
// parsing error in '&'
System.out.println(xjexl.getMessage());
}
try {
jexl.createScript("let foo = 0; foo = 42;");
} catch (JexlException xjexl) {
// ignore - parsing error in 'foo: variable is already declared'
System.out.println(xjexl.getMessage());
}
// the next call is OK
jexl.createScript("let foo = 0; foo = 42;");
}
@Test
void testIssue36x_456_let_template() {
final JexlEngine jexl = new Engine32(new JexlBuilder().strict(true));
// OK
jexl.createScript("let foo = 0;\nfoo = 42;");
final JxltEngine jxlt = jexl.createJxltEngine();
try {
jxlt.createTemplate("$$ var err =&;");
} catch (JexlException xjexl) {
// parsing error in '&'
System.out.println(xjexl.getMessage());
}
try {
jxlt.createTemplate("$$ let foo = 0;\nfoo = 42;");
} catch (JexlException xjexl) {
// ignore - parsing error in 'foo: variable is already declared'
System.out.println(xjexl.getMessage());
}
// the next call is still KO
jxlt.createTemplate("$$ let foo = 0;\nfoo = 42;");
} {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)