You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/05/16 17:12:27 UTC

[commons-vfs] branch master updated: Fix AbstractFileName.getURI returning unencoded #-sign (#64)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git


The following commit(s) were added to refs/heads/master by this push:
     new f1a1338  Fix AbstractFileName.getURI returning unencoded #-sign (#64)
f1a1338 is described below

commit f1a13382815ce08195c235e4806463fe20c99c07
Author: Boris Petrov <bo...@live.com>
AuthorDate: Thu May 16 20:12:22 2019 +0300

    Fix AbstractFileName.getURI returning unencoded #-sign (#64)
---
 .../commons/vfs2/provider/AbstractFileName.java    | 31 ++++++++++-
 .../commons/vfs2/provider/local/LocalFileName.java | 62 ----------------------
 .../vfs2/provider/AbstractFileNameTest.java        | 44 +++++++++++++++
 3 files changed, 74 insertions(+), 63 deletions(-)

diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileName.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileName.java
index 630ccf4..6114985 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileName.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileName.java
@@ -26,6 +26,19 @@ import org.apache.commons.vfs2.VFS;
  * A default file name implementation.
  */
 public abstract class AbstractFileName implements FileName {
+    // URI Characters that are possible in local filenames, but must be escaped
+    // for proper URI handling.
+    //
+    // How reserved URI chars were selected:
+    //
+    // URIs can contain :, /, ?, #, @
+    // See http://download.oracle.com/javase/6/docs/api/java/net/URI.html
+    // http://tools.ietf.org/html/rfc3986#section-2.2
+    //
+    // Since : and / occur before the path, only chars after path are escaped (i.e., # and ?)
+    // ? is a reserved filesystem character for Windows and Unix, so can't be part of a filename.
+    // Therefore only # is a reserved char in a URI as part of the path that can be in the filename.
+    private static final char[] RESERVED_URI_CHARS = { '#' };
 
     private final String scheme;
     private final String absPath;
@@ -252,10 +265,26 @@ public abstract class AbstractFileName implements FileName {
     private String createURI(final boolean useAbsolutePath, final boolean usePassword) {
         final StringBuilder buffer = new StringBuilder();
         appendRootUri(buffer, usePassword);
-        buffer.append(useAbsolutePath ? absPath : getPath());
+        buffer.append(handleURISpecialCharacters(useAbsolutePath ? absPath : getPath()));
         return buffer.toString();
     }
 
+    private String handleURISpecialCharacters(String uri) {
+        if (uri != null && uri.length() > 0) {
+            try {
+                // VFS-325: Handle URI special characters in filename
+                // Decode the base uri and re-encode with URI special characters
+                uri = UriParser.decode(uri);
+
+                return UriParser.encode(uri, RESERVED_URI_CHARS);
+            } catch (final FileSystemException e) {
+                // Default to base uri value
+            }
+        }
+
+        return uri;
+    }
+
     /**
      * Converts a file name to a relative name, relative to this file name.
      *
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/local/LocalFileName.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/local/LocalFileName.java
index 42a7c78..8463058 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/local/LocalFileName.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/local/LocalFileName.java
@@ -26,20 +26,6 @@ import org.apache.commons.vfs2.provider.UriParser;
  * A local file URI.
  */
 public class LocalFileName extends AbstractFileName {
-    // URI Characters that are possible in local filenames, but must be escaped
-    // for proper URI handling.
-    //
-    // How reserved URI chars were selected:
-    //
-    // URIs can contain :, /, ?, #, @
-    // See http://download.oracle.com/javase/6/docs/api/java/net/URI.html
-    // http://tools.ietf.org/html/rfc3986#section-2.2
-    //
-    // Since : and / occur before the path, only chars after path are escaped (i.e., # and ?)
-    // ? is a reserved filesystem character for Windows and Unix, so can't be part of a filename.
-    // Therefore only # is a reserved char in a URI as part of the path that can be in the filename.
-    private static final char[] RESERVED_URI_CHARS = { '#' };
-
     private final String rootFile;
 
     protected LocalFileName(final String scheme, final String rootFile, final String path, final FileType type) {
@@ -69,54 +55,6 @@ public class LocalFileName extends AbstractFileName {
     }
 
     /**
-     * Returns the absolute URI of the file.
-     *
-     * @return The absolute URI of the file.
-     */
-    @Override
-    public String getURI() {
-        String uri = super.getURI();
-
-        if (uri != null && uri.length() > 0) {
-            try {
-                // VFS-325: Handle URI special characters in filename
-                // Decode the base uri and re-encode with URI special characters
-                uri = UriParser.decode(uri);
-
-                uri = UriParser.encode(uri, RESERVED_URI_CHARS);
-            } catch (final FileSystemException e) {
-                // Default to base uri value
-            }
-        }
-
-        return uri;
-    }
-
-    /**
-     * returns a "friendly path", this is a path without a password.
-     *
-     * @return The "friendly" URI.
-     */
-    @Override
-    public String getFriendlyURI() {
-        String uri = super.getFriendlyURI();
-
-        if (uri != null && uri.length() > 0) {
-            try {
-                // VFS-325: Handle URI special characters in filename
-                // Decode the base uri and re-encode with URI special characters
-                uri = UriParser.decode(uri);
-
-                uri = UriParser.encode(uri, RESERVED_URI_CHARS);
-            } catch (final FileSystemException e) {
-                // Default to base uri value
-            }
-        }
-
-        return uri;
-    }
-
-    /**
      * Returns the decoded URI of the file.
      *
      * @return the FileName as a URI.
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/AbstractFileNameTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/AbstractFileNameTest.java
new file mode 100644
index 0000000..f107589
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/AbstractFileNameTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.commons.vfs2.provider;
+
+import org.apache.commons.vfs2.FileName;
+import org.apache.commons.vfs2.FileType;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AbstractFileNameTest {
+    @Test
+    public void testHashSignEncoded() {
+        AbstractFileName fileName = new AbstractFileName("file", "/foo/bar/file#name.txt", FileType.FILE) {
+            @Override
+            public FileName createName(String absolutePath, FileType fileType) {
+                return null;
+            }
+
+            @Override
+            protected void appendRootUri(StringBuilder buffer, boolean addPassword) {
+                if (addPassword) {
+                    buffer.append("pass");
+                }
+            }
+        };
+
+        Assert.assertEquals("pass/foo/bar/file%23name.txt", fileName.getURI());
+        Assert.assertEquals("/foo/bar/file%23name.txt", fileName.getFriendlyURI());
+    }
+}