1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * 26 * @test 27 * @bug 8164705 28 * @modules java.base/java.io:open 29 * @summary Remove pathname canonicalization from FilePermission 30 */ 31 32 import java.io.FilePermission; 33 import java.lang.reflect.Method; 34 import java.nio.file.Path; 35 import java.nio.file.Paths; 36 37 public class Correctness { 38 39 static boolean err = false; 40 static Method containsMethod; 41 static boolean isWindows = 42 System.getProperty("os.name").contains("Windows"); 43 public static void main(String args[]) throws Exception { 44 check("/", "/"); 45 checkNo("/", "/x"); 46 checkNo("/", "/../x"); 47 48 checkNo("/", "x"); 49 50 check("/-", "/*"); 51 checkNo("/*", "/-"); 52 53 check("/*", "/x"); 54 check("/-", "/x"); 55 check("/-", "/x/*"); 56 check("/-", "/x/-"); 57 check("/-", "/x/y"); 58 checkNo("/*", "/x/y"); 59 check("/x/*", "/x/x"); 60 checkNo("/x/-", "/x"); 61 checkNo("/x/*", "/x"); 62 check("/x/-", "/x/x"); 63 check("/x/-", "/x/x/y"); 64 checkNo("/x/*", "/x/x/y"); 65 checkNo("/x/*", "/x"); 66 67 check("*", "x"); 68 checkNo("", "x"); 69 check("-", "x"); 70 check("-", "*"); 71 check("-", "a/-"); 72 check("-", "a/*"); 73 checkNo("*", "a/b"); 74 check("a/*", "a/b"); 75 check("a/-", "a/*"); 76 check("a/-", "a/b/c"); 77 checkNo("a/*", "a/b/c"); 78 79 check("../", "../"); 80 check("../-", "../*"); 81 check("../../*", "../../a"); 82 83 // If we allow .. and abs/rel checks 84 check("../-", "a"); 85 check("../../-", "-"); 86 checkNo("../../*", "a"); 87 //check("/-", "a"); 88 //checkNo("/*", "a"); 89 //check("/-", "-"); 90 91 try { 92 // containsPath is broken on Windows. 93 containsMethod = FilePermission.class.getDeclaredMethod( 94 "containsPath", Path.class, Path.class); 95 containsMethod.setAccessible(true); 96 System.out.println(); 97 98 contains("x", "x", 0); 99 contains("x", "x/y", 1); 100 contains("x", "x/y/z", 2); 101 contains("x", "y", -1); 102 contains("x", "", -1); 103 contains("", "", 0); 104 contains("", "x", 1); 105 contains("", "x/y", 2); 106 contains("/", "/", 0); 107 contains("/", "/x", 1); 108 contains("/", "/x/y", 2); 109 contains("/x", "/x/y", 1); 110 contains("/x", "/y", -1); 111 //contains("/", "..", Integer.MAX_VALUE); 112 //contains("/", "x", Integer.MAX_VALUE); 113 //contains("/", "x/y", Integer.MAX_VALUE); 114 //contains("/", "../x", Integer.MAX_VALUE); 115 contains("/x", "y", -1); 116 contains("x", "/y", -1); 117 118 contains("", "..", -1); 119 contains("", "../x", -1); 120 contains("..", "", 1); 121 contains("..", "x", 2); 122 contains("..", "x/y", 3); 123 contains("../x", "x", -1); 124 contains("../x", "y", -1); 125 contains("../x", "../x/y", 1); 126 contains("../../x", "../../x/y", 1); 127 contains("../../../x", "../../../x/y", 1); 128 contains("../x", "../y", -1); 129 } catch (NoSuchMethodException e) { 130 // Ignored 131 } 132 if (err) throw new Exception("Failed."); 133 } 134 135 // Checks if s2 is inside s1 and depth is expected. 136 static void contains(String s1, String s2, int expected) throws Exception { 137 contains0(s1, s2, expected); 138 if (isWindows) { 139 contains0("C:" + s1, s2, -1); 140 contains0(s1, "C:" + s2, -1); 141 contains0("C:" + s1, "D:" + s2, -1); 142 contains0("C:" + s1, "C:" + s2, expected); 143 } 144 } 145 146 static void contains0(String s1, String s2, int expected) throws Exception { 147 Path p1 = Paths.get(s1); 148 Path p2 = Paths.get(s2); 149 int d = (int)containsMethod.invoke(null, p1, p2); 150 Path p; 151 try { 152 p = p2.relativize(p1); 153 } catch (Exception e) { 154 p = null; 155 } 156 System.out.printf("%-20s -> %-20s: %20s %5d %5d %s\n", s1, s2, p, 157 d, expected, d==expected?"":" WRONG"); 158 if (d != expected) { 159 err = true; 160 } 161 } 162 163 static void check(String s1, String s2, boolean expected) { 164 FilePermission fp1 = new FilePermission(s1, "read"); 165 FilePermission fp2 = new FilePermission(s2, "read"); 166 boolean b = fp1.implies(fp2); 167 System.out.printf("%-30s -> %-30s: %5b %s\n", 168 s1, s2, b, b==expected?"":" WRONG"); 169 if (b != expected) { 170 err = true; 171 System.out.println(fp1); 172 System.out.println(fp2); 173 } 174 } 175 176 static void check(String s1, String s2) { 177 check(s1, s2, true); 178 } 179 180 static void checkNo(String s1, String s2) { 181 check(s1, s2, false); 182 } 183 }