DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=3784>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE. http://nagoya.apache.org/bugzilla/show_bug.cgi?id=3784 Long URLs cause ArrayIndexOutOfBoundsException Summary: Long URLs cause ArrayIndexOutOfBoundsException Product: Tomcat 3 Version: 3.2.3 Final Platform: All OS/Version: Other Status: NEW Severity: Major Priority: Other Component: Connectors AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] I have discovered and fixed several bugs in jakarta-tomcat-3.2.3, all in the HttpRequestAdapter.java source file. The bugs manifest themselves when the URI for the HTTP request (including the request parameter list) exceeds 2048 characters. This prevents Tomcat from being useful for sites which have forms with lots of fields, for example, in which case the sumission of the form could cause a "POST" or "GET" request with a lot of parameters tacked onto the URI. This causes an ArrayIndexOutOfBoundsException due to badly written code in the src/org/apache/tomcat/service/http/HttpRequestAdapter.java. I have included my corrected versions of the affected methods from this file, and have tested it with URIs over 12,000 characters in length. There are two methods affected: readNextRequest() and readHeaders(). Please integrate these changes into the next release of jakarta-tomcat, so that everyone can benefit from them. Thanks for the great software!!! Ron Cemer public void readNextRequest(Response response) throws IOException { // Odd, but works: we use the ServletInputStream, which uses doRead. // We do implement doRead in Http protocol to return from the input // stream - it works for the normal body but also for the HTTP // head. The limit is set after ( and if ) we have a content-length. /// Replaced this line with the code block below to support requests of /// arbitrary lengths. - Ron Cemer /// count = in.readLine(buf, 0, buf.length); count = 0; while (true) { int len = buf.length-count; if (len > 0) { len = in.readLine(buf, count, len); if ( (len == -1) && (count == 0) ) { count = -1; break; } count += len; if (len == 0 || buf[count-1] == '\n') { break; } } // overflowed buffer, so temporarily expand and continue byte[] tmp = new byte[buf.length * 2]; System.arraycopy(buf, 0, tmp, 0, buf.length); buf = tmp; } /// End of replacement code. if (count < 0 ) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } processRequestLine(response ); // for 0.9, we don't have headers! if (protocol!=null) { // all HTTP versions with protocol also have headers ( 0.9 has no HTTP/0.9 !) readHeaders( headers, in ); } // XXX // detect for real whether or not we have more requests // coming moreRequests = false; } /** * Reads header fields from the specified servlet input stream until * a blank line is encountered. * @param in the servlet input stream * @exception IllegalArgumentException if the header format was invalid * @exception IOException if an I/O error has occurred */ public void readHeaders( MimeHeaders headers, ServletInputStream in ) throws IOException { // use pre-allocated buffer if possible off = count; // where the request line ended while (true) { int start = off; while (true) { int len = buf.length - off; if (len > 0) { len = in.readLine(buf, off, len); if (len == -1) { String msg = sm1.getString("mimeHeader.connection.ioe"); throw new IOException (msg); } /// } /// This code should be WITHIN the second "while (true)". - Ron Cemer off += len; if (len == 0 || buf[off-1] == '\n') { break; } /// } // overflowed buffer, so temporarily expand and continue // XXX DOS - if the length is too big - stop and throw exception byte[] tmp = new byte[buf.length * 2]; System.arraycopy(buf, 0, tmp, 0, buf.length); buf = tmp; } // strip off trailing "\r\n" /// if (--off > start && buf[off-1] == '\r') { /// --off; /// } /// This is a less error-prone way of accomplishing the task. - Ron Cemer if ( (off > start) && (buf[off-1] == '\n') ) { off--; if ( (off > start) && (buf[off-1] == '\r') ) off--; } if (off == start) { break; } // XXX this does not currently handle headers which // are folded to take more than one line. MimeHeaderField mhf=headers.putHeader(); if( ! parseHeaderFiled(mhf, buf, start, off - start) ) { // error parsing header return; } } }