Correctness.java revision 16177:89ef4b822745
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
32import java.io.FilePermission;
33import java.lang.reflect.Method;
34import java.nio.file.Path;
35import java.nio.file.Paths;
36
37public 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}
184