| /* | |
| * Copyright (c) 2016, 2017, 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 | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| /** | |
| * | |
| * @test | |
| * @bug 8164705 | |
| * @modules java.base/java.io:open | |
| * @summary Remove pathname canonicalization from FilePermission | |
| */ | |
| import java.io.FilePermission; | |
| import java.lang.reflect.Method; | |
| import java.nio.file.Path; | |
| import java.nio.file.Paths; | |
| public class Correctness { | |
| static boolean err = false; | |
| static Method containsMethod; | |
| static boolean isWindows = | |
| System.getProperty("os.name").contains("Windows"); | |
| public static void main(String args[]) throws Exception { | |
| check("/", "/"); | |
| checkNo("/", "/x"); | |
| checkNo("/", "/../x"); | |
| checkNo("/", "x"); | |
| check("/-", "/*"); | |
| checkNo("/*", "/-"); | |
| check("/*", "/x"); | |
| check("/-", "/x"); | |
| check("/-", "/x/*"); | |
| check("/-", "/x/-"); | |
| check("/-", "/x/y"); | |
| checkNo("/*", "/x/y"); | |
| check("/x/*", "/x/x"); | |
| checkNo("/x/-", "/x"); | |
| checkNo("/x/*", "/x"); | |
| check("/x/-", "/x/x"); | |
| check("/x/-", "/x/x/y"); | |
| checkNo("/x/*", "/x/x/y"); | |
| checkNo("/x/*", "/x"); | |
| check("*", "x"); | |
| checkNo("", "x"); | |
| check("-", "x"); | |
| check("-", "*"); | |
| check("-", "a/-"); | |
| check("-", "a/*"); | |
| checkNo("*", "a/b"); | |
| check("a/*", "a/b"); | |
| check("a/-", "a/*"); | |
| check("a/-", "a/b/c"); | |
| checkNo("a/*", "a/b/c"); | |
| check("../", "../"); | |
| check("../-", "../*"); | |
| check("../../*", "../../a"); | |
| // If we allow .. and abs/rel checks | |
| check("../-", "a"); | |
| check("../../-", "-"); | |
| checkNo("../../*", "a"); | |
| //check("/-", "a"); | |
| //checkNo("/*", "a"); | |
| //check("/-", "-"); | |
| try { | |
| containsMethod = FilePermission.class.getDeclaredMethod( | |
| "containsPath", Path.class, Path.class); | |
| containsMethod.setAccessible(true); | |
| System.out.println(); | |
| // The 1st 2 args of contains() must be normalized paths. | |
| // When FilePermission::containsPath is called by implies, | |
| // paths have already been normalized. | |
| contains("x", "x", 0); | |
| contains("x", "x/y", 1); | |
| contains("x", "x/y/z", 2); | |
| contains("x", "y", -1); | |
| contains("x", "", -1); | |
| contains("", "", 0); | |
| contains("", "x", 1); | |
| contains("", "x/y", 2); | |
| contains("/", "/", 0); | |
| contains("/", "/x", 1); | |
| contains("/", "/x/y", 2); | |
| contains("/x", "/x/y", 1); | |
| contains("/x", "/y", -1); | |
| //contains("/", "..", Integer.MAX_VALUE); | |
| //contains("/", "x", Integer.MAX_VALUE); | |
| //contains("/", "x/y", Integer.MAX_VALUE); | |
| //contains("/", "../x", Integer.MAX_VALUE); | |
| contains("/x", "y", -1); | |
| contains("x", "/y", -1); | |
| contains("", "..", -1); | |
| contains("", "../x", -1); | |
| contains("..", "", 1); | |
| contains("..", "x", 2); | |
| contains("..", "x/y", 3); | |
| contains("../x", "x", -1); | |
| contains("../x", "y", -1); | |
| contains("../x", "../x/y", 1); | |
| contains("../../x", "../../x/y", 1); | |
| contains("../../../x", "../../../x/y", 1); | |
| contains("../x", "../y", -1); | |
| } catch (NoSuchMethodException e) { | |
| // Ignored | |
| } | |
| if (err) throw new Exception("Failed."); | |
| } | |
| // Checks if s2 is inside s1 and depth is expected. | |
| static void contains(String s1, String s2, int expected) throws Exception { | |
| contains0(s1, s2, expected); | |
| if (isWindows) { | |
| contains0("C:" + s1, s2, -1); | |
| contains0(s1, "C:" + s2, -1); | |
| contains0("C:" + s1, "D:" + s2, -1); | |
| contains0("C:" + s1, "C:" + s2, expected); | |
| } | |
| } | |
| static void contains0(String s1, String s2, int expected) throws Exception { | |
| Path p1 = Paths.get(s1); | |
| Path p2 = Paths.get(s2); | |
| int d = (int)containsMethod.invoke(null, p1, p2); | |
| Path p; | |
| try { | |
| p = p2.relativize(p1); | |
| } catch (Exception e) { | |
| p = null; | |
| } | |
| System.out.printf("%-20s -> %-20s: %20s %5d %5d %s\n", s1, s2, p, | |
| d, expected, d==expected?"":" WRONG"); | |
| if (d != expected) { | |
| err = true; | |
| } | |
| } | |
| static void check0(String s1, String s2, boolean expected) { | |
| FilePermission fp1 = new FilePermission(s1, "read"); | |
| FilePermission fp2 = new FilePermission(s2, "read"); | |
| boolean b = fp1.implies(fp2); | |
| System.out.printf("%-30s -> %-30s: %5b %s\n", | |
| s1, s2, b, b==expected?"":" WRONG"); | |
| if (b != expected) { | |
| err = true; | |
| System.out.println(fp1); | |
| System.out.println(fp2); | |
| } | |
| } | |
| static void check(String s1, String s2, boolean expected) { | |
| check0(s1, s2, expected); | |
| if (isWindows) { | |
| check0("C:" + s1, s2, false); | |
| check0(s1, "C:" + s2, false); | |
| check0("C:" + s1, "D:" + s2, false); | |
| check0("C:" + s1, "C:" + s2, expected); | |
| } | |
| } | |
| static void check(String s1, String s2) { | |
| check(s1, s2, true); | |
| } | |
| static void checkNo(String s1, String s2) { | |
| check(s1, s2, false); | |
| } | |
| } |