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>&amp;</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

Reply via email to