< prev index next >

src/java.base/share/classes/java/io/FilePermission.java

Print this page
rev 16962 : 8177969: Faster FilePermission::implies by avoiding the use of Path::relativize

*** 1,7 **** /* ! * Copyright (c) 1997, 2015, 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. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1997, 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. Oracle designates this
*** 207,216 **** --- 207,220 ---- .getFileSystem(URI.create("file:///")); private static final Path here = builtInFS.getPath( GetPropertyAction.privilegedGetProperty("user.dir")); + private static final Path EMPTY_PATH = builtInFS.getPath(""); + private static final Path DASH_PATH = builtInFS.getPath("-"); + private static final Path DOTDOT_PATH = builtInFS.getPath(".."); + /** * A private constructor that clones some and updates some, * always with a different name. * @param input */
*** 339,349 **** // Windows. Some JDK codes generate such illegal names. npath = builtInFS.getPath(new File(name).getPath()) .normalize(); // lastName should always be non-null now Path lastName = npath.getFileName(); ! if (lastName != null && lastName.toString().equals("-")) { directory = true; recursive = !rememberStar; npath = npath.getParent(); } if (npath == null) { --- 343,353 ---- // Windows. Some JDK codes generate such illegal names. npath = builtInFS.getPath(new File(name).getPath()) .normalize(); // lastName should always be non-null now Path lastName = npath.getFileName(); ! if (lastName != null && lastName.equals(DASH_PATH)) { directory = true; recursive = !rememberStar; npath = npath.getParent(); } if (npath == null) {
*** 677,703 **** * @param p1 the expected outer path, normalized * @param p2 the expected inner path, normalized * @return the depth in between */ private static int containsPath(Path p1, Path p2) { ! Path p; ! try { ! p = p2.relativize(p1).normalize(); ! if (p.getName(0).toString().isEmpty()) { return 0; } else { ! for (Path item: p) { ! String s = item.toString(); ! if (!s.equals("..")) { return -1; } } ! return p.getNameCount(); } ! } catch (IllegalArgumentException iae) { return -1; } } /** * Checks two FilePermission objects for equality. Checks that <i>obj</i> is * a FilePermission, and has the same pathname and actions as this object. --- 681,760 ---- * @param p1 the expected outer path, normalized * @param p2 the expected inner path, normalized * @return the depth in between */ private static int containsPath(Path p1, Path p2) { ! ! // Two paths must have the same root. For example, ! // there is no contains relation between any two of ! // "/x", "x", "C:/x", "C:x", and "//host/share/x". ! if (!Objects.equals(p1.getRoot(), p2.getRoot())) { ! return -1; ! } ! ! // Empty path (i.e. "." or "") is a strange beast, ! // because its getNameCount()==1 but getName(0) is null. ! // It's better to deal with it separately. ! if (p1.equals(EMPTY_PATH)) { ! if (p2.equals(EMPTY_PATH)) { return 0; + } else if (p2.getName(0).equals(DOTDOT_PATH)) { + // "." contains p2 iif p2 has no "..". Since a + // a normalized path can only have 0 or more + // ".." at the beginning. We only need to look + // at the head. + return -1; } else { ! // and the distance is p2's name count. i.e. ! // 3 between "." and "a/b/c". ! return p2.getNameCount(); ! } ! } else if (p2.equals(EMPTY_PATH)) { ! int c1 = p1.getNameCount(); ! if (!p1.getName(c1 - 1).equals(DOTDOT_PATH)) { ! // "." is inside p1 iif p1 is 1 or more "..". ! // For the same reason above, we only need to ! // look at the tail. return -1; } + // and the distance is the count of ".." + return c1; } ! ! // Good. No more empty paths. ! ! // Common heads are removed ! ! int c1 = p1.getNameCount(); ! int c2 = p2.getNameCount(); ! ! int n = Math.min(c1, c2); ! int i = 0; ! while (i < n) { ! if (!p1.getName(i).equals(p2.getName(i))) ! break; ! i++; ! } ! ! // for p1 containing p2, p1 must be 0-or-more "..", ! // and p2 cannot have "..". For the same reason, we only ! // check tail of p1 and head of p2. ! if (i < c1 && !p1.getName(c1 - 1).equals(DOTDOT_PATH)) { ! return -1; } ! ! if (i < c2 && p2.getName(i).equals(DOTDOT_PATH)) { return -1; } + + // and the distance is the name counts added (after removing + // the common heads). + + // For example: p1 = "../../..", p2 = "../a". + // After removing the common heads, they become "../.." and "a", + // and the distance is (3-1)+(2-1) = 3. + return c1 - i + c2 - i; } /** * Checks two FilePermission objects for equality. Checks that <i>obj</i> is * a FilePermission, and has the same pathname and actions as this object.
< prev index next >