System.out.println(new File("C:").exists()); prints true, so I guess it works okay.
On Wed, Apr 20, 2016 at 3:31 PM, Konstantin Kolinko <knst.koli...@gmail.com> wrote: > 2016-04-19 22:42 GMT+03:00 Mark Thomas <ma...@apache.org>: > > On 19/04/2016 19:38, Dimitar Valov wrote: > >> All static resources such as index.html will not be found when > application > >> is added with <Context path="/" docBase="../../../"/>, for example > tomcat > >> is put inside the application's META-INF. > >> > >> I've drilled down that the AbstractFileResourceSet class is responsible > for > >> this behaviour, inside the protected final File file(String name, > boolean > >> mustExist) method. There absoluteBase and canonicalBase (absolute, > unique > >> with resolved symlinks) are used to determine if the file should be > >> accessed based on a case sensitivity check. > >> > >> Everything works fine if the docBase is not just path like > ../../.././../ > >> but has an actual directory at the end, like ../../../web-app. However > in > >> this edgy case the difference appears since the behaviour of > >> the org.apache.tomcat.util.http.RequestUtil.normalize method has > slightly > >> different behavior than the File.getCanonicalPath. > >> > >> System.out.println(RequestUtil.normalize("/base/1/2/3/../../../")); > >> /base/ > >> > >> System.out.println(RequestUtil.normalize("/base/1/2/3/../../..")); > >> /base/1/.. > >> System.out.println(new > File("/base/1/2/3/../../../").getCanonicalPath()); > >> /base > >> > >> The added /from RequestUtil breakes the logic inside the file method, > since > >> when doing the substring operation inside AbstractFileResourceSet.file > >> method it may or may not have a trailing /. In such situation <whatever > >> path>/index.html substring with the absoluteBase becomes ndex.html. At > the > >> end the file method returns from here: > >> > >> if (!canPath.equals(absPath)) // > !"index.html".equals("ndex.html") > >> => true > >> return null; > >> > >> The RequestUtil comes from the http packages and follows their > conventions > >> when normalizing the path, so an obvious way to fix this is to add and > if > >> statement after the normalization > >> inside AbstractFileResourceSet.initInternal. > >> > >> this.absoluteBase = normalize(absolutePath); > >> if (this.absoluteBase.endsWith("/")) { > >> this.absoluteBase = this.absoluteBase.substring(0, > >> this.absoluteBase.length() - 1); > >> } > >> > >> With Java 7 instead of using the RequestUtil for normalization, Path > >> java.nio.file.Path.normalize() can accomplish the correct thing. > >> > >> Do you think that is something that can be fixed? Maybe the above is not > >> the best approach, however it's the least invasive. > > > > We need to be very careful here since this is security sensitive. > > > > Given that normalize handles URIs, there is an argument for slightly > > different handling of trailing '/'. I'm currently of the view (subject > > to the results of some local tests I am running) that if the input ends > > in '/', so should the output. If the input doesn't end in '/' neither > > should the output unless the output is the string "/". > > > > The end result is likely to be that docBase values should not end in "/". > > > > (I have not looked at the context. Just a general comment / review of > r1740134) > > There is a risk of normalizing Windows path of "C:\foo\.." into "C:" > which denotes the current directory on drive C: while the expected > value is the root of the drive, "C:\". > > I have not tested how java.io.File("C:") actually works. > > Best regards, > Konstantin Kolinko > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >