Bug 57441

Summary: EL Lambda expression in a JSP fails with The function incr must be used with a prefix when a default namespace is not specified
Product: Tomcat 8 Reporter: Anup <codetester08>
Component: ELAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 8.0.15   
Target Milestone: ----   
Hardware: PC   
OS: All   

Description Anup 2015-01-14 04:21:20 UTC
Run the following Lambda EL expression in a JSP 

${incr = x->x+1; incr(10)}

fails with this exception,

message /TestLambda.jsp (line: 59, column: 42) The function incr must be used with a prefix when a default namespace is not specified

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: /TestLambda.jsp (line: 59, column: 42) The function incr must be used with a prefix when a default namespace is not specified
	org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:42)
Comment 1 Konstantin Kolinko 2015-01-14 06:29:29 UTC
Reproducible in 8.0.17.

The exception occurs during Validator$ValidateVisitor.validateFunctions() call.

Stacktrace in 8.0.17:

 org.apache.jasper.JasperException: /test.jsp (line: 1, column: 9) The function incr must be used with a prefix when a default namespace is not specified
	at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:41)
	at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:275)
	at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:107)
	at org.apache.jasper.compiler.Validator$ValidateVisitor$1FVVisitor.visit(Validator.java:1585)
	at org.apache.jasper.compiler.ELNode$Function.accept(ELNode.java:139)
	at org.apache.jasper.compiler.ELNode$Nodes.visit(ELNode.java:214)
	at org.apache.jasper.compiler.ELNode$Visitor.visit(ELNode.java:256)
	at org.apache.jasper.compiler.ELNode$Root.accept(ELNode.java:61)
	at org.apache.jasper.compiler.ELNode$Nodes.visit(ELNode.java:214)
	at org.apache.jasper.compiler.Validator$ValidateVisitor.validateFunctions(Validator.java:1607)
	at org.apache.jasper.compiler.Validator$ValidateVisitor.prepareExpression(Validator.java:1612)
	at org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:750)
	at org.apache.jasper.compiler.Node$ELExpression.accept(Node.java:950)
	at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2376)
	at org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2428)
	at org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2434)
	at org.apache.jasper.compiler.Node$Root.accept(Node.java:464)
	at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2376)
	at org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1846)
	at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:217)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:356)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:336)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:323)
	at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:570)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:356)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
Comment 2 Mark Thomas 2015-01-17 17:50:50 UTC
I think it is time to ditch Jasper's partial EL parser and use o.a.el.lang.ExpressionBuilder.createNode() to fully parse the EL with a 'proper' EL implementation and then process those nodes.

The down side is that I think this would be the first thing to make Jasper depend on Tomcat's EL implementation rather than any EL implementation. Users would still be free to use another EL impl at runtime - Jasper would just always use Tomcat's impl directly so it can access the parsed nodes. (I need to check the dependency issues. The poms already show a dependency here.)

The upside should be an end to the steady stream of bugs with every new major release as the various new EL features are found to break the simple EL parsing Jasper does. A side benefit is deleting more code and I'm always happy when I can provide the same or better functionality with less code.
Comment 3 Konstantin Kolinko 2015-01-19 09:41:11 UTC
Is it at all possible to reliably validate functions at compile time?

Maybe whitelist functions that have name only with no prefix?


BTW, it is possible to use javax.el.ImportHandler.importStatic() to declare a function by importing a static method of a class.  An example of manipulating ImportHandler at run time is in bug 57142.  If it is manipulated at run time, it means that the information is not available at compile time to perform validation.

https://issues.apache.org/bugzilla/show_bug.cgi?id=57142#c1
Comment 4 Mark Thomas 2015-01-20 10:59:22 UTC
(In reply to Konstantin Kolinko from comment #3)
> Is it at all possible to reliably validate functions at compile time?

You are right. As of EL 3.0 this is no longer possible.

> Maybe whitelist functions that have name only with no prefix?

I think that is the only option at this point. In fact, I can't see any other option that would work because of the point you make below:

> BTW, it is possible to use javax.el.ImportHandler.importStatic() to declare
> a function by importing a static method of a class.  An example of
> manipulating ImportHandler at run time is in bug 57142.  If it is
> manipulated at run time, it means that the information is not available at
> compile time to perform validation.
> 
> https://issues.apache.org/bugzilla/show_bug.cgi?id=57142#c1

Hmm. If we have no choice but to whitelist functions with no prefix then there might not be a need for the switch to the full EL parser.

I think it is worth raising this with the JSP maint lead. I'll do that shortly.
Comment 5 Mark Thomas 2015-01-22 13:56:48 UTC
Fixed by whitelisting function names without a namespace. I have a query in the the JSP maintenance lead in case an alternative approach is decided.