Hello, org.apache.tomcat.util.FileUtil.safePath() had a bug (at least from my point of view) that was preventing use of "\\machine\share" paths in context docBases, yielding a 404 on those contexts. The patch was obtained with a "diff -u <old> <new>", I don't know if that's ok. I've made some testing, and the reasons that lead to safePath implementation in TC32 are still held, I believe (no paths fall outside docBase, case sensitiveness enforced, Win oddities like "*.jsp." prevented). I haven't tested on *nix or netware, but the scope of the changes doesn't seem that big (but feel free to ignore them or apply only on the next bug fix release ;-) Regards, -- Rogério Meneguelli Gatto | ICQ# 25775025 Analista de Sistemas Pleno | +55 19 3254-6518 ext 223 Software Design Informática | http://www.softwaredesign.com.br God is a comic playing to an audience that's afraid to laugh
--- /usr/tomcat32b8/src/org/apache/tomcat/util/FileUtil.java Tue Nov 21 00:59:54 2000 +++ FileUtil.java Tue Nov 28 18:02:53 2000 @@ -67,6 +67,7 @@ import java.io.File; import java.io.IOException; import java.util.Locale; +import java.util.StringTokenizer; /* * FileUtil contains utils for dealing with Files. Some of these are @@ -83,6 +84,7 @@ */ public class FileUtil { + public static final String PATH_SEPARATORS = "/" + File.separatorChar; public static File[] listFiles(File dir) { @@ -134,47 +136,32 @@ // Hack for Jsp ( and other servlets ) that use rel. paths // if( ! path.startsWith("/") ) path="/"+ path; - String normP=path; - if( path.indexOf('\\') >=0 ) - normP= path.replace('\\', '/'); - - if ( !normP.startsWith("/")) - normP = "/" + normP; - - int index = normP.indexOf("/../"); - if (index >= 0) { - - // Clean out "//" and "/./" so they will not be confused - // with real parent directories - int index2 = 0; - while ((index2 = normP.indexOf("//", index2)) >= 0) { - normP = normP.substring(0, index2) + - normP.substring(index2 + 1); - if (index2 < index) - index--; - } - index2 = 0; - while ((index2 = normP.indexOf("/./", index2)) >= 0) { - normP = normP.substring(0, index2) + - normP.substring(index2 + 2); - if (index2 < index) - index -= 2; - } - - // Remove cases of "/{directory}/../" - while (index >= 0) { - // If no parent directory to remove, return null - if (index == 0) - return (null); // Trying to leave our context - index2 = normP.lastIndexOf('/', index-1); - normP = normP.substring(0, index2) + - normP.substring(index + 3); - index = normP.indexOf("/../", index2); - } - - } + // Splits path into its componentes and normalize it + StringTokenizer tk = new StringTokenizer(path, PATH_SEPARATORS, false); + String[] comp = new String[tk.countTokens()]; + int length = 0; + while (tk.hasMoreTokens()) { + String component = tk.nextToken(); + if (component.length() == 0 || component.equals(".")) { + // Empty path component, ignore + continue; + } else if (component.equals("..")) { + // Remove last component. + if (--length < 0) { + // No last component to remove, trying to leave our context + return null; + }; + } else { + // Normal component, append + comp[length++] = component; + } + } + StringBuffer buf = new StringBuffer(base); + for (int i = 0; i < length; i++) { + buf.append(File.separatorChar).append(comp[i]); + } - String realPath= base + normP; + String realPath = buf.toString(); // Probably not needed - it will be used on the local FS realPath = FileUtil.patch(realPath);