changeset 1416:4f0d82b723ca

sanitizing of paths made windows friendly * netx/net/sourceforge/jnlp/util/FileUtils.java: (INVALID_CHARS) replaced by INVALID_PATH for filtering paths, and INVALID_NAME, based on INVALID_PATH with slashes, for filtering chars form name. (sanitizePath) and (sanitizeFileName) rewrote to use adequate list, and get rid of unreliable separator - windows can have both. In addition. (sanitizePath) enhanced to deal with absolute X:\ windows path and keep filtering any other colons. * tests/netx/unit/net/sourceforge/jnlp/util/FileUtilsTest.java: test adapted to new logic. Added tests for new cases,added tests for some cornercases
author Jiri Vanek <jvanek@redhat.com>
date Thu, 04 May 2017 12:36:45 +0200
parents 0c05ca429063
children 586e12244c40
files ChangeLog netx/net/sourceforge/jnlp/util/FileUtils.java tests/netx/unit/net/sourceforge/jnlp/util/FileUtilsTest.java
diffstat 3 files changed, 99 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed May 03 18:49:07 2017 +0200
+++ b/ChangeLog	Thu May 04 12:36:45 2017 +0200
@@ -1,3 +1,16 @@
+2017-05-04  Jiri Vanek <jvanek@redhat.com>
+            Adam Buchta  <adbuch7@gmail.com>
+
+	sanitizing of paths made windows friendly
+	* netx/net/sourceforge/jnlp/util/FileUtils.java: (INVALID_CHARS) replaced by INVALID_PATH
+	for filtering paths, and INVALID_NAME, based on INVALID_PATH with slashes, for filtering
+	chars form name. (sanitizePath) and (sanitizeFileName) rewrote to use adequate list, and get
+	rid of unreliable separator - windows can have both.  In addition. (sanitizePath) enhanced
+	to deal with absolute X:\ windows path and keep filtering any other colons.
+	* tests/netx/unit/net/sourceforge/jnlp/util/FileUtilsTest.java: test
+	adapted to new logic. Added tests for new cases,added tests for some
+	cornercases
+
 2017-05-03  Jiri Vanek <jvanek@redhat.com>
 
 	* javaws.desktop.in: added x-scheme-handler/jnlp;x-scheme-handler/jnlps
--- a/netx/net/sourceforge/jnlp/util/FileUtils.java	Wed May 03 18:49:07 2017 +0200
+++ b/netx/net/sourceforge/jnlp/util/FileUtils.java	Thu May 04 12:36:45 2017 +0200
@@ -17,7 +17,6 @@
 package net.sourceforge.jnlp.util;
 
 import java.awt.Component;
-import static net.sourceforge.jnlp.runtime.Translator.R;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -38,6 +37,7 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import javax.swing.JFrame;
@@ -48,6 +48,7 @@
 import net.sourceforge.jnlp.config.DirectoryValidator.DirectoryCheckResults;
 import net.sourceforge.jnlp.runtime.JNLPRuntime;
 import net.sourceforge.jnlp.util.logging.OutputController;
+import static net.sourceforge.jnlp.runtime.Translator.R;
 
 /**
  * This class contains a few file-related utility functions.
@@ -57,6 +58,8 @@
 
 public final class FileUtils {
 
+    private static final String WIN_DRIVE_LETTER_COLON_WILDCHAR = "WINDOWS_VERY_SPECIFIC_DOUBLEDOT";
+
     /**
      * Indicates whether a file was successfully opened. If not, provides specific reasons
      * along with a general failure case
@@ -77,7 +80,13 @@
     /**
      * list of characters not allowed in filenames
      */
-    public static final char INVALID_CHARS[] = {'\\', '/', ':', '*', '?', '"', '<', '>', '|', '[', ']', '\'', ';', '=', ','};
+    public static final List<Character> INVALID_PATH = Arrays.asList(new Character[]{':', '*', '?', '"', '<', '>', '|', '[', ']', '\'', ';', '=', ','});
+    public static final List<Character> INVALID_NAME = new ArrayList<>(INVALID_PATH);
+
+    static {
+        INVALID_NAME.add(0, '\\');
+        INVALID_NAME.add(0, '/');
+    }
 
     private static final char SANITIZED_CHAR = '_';
 
@@ -85,25 +94,28 @@
      * Clean up a string by removing characters that can't appear in a local
      * file name.
      *
-     * @param path
-     *        the path to sanitize
+     * @param path the path to sanitize
      * @return a sanitized version of the input which is suitable for using as a
