8140449: (fs) Paths.get("x").relativize("") return ..\ on Windows
authoralanb
Fri, 17 Jun 2016 17:17:21 +0100
changeset 39058 b1ab5b47d979
parent 39057 3ad96930e68b
child 39059 a51b9d78b20c
8140449: (fs) Paths.get("x").relativize("") return ..\ on Windows Reviewed-by: chegar, rriggs
jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java
jdk/test/java/nio/file/Path/PathOps.java
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java	Fri Jun 17 16:18:37 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java	Fri Jun 17 17:17:21 2016 +0100
@@ -243,13 +243,13 @@
             // relative to default directory
             String remaining = path.substring(root.length());
             String defaultDirectory = getFileSystem().defaultDirectory();
-            String result;
-            if (defaultDirectory.endsWith("\\")) {
-                result = defaultDirectory + remaining;
+            if (remaining.length() == 0) {
+                return defaultDirectory;
+            } else if (defaultDirectory.endsWith("\\")) {
+                 return defaultDirectory + remaining;
             } else {
-                result = defaultDirectory + "\\" + remaining;
+                return defaultDirectory + "\\" + remaining;
             }
-            return result;
         } else {
             // relative to some other drive
             String wd;
@@ -412,9 +412,11 @@
         }
 
         // append remaining names in child
-        for (int j=i; j<cn; j++) {
-            result.append(other.getName(j).toString());
-            result.append("\\");
+        if (!other.isEmpty()) {
+            for (int j=i; j<cn; j++) {
+                result.append(other.getName(j).toString());
+                result.append("\\");
+            }
         }
 
         // drop trailing slash in result
--- a/jdk/test/java/nio/file/Path/PathOps.java	Fri Jun 17 16:18:37 2016 +0200
+++ b/jdk/test/java/nio/file/Path/PathOps.java	Fri Jun 17 17:17:21 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,23 +22,24 @@
  */
 
 /* @test
- * @bug 4313887 6838333 6925932 7006126 8037945 8072495
+ * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449
  * @summary Unit test for java.nio.file.Path path operations
  */
 
-import java.nio.file.*;
+import java.nio.file.FileSystems;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 
 public class PathOps {
 
     static final java.io.PrintStream out = System.out;
 
-    private String input;
     private Path path;
     private Exception exc;
 
     private PathOps(String first, String... more) {
         out.println();
-        input = first;
         try {
             path = FileSystems.getDefault().getPath(first, more);
             out.format("%s -> %s", first, path);
@@ -87,6 +88,14 @@
         return this;
     }
 
+    PathOps hasRoot() {
+        out.println("check has root");
+        checkPath();
+        if (path.getRoot() == null)
+            fail();
+        return this;
+    }
+
     PathOps parent(String expected) {
         out.println("check parent");
         checkPath();
@@ -147,6 +156,11 @@
         return this;
     }
 
+    PathOps makeAbsolute() {
+        this.path = path.toAbsolutePath();
+        return this;
+    }
+
     PathOps absolute() {
         out.println("check path is absolute");
         checkPath();
@@ -209,6 +223,11 @@
         return new PathOps(first, more);
     }
 
+    static PathOps test(Path path) {
+        return new PathOps(path.toString());
+    }
+
+
     // -- PathOpss --
 
     static void header(String s) {
@@ -219,6 +238,7 @@
 
     static void doWindowsTests() {
         header("Windows specific tests");
+        Path cwd = Paths.get("").toAbsolutePath();
 
         // construction
         test("C:\\")
@@ -417,6 +437,52 @@
         test("C:\\abc").absolute();
         test("\\\\server\\share\\").absolute();
         test("").notAbsolute();
+        test(cwd).absolute();
+
+        // toAbsolutePath
+        test("")
+            .makeAbsolute()
+            .absolute()
+            .hasRoot()
+            .string(cwd.toString());
+        test(".")
+            .makeAbsolute()
+            .absolute()
+            .hasRoot()
+            .string(cwd.toString() + "\\.");
+        test("foo")
+            .makeAbsolute()
+            .absolute()
+            .hasRoot()
+            .string(cwd.toString() + "\\foo");
+
+        String rootAsString = cwd.getRoot().toString();
+        if (rootAsString.length() == 3
+                && rootAsString.charAt(1) == ':'
+                && rootAsString.charAt(2) == '\\') {
+            Path root = Paths.get(rootAsString.substring(0, 2));
+
+            // C:
+            test(root)
+                .makeAbsolute()
+                .absolute()
+                .hasRoot()
+                .string(cwd.toString());
+
+            // C:.
+            test(root + ".")
+                .makeAbsolute()
+                .absolute()
+                .hasRoot()
+                .string(cwd.toString() + "\\.");
+
+            // C:foo
+            test(root + "foo")
+                .makeAbsolute()
+                .absolute()
+                .hasRoot()
+                .string(cwd.toString() + "\\foo");
+        }
 
         // resolve
         test("C:\\")
@@ -506,19 +572,29 @@
             .resolveSibling("C:\\", "C:\\");
 
         // relativize
+        test("foo")
+            .relativize("foo", "")
+            .relativize("bar", "..\\bar")
+            .relativize("..", "..\\..")
+            .relativize("", "..");
         test("foo\\bar")
             .relativize("foo\\bar", "")
-            .relativize("foo", "..");
+            .relativize("foo", "..")
+            .relativize("gus", "..\\..\\gus")
+            .relativize("..", "..\\..\\..")
+            .relativize("", "..\\..");
         test("C:\\a\\b\\c")
             .relativize("C:\\a", "..\\..")
-            .relativize("C:\\a\\b\\c", "");
+            .relativize("C:\\a\\b\\c", "")
+            .relativize("C:\\x", "..\\..\\..\\x");
         test("\\\\server\\share\\foo")
             .relativize("\\\\server\\share\\bar", "..\\bar")
             .relativize("\\\\server\\share\\foo", "");
         test("")
-            .relativize("", "")
             .relativize("a", "a")
-            .relativize("a\\b\\c", "a\\b\\c");
+            .relativize("a\\b\\c", "a\\b\\c")
+            .relativize("..", "..")
+            .relativize("", "");
 
         // normalize
         test("C:\\")
@@ -672,6 +748,7 @@
 
     static void doUnixTests() {
         header("Unix specific tests");
+        Path cwd = Paths.get("").toAbsolutePath();
 
         // construction
         test("/")
@@ -840,7 +917,22 @@
             .notAbsolute();
         test("")
             .notAbsolute();
+        test(cwd)
+            .absolute();
 
+        // toAbsolutePath
+        test("/")
+            .makeAbsolute()
+            .absolute();
+        test("/tmp")
+            .makeAbsolute()
+            .absolute();
+        test("tmp")
+            .makeAbsolute()
+            .absolute();
+        test("")
+            .makeAbsolute()
+            .absolute();
 
         // resolve
         test("/tmp")