[IO-600] Fix getPrefixLength method for Linux filename (#179)
* IO-600: fix getPrefixLength method for Linux filename
* IO-600: fix javadoc
diff --git a/src/main/java/org/apache/commons/io/FilenameUtils.java b/src/main/java/org/apache/commons/io/FilenameUtils.java
index 478a1e3..bd92853 100644
--- a/src/main/java/org/apache/commons/io/FilenameUtils.java
+++ b/src/main/java/org/apache/commons/io/FilenameUtils.java
@@ -605,22 +605,23 @@ public static String separatorsToSystem(final String path) {
* than the length of the input string.
* <pre>
* Windows:
- * a\b\c.txt --> "" --> relative
- * \a\b\c.txt --> "\" --> current drive absolute
- * C:a\b\c.txt --> "C:" --> drive relative
- * C:\a\b\c.txt --> "C:\" --> absolute
- * \\server\a\b\c.txt --> "\\server\" --> UNC
- * \\\a\b\c.txt --> error, length = -1
+ * a\b\c.txt --> 0 --> relative
+ * \a\b\c.txt --> 1 --> current drive absolute
+ * C:a\b\c.txt --> 2 --> drive relative
+ * C:\a\b\c.txt --> 3 --> absolute
+ * \\server\a\b\c.txt --> 9 --> UNC
+ * \\\a\b\c.txt --> -1 --> error
*
* Unix:
- * a/b/c.txt --> "" --> relative
- * /a/b/c.txt --> "/" --> absolute
- * ~/a/b/c.txt --> "~/" --> current user
- * ~ --> "~/" --> current user (slash added)
- * ~user/a/b/c.txt --> "~user/" --> named user
- * ~user --> "~user/" --> named user (slash added)
- * //server/a/b/c.txt --> "//server/"
- * ///a/b/c.txt --> error, length = -1
+ * a/b/c.txt --> 0 --> relative
+ * /a/b/c.txt --> 1 --> absolute
+ * ~/a/b/c.txt --> 2 --> current user
+ * ~ --> 2 --> current user (slash added)
+ * ~user/a/b/c.txt --> 6 --> named user
+ * ~user --> 6 --> named user (slash added)
+ * //server/a/b/c.txt --> 9
+ * ///a/b/c.txt --> -1 --> error
+ * C: --> 0 --> valid filename as only null byte and / are reserved characters
* </pre>
* <p>
* The output will be the same irrespective of the machine that the code is running on.
@@ -665,7 +666,10 @@ public static int getPrefixLength(final String fileName) {
if (ch1 == ':') {
ch0 = Character.toUpperCase(ch0);
if (ch0 >= 'A' && ch0 <= 'Z') {
- if (len == 2 || isSeparator(fileName.charAt(2)) == false) {
+ if (len == 2 && !FileSystem.getCurrent().supportsDriveLetter()) {
+ return 0;
+ }
+ if (len == 2 || !isSeparator(fileName.charAt(2))) {
return 2;
}
return 3;
diff --git a/src/test/java/org/apache/commons/io/FilenameUtilsTestCase.java b/src/test/java/org/apache/commons/io/FilenameUtilsTestCase.java
index 2fe5028..5a6599e 100644
--- a/src/test/java/org/apache/commons/io/FilenameUtilsTestCase.java
+++ b/src/test/java/org/apache/commons/io/FilenameUtilsTestCase.java
@@ -31,6 +31,7 @@
import java.util.Collection;
import org.apache.commons.io.test.TestUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -554,7 +555,14 @@ public void testGetPrefixLength() {
assertEquals(0, FilenameUtils.getPrefixLength(""));
assertEquals(1, FilenameUtils.getPrefixLength("\\"));
- assertEquals(2, FilenameUtils.getPrefixLength("C:"));
+
+ if (SystemUtils.IS_OS_WINDOWS) {
+ assertEquals(2, FilenameUtils.getPrefixLength("C:"));
+ }
+ if (SystemUtils.IS_OS_LINUX) {
+ assertEquals(0, FilenameUtils.getPrefixLength("C:"));
+ }
+
assertEquals(3, FilenameUtils.getPrefixLength("C:\\"));
assertEquals(9, FilenameUtils.getPrefixLength("//server/"));
assertEquals(2, FilenameUtils.getPrefixLength("~"));
@@ -645,7 +653,14 @@ public void testGetPrefix() {
assertEquals("", FilenameUtils.getPrefix(""));
assertEquals("\\", FilenameUtils.getPrefix("\\"));
- assertEquals("C:", FilenameUtils.getPrefix("C:"));
+
+ if (SystemUtils.IS_OS_WINDOWS) {
+ assertEquals("C:", FilenameUtils.getPrefix("C:"));
+ }
+ if (SystemUtils.IS_OS_LINUX) {
+ assertEquals("", FilenameUtils.getPrefix("C:"));
+ }
+
assertEquals("C:\\", FilenameUtils.getPrefix("C:\\"));
assertEquals("//server/", FilenameUtils.getPrefix("//server/"));
assertEquals("~/", FilenameUtils.getPrefix("~"));
@@ -786,7 +801,14 @@ public void testGetFullPath() {
assertEquals(null, FilenameUtils.getFullPath("//a"));
assertEquals("", FilenameUtils.getFullPath(""));
- assertEquals("C:", FilenameUtils.getFullPath("C:"));
+
+ if (SystemUtils.IS_OS_WINDOWS) {
+ assertEquals("C:", FilenameUtils.getFullPath("C:"));
+ }
+ if (SystemUtils.IS_OS_LINUX) {
+ assertEquals("", FilenameUtils.getFullPath("C:"));
+ }
+
assertEquals("C:/", FilenameUtils.getFullPath("C:/"));
assertEquals("//server/", FilenameUtils.getFullPath("//server/"));
assertEquals("~/", FilenameUtils.getFullPath("~"));
@@ -821,7 +843,14 @@ public void testGetFullPathNoEndSeparator() {
assertEquals(null, FilenameUtils.getFullPathNoEndSeparator("//a"));
assertEquals("", FilenameUtils.getFullPathNoEndSeparator(""));
- assertEquals("C:", FilenameUtils.getFullPathNoEndSeparator("C:"));
+
+ if (SystemUtils.IS_OS_WINDOWS) {
+ assertEquals("C:", FilenameUtils.getFullPathNoEndSeparator("C:"));
+ }
+ if (SystemUtils.IS_OS_LINUX) {
+ assertEquals("", FilenameUtils.getFullPathNoEndSeparator("C:"));
+ }
+
assertEquals("C:/", FilenameUtils.getFullPathNoEndSeparator("C:/"));
assertEquals("//server/", FilenameUtils.getFullPathNoEndSeparator("//server/"));
assertEquals("~", FilenameUtils.getFullPathNoEndSeparator("~"));