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]>