Author: markt Date: Thu Jun 29 20:02:59 2017 New Revision: 1800309 URL: http://svn.apache.org/viewvc?rev=1800309&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61229 Correct a regression in 9.0.0.M21 that broke WebDAV handling for resources with names that included a '&' character.
Added: tomcat/trunk/test/org/apache/catalina/util/TestURLEncoder.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java tomcat/trunk/java/org/apache/catalina/util/URLEncoder.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java?rev=1800309&r1=1800308&r2=1800309&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/servlets/WebdavServlet.java Thu Jun 29 20:02:59 2017 @@ -44,6 +44,7 @@ import org.apache.catalina.WebResource; import org.apache.catalina.connector.RequestFacade; import org.apache.catalina.util.ConcurrentDateFormat; import org.apache.catalina.util.DOMWriter; +import org.apache.catalina.util.URLEncoder; import org.apache.catalina.util.XMLWriter; import org.apache.tomcat.util.buf.UDecoder; import org.apache.tomcat.util.http.FastHttpDateFormat; @@ -119,14 +120,22 @@ import org.xml.sax.SAXException; * * @author Remy Maucherat */ -public class WebdavServlet - extends DefaultServlet { +public class WebdavServlet extends DefaultServlet { private static final long serialVersionUID = 1L; // -------------------------------------------------------------- Constants + private static final URLEncoder URL_ENCODER_XML; + static { + URL_ENCODER_XML = (URLEncoder) URLEncoder.DEFAULT.clone(); + // Remove '&' from the safe character set since while it it permitted + // in a URI path, it is not permitted in XML and encoding it is a simple + // way to address this. + URL_ENCODER_XML.removeSafeCharacter('&'); + } + private static final String METHOD_PROPFIND = "PROPFIND"; private static final String METHOD_PROPPATCH = "PROPPATCH"; private static final String METHOD_MKCOL = "MKCOL"; @@ -379,6 +388,18 @@ public class WebdavServlet } + /** + * URL rewriter. + * + * @param path Path which has to be rewritten + * @return the rewritten path + */ + @Override + protected String rewriteUrl(String path) { + return URL_ENCODER_XML.encode(path, StandardCharsets.UTF_8); + } + + /** * Override the DefaultServlet implementation and only use the PathInfo. If * the ServletPath is non-null, it will be because the WebDAV servlet has Modified: tomcat/trunk/java/org/apache/catalina/util/URLEncoder.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/URLEncoder.java?rev=1800309&r1=1800308&r2=1800309&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/util/URLEncoder.java (original) +++ tomcat/trunk/java/org/apache/catalina/util/URLEncoder.java Thu Jun 29 20:02:59 2017 @@ -34,10 +34,10 @@ import java.util.BitSet; * @author Craig R. McClanahan * @author Remy Maucherat */ -public class URLEncoder { +public class URLEncoder implements Cloneable { + private static final char[] hexadecimal = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; public static final URLEncoder DEFAULT = new URLEncoder(); public static final URLEncoder QUERY = new URLEncoder(); @@ -99,12 +99,14 @@ public class URLEncoder { } //Array containing the safe characters set. - private final BitSet safeCharacters = new BitSet(256); + private final BitSet safeCharacters; private boolean encodeSpaceAsPlus = false; public URLEncoder() { + this(new BitSet(256)); + for (char i = 'a'; i <= 'z'; i++) { addSafeCharacter(i); } @@ -117,8 +119,18 @@ public class URLEncoder { } - public void addSafeCharacter( char c ) { - safeCharacters.set( c ); + private URLEncoder(BitSet safeCharacters) { + this.safeCharacters = safeCharacters; + } + + + public void addSafeCharacter(char c) { + safeCharacters.set(c); + } + + + public void removeSafeCharacter(char c) { + safeCharacters.clear(c); } @@ -172,4 +184,12 @@ public class URLEncoder { } return rewrittenPath.toString(); } + + + @Override + public Object clone() { + URLEncoder result = new URLEncoder((BitSet) safeCharacters.clone()); + result.setEncodeSpaceAsPlus(encodeSpaceAsPlus); + return result; + } } Added: tomcat/trunk/test/org/apache/catalina/util/TestURLEncoder.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/util/TestURLEncoder.java?rev=1800309&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/catalina/util/TestURLEncoder.java (added) +++ tomcat/trunk/test/org/apache/catalina/util/TestURLEncoder.java Thu Jun 29 20:02:59 2017 @@ -0,0 +1,56 @@ +/* + * 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.catalina.util; + +import java.nio.charset.StandardCharsets; + +import org.junit.Assert; +import org.junit.Test; + +public class TestURLEncoder { + + private static final String SPACE = " "; + private static final String DOLLAR = "$"; + private static final String AMPERSAND = "&"; + private static final String AMPERSAND_ENCODED = "%26"; + + @Test + public void testClone() { + URLEncoder original = new URLEncoder(); + URLEncoder clone = (URLEncoder) original.clone(); + + // Ensure encode as space is not shared + original.setEncodeSpaceAsPlus(true); + Assert.assertNotEquals(original.encode(SPACE, StandardCharsets.UTF_8), + clone.encode(SPACE, StandardCharsets.UTF_8)); + + // Ensure safe characters is not shared + original.addSafeCharacter('$'); + Assert.assertNotEquals(original.encode(DOLLAR, StandardCharsets.UTF_8), + clone.encode(DOLLAR, StandardCharsets.UTF_8)); + } + + + @Test + public void testRemoveSafeCharacter() { + URLEncoder xml = (URLEncoder) URLEncoder.DEFAULT.clone(); + // This should not encode '&' + Assert.assertEquals(AMPERSAND, xml.encode(AMPERSAND, StandardCharsets.UTF_8)); + xml.removeSafeCharacter('&'); + Assert.assertEquals(AMPERSAND_ENCODED, xml.encode(AMPERSAND, StandardCharsets.UTF_8)); + } +} Propchange: tomcat/trunk/test/org/apache/catalina/util/TestURLEncoder.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1800309&r1=1800308&r2=1800309&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Jun 29 20:02:59 2017 @@ -69,6 +69,11 @@ thread that cleans the log files is marked as daemon thread. (violetagg) </fix> + <fix> + <bug>61229</bug>: Correct a regression in 9.0.0.M21 that broke WebDAV + handling for resources with names that included a <code>&</code> + character. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org