Bug 48498

Summary: 6.0.22RC: ArrayIndexOutOfBoundsException from Jasper when compilation error inside a CDATA block
Product: Tomcat 6 Reporter: Konstantin Kolinko <knst.kolinko>
Component: JasperAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 6.0.20   
Target Milestone: default   
Hardware: PC   
OS: Windows XP   
Attachments: /webapps/examples/WEB-INF/tags/panel.tagx
/webapps/examples/jsp/jsp2/jspx/basic.jspx

Description Konstantin Kolinko 2010-01-06 19:40:54 UTC
Created attachment 24808 [details]
/webapps/examples/WEB-INF/tags/panel.tagx

Steps to reproduce:
1. Remove /WEB-INF/tags/panel.tag
from the Tomcat Examples webapp and replace it with the attached XML Tag file, panel.tagx

2. Visit the following page:
http://localhost:8080/examples/jsp/jsp2/tagfiles/panel.jsp

3. The page contains a scriptlet, with a CDATA block that produces
a compilatin error.

Expected result:
Compilation error being reported for line 39,
  Integer.parseInt(10);

Actual result:
java.lang.ArrayIndexOutOfBoundsException: 46
	org.apache.jasper.compiler.JavacErrorDetail.<init>(JavacErrorDetail.java:111)

4. If I add sufficient number of empty lines after the CDATA block,
ArrayIndexOutOfBoundsException disappears and I can see the compiler error,
but the error lines shown are wrong. The shown lines are below the actual
location of the error.
It looks like this offset in line numbers is due to the size of the CDATA
block.






====================================================================
Full stacktrace of the above ArrayIndexOutOfBoundsException exception:

java.lang.ArrayIndexOutOfBoundsException: 46
	org.apache.jasper.compiler.JavacErrorDetail.<init>(JavacErrorDetail.java:111)
	org.apache.jasper.compiler.ErrorDispatcher.createJavacError(ErrorDispatcher.java:533)
	org.apache.jasper.compiler.JDTCompiler$2.acceptResult(JDTCompiler.java:377)
	org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:398)
	org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:429)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:334)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)
	org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:589)
	org.apache.jasper.servlet.JspServletWrapper.loadTagFile(JspServletWrapper.java:215)
	org.apache.jasper.compiler.TagFileProcessor.loadTagFile(TagFileProcessor.java:625)
	org.apache.jasper.compiler.TagFileProcessor.access$000(TagFileProcessor.java:52)
	org.apache.jasper.compiler.TagFileProcessor$TagFileLoaderVisitor.visit(TagFileProcessor.java:685)
	org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1530)
	org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)
	org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2411)
	org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2417)
	org.apache.jasper.compiler.Node$Root.accept(Node.java:495)
	org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)
	org.apache.jasper.compiler.TagFileProcessor.loadTagFiles(TagFileProcessor.java:703)
	org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:195)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:332)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)
	org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:589)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
====================================================================
Comment 1 Konstantin Kolinko 2010-01-06 19:47:10 UTC
Created attachment 24809 [details]
/webapps/examples/jsp/jsp2/jspx/basic.jspx

One more example - a JSP page.

Location: /webapps/examples/jsp/jsp2/jspx/basic.jspx
HTTP Address: http://localhost:8080/examples/jsp/jsp2/jspx/basic.jspx

Displays
 java.lang.ArrayIndexOutOfBoundsException: 57
Comment 2 Konstantin Kolinko 2010-01-13 17:00:40 UTC
Reproducible in 6.0.20.
So, it is not a regression in the current 6.0.x.


If anyone encounters this, one way to find where it failed is to search in the /work directory for a *.java file that does not have *.class file of the same name. That matches to a jsp or tag file that failed to compile.
Comment 3 Mark Thomas 2010-02-15 16:42:03 UTC
This is not a Tomcat but, but a bug in the SAX Parser provided by the JDK. Local testing shows:
1.5.0_22_x64 - works
1.6.0_16_x64 - ArrayIndexOutOfBoundsException
1.7.0_b76_x64 - ArrayIndexOutOfBoundsException

The bug is that in LexicalHandler.startCDATA() the Locator points to the end of the CDATA section rather than the start. This will always lead to misleading JSP snippets any may result in an ArrayIndexOutOfBoundsException if the CDATA block is close enough to the end of the JSP file.

I have reported the bug to Sun and am awaiting a public bug number. I'll update this issue when I get it.

You can use Xerces 2.9.1 to override the default SAX Parser provided by the JDK to work around this bug if required.

I looked at providing a work around in Tomcat but correctly handling the behaviour of different JDKs with and without Xerces overriding was getting just too messy to be worth while.
Comment 4 Konstantin Kolinko 2010-02-15 17:53:00 UTC
Reopening. Even if we cannot fix/workaround the root cause, at least we can add bounds checking to JavacErrorDetail constructor.

The sad outcome of this issue was that when this ArrayIndexOutOfBoundsException error occurs, there is no information in the stack trace about what JSP or Tag file caused this issue.

Even if we cannot display the source lines, it would be nice to display all other details.
Comment 5 Mark Thomas 2010-02-16 00:48:14 UTC
As much as it pains me to have to add a workaround in Tomcat for a Java bug you have a fair point that hiding the compilation error is a nasty side-effect.

Workaround added to 7.0.x and proposed for 6.0.x
Comment 6 Mark Thomas 2010-03-03 14:30:55 UTC
The workaround has been applied to 6.0.x and will be included in 6.0.26 onwards.