Bug 60022 - ContextConfig#fixDocBase function generates invalid docBase if exploded war is a sym-link
Summary: ContextConfig#fixDocBase function generates invalid docBase if exploded war i...
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.5.4
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2016-08-19 02:16 UTC by mohitchugh
Modified: 2016-08-23 19:43 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description mohitchugh 2016-08-19 02:16:24 UTC
I have a scenario where my appBase looks something like this - 


and I have a ROOT.war file and a pre-exploded war both as symlinks, something like -

/xyz/tomcat/webapps/ROOT -> /abc/ROOT/
/xyz/tomcat/webapps/ROOT.war -> /abc/ROOT.war

This means that in ContextConfig.fixDocBase():578, I see docBase = ROOT.war

This then expands to docBase = /xyz/tomcat/webapps/ROOT.war at line:591. 

Stepping forward, at line:609, docBaseInAppBase gets set to true as my docBase indeed starts with the appBase string.

Considering that the docBase value as of now ends in .war and it is not a directory and I have unpackWARS set to true, at line 614, docBase is set to '/xyz/tomcat/webapps/ROOT' (as that's what ExpandWars.expand returns).

And then at line 616, docBase is set to the canonicalPath of /xyz/tomcat/webapps/ROOT which in my case is /abc/ROOT/

Note that my docBaseInAppBase is still set to true, which is now incorrect.

This means that at line:656, either docBase.substring() throws an exception if my docBase was shorter than appBase, or, if not, context.setDocBase gets set to an invalid truncated value of the canonical path at line:665 which causes problems down the line.

Specifically for longer canonical paths of the exploded war I get -  

Caused by: java.lang.IllegalArgumentException: The main resource set specified [<invalid-truncated-path>] is not valid
    239   at org.apache.catalina.webresources.StandardRoot.createMainResourceSet(StandardRoot.java:729) ~[catalina.jar:8.5.4]
    240   at org.apache.catalina.webresources.StandardRoot.startInternal(StandardRoot.java:686) ~[catalina.jar:8.5.4]
    241   at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) ~[catalina.jar:8.5.4]
    242   at org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:4831) ~[catalina.jar:8.5.4]
    243   at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4963) ~[catalina.jar:8.5.4]
    244   at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) ~[catalina.jar:8.5.4]

In my tests, refreshing the docBaseInAppBase value by calling again -
docBaseInAppBase = docBase.startsWith(appBase.getPath() + File.separatorChar); 

just before line:655 (which checks the docBaseInAppBase value) solves the problem, but I'm not sure if I'm missing any other edge conditions.

I'll really appreciate a formal fix for the issue. Thanks!
Comment 1 mohitchugh 2016-08-19 02:25:30 UTC
To summarize, ContextConfig.fixDocBase() is not correctly revalidating the fact that it thought docBase was inside appBase after it sets docBase to its canonical path.
Comment 2 Mark Thomas 2016-08-23 19:43:22 UTC
This has been fixed in the following branches:
- 9.0.x for 9.0.0.M10 onwards
- 8.5.x for 8.5.5 onwards
- 8.0.x for 8.0.37 onwards

7.0.x and earlier are not affected.