Author: markt Date: Fri Jul 23 14:30:26 2010 New Revision: 967107 URL: http://svn.apache.org/viewvc?rev=967107&view=rev Log: Handle the edge cases where resources packaged in JARs have names that start with a single quote character or a double quote character.
Added: tomcat/trunk/test/org/apache/naming/resources/TestWarDirContext.java (with props) tomcat/trunk/test/webapp-3.0-fragments/'singlequote2.jsp (with props) tomcat/trunk/test/webapp-3.0-fragments/WEB-INF/classes/ tomcat/trunk/test/webapp-3.0-fragments/warDirContext.jsp (with props) Modified: tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java tomcat/trunk/test/webapp-3.0-fragments/WEB-INF/lib/resources.jar tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java?rev=967107&r1=967106&r2=967107&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java (original) +++ tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java Fri Jul 23 14:30:26 2010 @@ -198,7 +198,7 @@ public class WARDirContext extends BaseD Name name; try { - name = new CompositeName(strName); + name = getEscapedJndiName(strName); } catch (InvalidNameException e) { log.info(sm.getString("resources.invalidName", strName), e); return null; @@ -219,6 +219,19 @@ public class WARDirContext extends BaseD /** + * JNDI treats ' and " as reserved characters therefore they need to be + * escaped as part of converting file names to JNDI names. Note that while + * ' can be used in Windows and Unix file names, " is only valid on Unix. + * This method assumes that the string is currently unquoted. + * + * @return A valid JNDI name + * @throws InvalidNameException + */ + private Name getEscapedJndiName(String name) throws InvalidNameException { + return new CompositeName(name.replace("'", "\\'").replace("\"", "")); + } + + /** * Unbinds the named object. Removes the terminal atomic name in name * from the target context--that named by all but the terminal atomic * part of name. @@ -273,7 +286,7 @@ public class WARDirContext extends BaseD @Override public NamingEnumeration<NameClassPair> list(String name) throws NamingException { - return list(new CompositeName(name)); + return list(getEscapedJndiName(name)); } @@ -320,7 +333,7 @@ public class WARDirContext extends BaseD protected NamingEnumeration<Binding> doListBindings(String strName) throws NamingException { - Name name = new CompositeName(strName); + Name name = getEscapedJndiName(strName); if (name.isEmpty()) return new NamingContextBindingsEnumeration(list(entries).iterator(), @@ -426,7 +439,7 @@ public class WARDirContext extends BaseD @Override protected Attributes doGetAttributes(String name, String[] attrIds) throws NamingException { - return getAttributes(new CompositeName(name), attrIds); + return getAttributes(getEscapedJndiName(name), attrIds); } @@ -760,8 +773,8 @@ public class WARDirContext extends BaseD int currentPos = -1; int lastPos = 0; while ((currentPos = name.indexOf('/', lastPos)) != -1) { - Name parentName = new CompositeName(name.substring(0, lastPos)); - Name childName = new CompositeName(name.substring(0, currentPos)); + Name parentName = getEscapedJndiName(name.substring(0, lastPos)); + Name childName = getEscapedJndiName(name.substring(0, currentPos)); String entryName = name.substring(lastPos, currentPos); // Parent should have been created in last cycle through // this loop @@ -781,7 +794,7 @@ public class WARDirContext extends BaseD lastPos = currentPos + 1; } String entryName = name.substring(pos + 1, name.length()); - Name compositeName = new CompositeName(name.substring(0, pos)); + Name compositeName = getEscapedJndiName(name.substring(0, pos)); Entry parent = treeLookup(compositeName); Entry child = new Entry(entryName, entry); if (parent != null) Added: tomcat/trunk/test/org/apache/naming/resources/TestWarDirContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/naming/resources/TestWarDirContext.java?rev=967107&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/naming/resources/TestWarDirContext.java (added) +++ tomcat/trunk/test/org/apache/naming/resources/TestWarDirContext.java Fri Jul 23 14:30:26 2010 @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.naming.resources; + +import java.io.File; + +import org.apache.catalina.core.JreMemoryLeakPreventionListener; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.buf.ByteChunk; + +public class TestWarDirContext extends TomcatBaseTest { + + @Override + public void setUp() throws Exception { + super.setUp(); + + Tomcat tomcat = getTomcatInstance(); + + // The test fails if JreMemoryLeakPreventionListener is not + // present. The listener affects the JVM, and thus not only the current, + // but also the subsequent tests that are run in the same JVM. So it is + // fair to add it in every test. + tomcat.getServer().addLifecycleListener( + new JreMemoryLeakPreventionListener()); + } + + /** + * Check https://jira.springsource.org/browse/SPR-7350 isn't really an issue + */ + public void testLookupException() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0-fragments"); + // app dir is relative to server home + tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); + + tomcat.start(); + + ByteChunk bc = getUrl("http://localhost:" + getPort() + + "/test/warDirContext.jsp"); + assertEquals("<p>java.lang.ClassNotFoundException</p>", + bc.toString()); + } + + + /** + * Additional test following on from SPR-7350 above to check files that + * contain JNDI reserved characters can be served when caching is enabled. + */ + public void testReservedJNDIFileNamesWithCache() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0-fragments"); + // app dir is relative to server home + StandardContext ctxt = (StandardContext) tomcat.addWebapp( + null, "/test", appDir.getAbsolutePath()); + ctxt.setCachingAllowed(true); + + tomcat.start(); + + // Should be found in resources.jar + ByteChunk bc = getUrl("http://localhost:" + getPort() + + "/test/'singlequote.jsp"); + assertEquals("<p>'singlequote.jsp in resources.jar</p>", + bc.toString()); + + // Should be found in file system + bc = getUrl("http://localhost:" + getPort() + + "/test/'singlequote2.jsp"); + assertEquals("<p>'singlequote2.jsp in file system</p>", + bc.toString()); + } + + + /** + * Additional test following on from SPR-7350 above to check files that + * contain JNDI reserved characters can be served when caching is disabled. + */ + public void testReservedJNDIFileNamesNoCache() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0-fragments"); + // app dir is relative to server home + StandardContext ctxt = (StandardContext) tomcat.addWebapp( + null, "/test", appDir.getAbsolutePath()); + ctxt.setCachingAllowed(false); + + tomcat.start(); + + // Should be found in resources.jar + ByteChunk bc = getUrl("http://localhost:" + getPort() + + "/test/'singlequote.jsp"); + assertEquals("<p>'singlequote.jsp in resources.jar</p>", + bc.toString()); + + // Should be found in file system + bc = getUrl("http://localhost:" + getPort() + + "/test/'singlequote2.jsp"); + assertEquals("<p>'singlequote2.jsp in file system</p>", + bc.toString()); + } +} Propchange: tomcat/trunk/test/org/apache/naming/resources/TestWarDirContext.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/test/webapp-3.0-fragments/'singlequote2.jsp URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp-3.0-fragments/%27singlequote2.jsp?rev=967107&view=auto ============================================================================== --- tomcat/trunk/test/webapp-3.0-fragments/'singlequote2.jsp (added) +++ tomcat/trunk/test/webapp-3.0-fragments/'singlequote2.jsp Fri Jul 23 14:30:26 2010 @@ -0,0 +1,19 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--%><%-- + Resource file that is present both in the web application and in the + WEB-INF/lib/resources.jar file. The one in the web application should win. +--%><p>'singlequote2.jsp in file system</p> \ No newline at end of file Propchange: tomcat/trunk/test/webapp-3.0-fragments/'singlequote2.jsp ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/test/webapp-3.0-fragments/WEB-INF/lib/resources.jar URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp-3.0-fragments/WEB-INF/lib/resources.jar?rev=967107&r1=967106&r2=967107&view=diff ============================================================================== Binary files - no diff available. Added: tomcat/trunk/test/webapp-3.0-fragments/warDirContext.jsp URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp-3.0-fragments/warDirContext.jsp?rev=967107&view=auto ============================================================================== --- tomcat/trunk/test/webapp-3.0-fragments/warDirContext.jsp (added) +++ tomcat/trunk/test/webapp-3.0-fragments/warDirContext.jsp Fri Jul 23 14:30:26 2010 @@ -0,0 +1,21 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--%><% +try { + Class<?> clazz = Class.forName("'P'"); +} catch (Exception e) { + out.print("<p>" + e.getClass().getName() + "</p>"); +}%> \ No newline at end of file Propchange: tomcat/trunk/test/webapp-3.0-fragments/warDirContext.jsp ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=967107&r1=967106&r2=967107&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Fri Jul 23 14:30:26 2010 @@ -189,6 +189,10 @@ that make multiple class to <code>Request.getAttributeNames()</code>. Patch provided by Sampo Savolainen. (markt) </fix> + <fix> + Handle the edge cases where resources packaged in JARs have names that + start with a single quote character or a double quote character. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org