-     *         file path
+     * file path
      */
     public static String sanitizePath(String path) {
         return sanitizePath(path, SANITIZED_CHAR);
     }
 
     public static String sanitizePath(String path, char substitute) {
-
-        for (int i = 0; i < INVALID_CHARS.length; i++) {
-            if (INVALID_CHARS[i] != File.separatorChar) {
-                if (-1 != path.indexOf(INVALID_CHARS[i])) {
-                    path = path.replace(INVALID_CHARS[i], substitute);
-                }
+        //on windows, we can recieve both c:/path/ and c:\path\
+        path = path.replace("\\", "/");
+        if (JNLPRuntime.isWindows() && path.matches("^[a-zA-Z]\\:.*")) {
+            path = path.replaceFirst(":", WIN_DRIVE_LETTER_COLON_WILDCHAR);
+        }
+        for (int i = 0; i < INVALID_PATH.size(); i++) {
+            if (-1 != path.indexOf(INVALID_PATH.get(i))) {
+                path = path.replace(INVALID_PATH.get(i), substitute);
             }
         }
-
+        if (JNLPRuntime.isWindows()) {
+            path = path.replaceFirst(WIN_DRIVE_LETTER_COLON_WILDCHAR, ":");
+        }
         return path;
     }
 
@@ -120,9 +132,9 @@
 
     public static String sanitizeFileName(String filename, char substitute) {
 
-        for (int i = 0; i < INVALID_CHARS.length; i++) {
-            if (-1 != filename.indexOf(INVALID_CHARS[i])) {
-                filename = filename.replace(INVALID_CHARS[i], substitute);
+        for (int i = 0; i < INVALID_NAME.size(); i++) {
+            if (-1 != filename.indexOf(INVALID_NAME.get(i))) {
+                filename = filename.replace(INVALID_NAME.get(i), substitute);
             }
         }
 
--- a/tests/netx/unit/net/sourceforge/jnlp/util/FileUtilsTest.java	Wed May 03 18:49:07 2017 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/util/FileUtilsTest.java	Thu May 04 12:36:45 2017 +0200
@@ -34,10 +34,13 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version.
  */
-
 package net.sourceforge.jnlp.util;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
 
 import org.junit.Test;
 
@@ -45,35 +48,74 @@
 
 public class FileUtilsTest {
 
-    private static final char[] INVALID = {
-            '\\',
-            '/',
-            ':',
-            '*',
-            '?',
-            '"',
-            '<',
-            '>',
-            '|', };
-    private static final char SANITIZED = '_';
+    public static final List<Character> INVALID_PATH = Arrays.asList(new Character[]{':', '*', '?', '"', '<', '>', '|', '[', ']', '\'', ';', '=', ','});
+    public static final List<Character> INVALID_NAME = new ArrayList<>(INVALID_PATH);
+
+    static {
+        INVALID_NAME.add(0, '\\');
+        INVALID_NAME.add(0, '/');
+    }
 
     @Test
     public void testSanitizePath() throws Exception {
-        for (char ch : INVALID) {
-            String str = File.separator + "tmp" + File.separator + "test" + ch + "path";
+        for (char ch : INVALID_PATH) {
+            String str = "/tmp/test" + ch + "path";
             String sanitized = FileUtils.sanitizePath(str);
             assertFalse(ch + " should be sanitized from " + sanitized, ch != File.separatorChar && sanitized.contains(Character.toString(ch)));
-            assertEquals(str.replace(ch, ch == File.separatorChar ? ch : SANITIZED), sanitized);
+            assertEquals("/tmp/test_path", sanitized);
+        }
+    }
+
+    @Test
+    public void testSanitizeMoreDoubleDots() throws Exception {
+        String str = "C:/some:dir/some:file";
+        String sanitized = FileUtils.sanitizePath(str);
+        if (JNLPRuntime.isWindows()) {
+            assertEquals("C:/some_dir/some_file", sanitized);
+        } else {
+            assertEquals("C_/some_dir/some_file", sanitized);
+        }
+    }
+
+    @Test
+    public void testSanitizePathWindowsLinuxSlashes() throws Exception {
+        String str = "C:/some.dir/some.file";
+        String sanitized = FileUtils.sanitizePath(str);
+        if (JNLPRuntime.isWindows()) {
+            assertEquals("C:/some.dir/some.file", sanitized);
+        } else {
+            assertEquals("C_/some.dir/some.file", sanitized);
+        }
+    }
+
+    @Test
+    public void testSanitizePathWindowsWinSlashes() throws Exception {
+        String str = "C:\\some.dir\\some.file";
+        String sanitized = FileUtils.sanitizePath(str);
+        if (JNLPRuntime.isWindows()) {
+            assertEquals("C:/some.dir/some.file", sanitized);
+        } else {
+            assertEquals("C_/some.dir/some.file", sanitized);
         }
     }
 
     @Test
     public void testSanitizeFilename() throws Exception {
-        for (char ch : INVALID) {
+        for (char ch : INVALID_PATH) {
             String str = "file" + ch + "name";
             String sanitized = FileUtils.sanitizeFileName(str);
             assertFalse(ch + " should be sanitized from " + sanitized, sanitized.contains(Character.toString(ch)));
-            assertEquals(str.replace(ch, SANITIZED), sanitized);
+            assertEquals("file_name", sanitized);
+        }
+    }
+
+    @Test
+    public void testSanitizeFilenameSlashes() throws Exception {
+        for (char ch : new char[]{'/', '\\'}) {
+            String str = "file" + ch + "name";
+            String sanitized = FileUtils.sanitizeFileName(str);
+            assertFalse(ch + " should be sanitized from " + sanitized, sanitized.contains(Character.toString(ch)));
+            assertEquals("file_name", sanitized);
         }
     }