< 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 >