remm 02/03/15 21:31:12 Modified: coyote/src/java/org/apache/coyote/tomcat4 CoyoteProcessor.java Log: - Reimplement the URI normalization algorithm using a memory efficient algorithm. Revision Changes Path 1.16 +77 -33 jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java Index: CoyoteProcessor.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- CoyoteProcessor.java 15 Mar 2002 19:04:49 -0000 1.15 +++ CoyoteProcessor.java 16 Mar 2002 05:31:12 -0000 1.16 @@ -1,6 +1,6 @@ -/* * $Header: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java,v 1.15 2002/03/15 19:04:49 remm Exp $ - * $Revision: 1.15 $ - * $Date: 2002/03/15 19:04:49 $ +/* * $Header: /home/cvs/jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote/tomcat4/CoyoteProcessor.java,v 1.16 2002/03/16 05:31:12 remm Exp $ + * $Revision: 1.16 $ + * $Date: 2002/03/16 05:31:12 $ * * ==================================================================== * @@ -117,7 +117,7 @@ * * @author Craig R. McClanahan * @author Remy Maucherat - * @version $Revision: 1.15 $ $Date: 2002/03/15 19:04:49 $ + * @version $Revision: 1.16 $ $Date: 2002/03/16 05:31:12 $ */ final class CoyoteProcessor @@ -390,14 +390,14 @@ else request.setServerPort(serverPort); - parseSessionId(req); - if (!normalize(req.decodedURI())) { res.setStatus(400); res.setMessage("Invalid URI"); throw new IOException("Invalid URI"); } + parseSessionId(req); + // Additional URI normalization and validation is needed for security // reasons on Tomcat 4.0.x if (connector.getUseURIValidationHack()) { @@ -640,54 +640,98 @@ * * @param uri URI to be normalized */ - public boolean normalize(MessageBytes uri) { - - // FIXME: Write a GC friendly version of this + public boolean normalize(MessageBytes uriMB) { - // Create a place for the normalized path - String normalized = uri.toString(); - - // Normalize slashes - if (normalized.indexOf('\\') >= 0) - normalized = normalized.replace('\\', '/'); + ByteChunk uriBC = uriMB.getByteChunk(); + byte[] b = uriBC.getBytes(); + int start = uriBC.getStart(); + int end = uriBC.getEnd(); + + int pos = 0; + int index = 0; + + // Replace '\' with '/' + for (pos = start; pos < end; pos++) { + if (b[pos] == (byte) '\\') + b[pos] = (byte) '/'; + } + + // Replace "//" with "/" + for (pos = start; pos < (end - 1); pos++) { + if ((b[pos] == (byte) '/') && (b[pos + 1] == (byte) '/')) { + copyBytes(b, pos, pos + 1, end - pos - 1); + end--; + } + } - // Resolve occurrences of "//" in the normalized path - while (true) { - int index = normalized.indexOf("//"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 1); + // If the URI ends with "/." or "/..", then we append an extra "/" + // Note: It is possible to extend the URI by 1 without any side effect + // as the next character in a non-significant WS. + if (((end - start) > 2) && (b[end - 1] == (byte) '.')) { + if ((b[end - 2] == (byte) '/') + || ((b[end - 2] == (byte) '.') + && (b[end - 3] == (byte) '/'))) { + b[end] = (byte) '/'; + end++; + } } - if (normalized.endsWith("/.") || normalized.endsWith("/..")) - normalized = normalized + "/"; + uriBC.setEnd(end); + + index = 0; // Resolve occurrences of "/./" in the normalized path while (true) { - int index = normalized.indexOf("/./"); + index = uriBC.indexOf("/./", 0, 3, index); if (index < 0) break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 2); + copyBytes(b, start + index, start + index + 2, + end - start - index - 2); + end = end - 2; + uriBC.setEnd(end); } + index = 0; + // Resolve occurrences of "/../" in the normalized path while (true) { - int index = normalized.indexOf("/../"); + index = uriBC.indexOf("/../", 0, 4, index); if (index < 0) break; + // Prevent from going outside our context if (index == 0) - return false; // Trying to go outside our context - int index2 = normalized.lastIndexOf('/', index - 1); - normalized = normalized.substring(0, index2) + - normalized.substring(index + 3); + return false; + int index2 = -1; + for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos --) { + if (b[pos] == (byte) '/') { + index2 = pos; + } + } + copyBytes(b, start + index2, start + index + 3, + end - start - index - 3); + end = end + index2 - index - 3; + uriBC.setEnd(end); + index = index2; } - uri.setString(normalized); + uriBC.setBytes(b, start, end); return true; + } + + + // ------------------------------------------------------ Protected Methods + + + /** + * Copy an array of bytes to a different position. Used during + * normalization. + */ + protected void copyBytes(byte[] b, int dest, int src, int len) { + for (int pos = 0; pos < len; pos++) { + b[pos + dest] = b[pos + src]; + } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>