When submitting a JSP request in which the value of the LAST parameter on the URL ends in a percent sign, Catalina throws a "java.lang.ArrayIndexOutOfBoundsException" in the parseParameters() method of org.apache.catalina.util.RequestUtil. Looking at the following line from the switch statement, it would seem that the code is assuming there are two more characters after the percent sign: case '%': data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4) + convertHexDigit(data[ix++])); If the query string were properly encoded (% -> %25), this wouldn't be an issue. But if it's not, shouldn't the container handle it better than this exception?
If this is failing it is a bug in your code, _not_ a bug in Tomcat. Please read: http://jakarta.apache.org/tomcat/bugreport.html
This happens in method: public static void parseParameters(Map map, byte[] data, String encoding) throws UnsupportedEncodingException Wouldn't this be a good place for this method to throw a UnsupportedEncodingException? That way the calling method can decide how to handle it ( throw an exception, display an error page, etc ) Jay wasn't saying this behavior was a bug in Tomcat, but rather that Tomcat should handle it more gracefully. I agree--I don't think anything the end-user could potentially do should cause Tomcat to throw such a low-level exception
The code isn't there in Tomcat 4.1.x (where the URL decoding code doesn't try to handle encodings), so this will not be fixed.
I can accept that the latest version doesn't use the same code, so it's not going to be fixed. But it IS a bug in the 4.0.4, so let's at least agree to that, and document it, in case someone else runs across it. First, with regards to the suggestion that it was a bug in my code, the error manifested itself when I did the following in my JSP custom tag handler: HttpServletRequest req = (HttpServletRequest) pageContext.getRequest(); Enumeration names = req.getParameterNames(); As far as I know, I there's nothing illegal about that. So, I followed the stack trace, and it led to Catalina's RequestUtil.parseParameters(). Unless I'm completely missing something, you can't write a while loop that checks that "ix < data.length", then blindly increments "ix" THREE times before you check it again: while (ix < data.length) { switch ((char) c) { ... case '%': data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4) + convertHexDigit(data[ix++])); break; ... } } Here's the stack trace too, just for reference. Starting service Tomcat-Standalone Apache Tomcat/4.0.4 java.lang.ArrayIndexOutOfBoundsException at org.apache.catalina.util.RequestUtil.parseParameters(RequestUtil.java :517) at org.apache.catalina.util.RequestUtil.parseParameters(RequestUtil.java :337) at org.apache.catalina.connector.HttpRequestBase.parseParameters(HttpReq uestBase.java:625) at org.apache.catalina.connector.HttpRequestBase.getParameterNames(HttpR equestBase.java:723) at org.apache.catalina.connector.RequestFacade.getParameterNames(Request Facade.java:165) at com.digarch.tags.DATag.doEndTag(DATag.java:114) at org.apache.jsp.displaytable1$jsp._jspService(displaytable1$jsp.java:1 24) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:107) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.jasper.servlet.JspServlet$JspServletWrapper.service(JspSer vlet.java:201) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:3 81) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:473) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl icationFilterChain.java:247) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF ilterChain.java:193) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV alve.java:243) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:566) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav a:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV alve.java:190) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:566) at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve .java:246) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:564) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav a:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.core.StandardContext.invoke(StandardContext.java: 2347) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j ava:180) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:566) at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatche rValve.java:170) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:564) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j ava:170) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:564) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav a:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal ve.java:174) at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline .java:566) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav a:472) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943) at org.apache.catalina.connector.http.HttpProcessor.process(HttpProcesso r.java:1027) at org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.ja va:1125) at java.lang.Thread.run(Thread.java:536) Jay
My reference earlier to a bug in your code was a cut n paste error. That comment was meant for a different bug report. Sorry.