[jira] [Commented] (JEXL-456) Change in template parser behavior
[
https://issues.apache.org/jira/browse/JEXL-456?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18058667#comment-18058667
]
Henri Biestro commented on JEXL-456:
On the side-effect observed when parsing was in error, there was indeed some
cleanup missing.
On the '$$' not always being on a newline and to allow a smooth transition,
I've added a feature flag (ignoreTemplatePrefix) that is (almost) self
explanatory: when true, it indicates to the template parser that it should
ignore any token that matches the prefix ($$ in the common case). The trade-off
is that a $$ variable would be unknown since made invisible; not sure of this
warrants more control (at execution time, throw exception if local args or
context contain such a variable when the flag is on).
I'd suggest to adhere to the non-relaxed syntax for templates; prefix
(+whitespaces) at beginning of line :-) .
> 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.0, 3.6.1, 3.6.2
>Reporter: Vincent Bussol
>Assignee: Henri Biestro
>Priority: Major
> Fix For: 3.6.3
>
>
> 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 J
[jira] [Commented] (JEXL-456) Change in template parser behavior
[
https://issues.apache.org/jira/browse/JEXL-456?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18058230#comment-18058230
]
Gary D. Gregory commented on JEXL-456:
--
Hi [~henrib]
Any thoughts here?
> 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.0, 3.6.1, 3.6.2
>Reporter: Vincent Bussol
>Priority: Major
>
> 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() {
> fi
[jira] [Commented] (JEXL-456) Change in template parser behavior
[
https://issues.apache.org/jira/browse/JEXL-456?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18057580#comment-18057580
]
Vincent Bussol commented on JEXL-456:
-
I first detected it when integrating the 3.6.2 into our codebase. Then I
performed unit tests using the 3.6.0. So this is not new in 3.6.2.
> 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
>Priority: Major
>
> 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 th
[jira] [Commented] (JEXL-456) Change in template parser behavior
[
https://issues.apache.org/jira/browse/JEXL-456?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18057563#comment-18057563
]
Gary D. Gregory commented on JEXL-456:
--
Hello [~kshvbussol]
Thank you for your report. Is this new in 3.6.2, or did it also occur in 3.6.0
and 3.6.1?
> 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
>Priority: Major
>
> 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.
