1 /*
2 * Copyright (c) 1997, 2015, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
192 // sb.append('\n');
193 // }
194 // }
195 // sb.append("***\n");
196 // return sb.toString();
197 // }
198
199 private static final long serialVersionUID = 7930732926638008763L;
200
201 /**
202 * Always use the internal default file system, in case it was modified
203 * with java.nio.file.spi.DefaultFileSystemProvider.
204 */
205 private static final java.nio.file.FileSystem builtInFS =
206 DefaultFileSystemProvider.create()
207 .getFileSystem(URI.create("file:///"));
208
209 private static final Path here = builtInFS.getPath(
210 GetPropertyAction.privilegedGetProperty("user.dir"));
211
212 /**
213 * A private constructor that clones some and updates some,
214 * always with a different name.
215 * @param input
216 */
217 private FilePermission(String name,
218 FilePermission input,
219 Path npath,
220 Path npath2,
221 int mask,
222 String actions) {
223 super(name);
224 // Customizables
225 this.npath = npath;
226 this.npath2 = npath2;
227 this.actions = actions;
228 this.mask = mask;
229 // Cloneds
230 this.allFiles = input.allFiles;
231 this.invalid = input.invalid;
324 allFiles = true;
325 npath = builtInFS.getPath("");
326 // other fields remain default
327 return;
328 }
329
330 boolean rememberStar = false;
331 if (name.endsWith("*")) {
332 rememberStar = true;
333 recursive = false;
334 name = name.substring(0, name.length()-1) + "-";
335 }
336
337 try {
338 // new File() can "normalize" some name, for example, "/C:/X" on
339 // Windows. Some JDK codes generate such illegal names.
340 npath = builtInFS.getPath(new File(name).getPath())
341 .normalize();
342 // lastName should always be non-null now
343 Path lastName = npath.getFileName();
344 if (lastName != null && lastName.toString().equals("-")) {
345 directory = true;
346 recursive = !rememberStar;
347 npath = npath.getParent();
348 }
349 if (npath == null) {
350 npath = builtInFS.getPath("");
351 }
352 invalid = false;
353 } catch (InvalidPathException ipe) {
354 // Still invalid. For compatibility reason, accept it
355 // but make this permission useless.
356 npath = builtInFS.getPath("-u-s-e-l-e-s-s-");
357 invalid = true;
358 }
359
360 } else {
361 if ((cpath = getName()) == null)
362 throw new NullPointerException("name can't be null");
363
364 this.mask = mask;
662 return (this.cpath.equals(that.cpath));
663 }
664 }
665 }
666
667 /**
668 * Returns the depth between an outer path p1 and an inner path p2. -1
669 * is returned if
670 *
671 * - p1 does not contains p2.
672 * - this is not decidable. For example, p1="../x", p2="y".
673 * - the depth is not decidable. For example, p1="/", p2="x".
674 *
675 * This method can return 2 if the depth is greater than 2.
676 *
677 * @param p1 the expected outer path, normalized
678 * @param p2 the expected inner path, normalized
679 * @return the depth in between
680 */
681 private static int containsPath(Path p1, Path p2) {
682 Path p;
683 try {
684 p = p2.relativize(p1).normalize();
685 if (p.getName(0).toString().isEmpty()) {
686 return 0;
687 } else {
688 for (Path item: p) {
689 String s = item.toString();
690 if (!s.equals("..")) {
691 return -1;
692 }
693 }
694 return p.getNameCount();
695 }
696 } catch (IllegalArgumentException iae) {
697 return -1;
698 }
699 }
700
701 /**
702 * Checks two FilePermission objects for equality. Checks that <i>obj</i> is
703 * a FilePermission, and has the same pathname and actions as this object.
704 *
705 * @implNote More specifically, two pathnames are the same if and only if
706 * they have the same wildcard flag and their {@code cpath}
707 * (if {@code jdk.io.permissionsUseCanonicalPath} is {@code true}) or
708 * {@code npath} (if {@code jdk.io.permissionsUseCanonicalPath}
709 * is {@code false}) are equal. Or they are both {@literal "<<ALL FILES>>"}.
710 * <p>
711 * When {@code jdk.io.permissionsUseCanonicalPath} is {@code false}, an
712 * invalid {@code FilePermission} does not equal to any object except
713 * for itself, even if they are created using the same invalid path.
714 *
715 * @param obj the object we are testing for equality with this object.
716 * @return <code>true</code> if obj is a FilePermission, and has the same
717 * pathname and actions as this FilePermission object,
718 * <code>false</code> otherwise.
|
1 /*
2 * Copyright (c) 1997, 2017, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
192 // sb.append('\n');
193 // }
194 // }
195 // sb.append("***\n");
196 // return sb.toString();
197 // }
198
199 private static final long serialVersionUID = 7930732926638008763L;
200
201 /**
202 * Always use the internal default file system, in case it was modified
203 * with java.nio.file.spi.DefaultFileSystemProvider.
204 */
205 private static final java.nio.file.FileSystem builtInFS =
206 DefaultFileSystemProvider.create()
207 .getFileSystem(URI.create("file:///"));
208
209 private static final Path here = builtInFS.getPath(
210 GetPropertyAction.privilegedGetProperty("user.dir"));
211
212 private static final Path EMPTY_PATH = builtInFS.getPath("");
213 private static final Path DASH_PATH = builtInFS.getPath("-");
214 private static final Path DOTDOT_PATH = builtInFS.getPath("..");
215
216 /**
217 * A private constructor that clones some and updates some,
218 * always with a different name.
219 * @param input
220 */
221 private FilePermission(String name,
222 FilePermission input,
223 Path npath,
224 Path npath2,
225 int mask,
226 String actions) {
227 super(name);
228 // Customizables
229 this.npath = npath;
230 this.npath2 = npath2;
231 this.actions = actions;
232 this.mask = mask;
233 // Cloneds
234 this.allFiles = input.allFiles;
235 this.invalid = input.invalid;
328 allFiles = true;
329 npath = builtInFS.getPath("");
330 // other fields remain default
331 return;
332 }
333
334 boolean rememberStar = false;
335 if (name.endsWith("*")) {
336 rememberStar = true;
337 recursive = false;
338 name = name.substring(0, name.length()-1) + "-";
339 }
340
341 try {
342 // new File() can "normalize" some name, for example, "/C:/X" on
343 // Windows. Some JDK codes generate such illegal names.
344 npath = builtInFS.getPath(new File(name).getPath())
345 .normalize();
346 // lastName should always be non-null now
347 Path lastName = npath.getFileName();
348 if (lastName != null && lastName.equals(DASH_PATH)) {
349 directory = true;
350 recursive = !rememberStar;
351 npath = npath.getParent();
352 }
353 if (npath == null) {
354 npath = builtInFS.getPath("");
355 }
356 invalid = false;
357 } catch (InvalidPathException ipe) {
358 // Still invalid. For compatibility reason, accept it
359 // but make this permission useless.
360 npath = builtInFS.getPath("-u-s-e-l-e-s-s-");
361 invalid = true;
362 }
363
364 } else {
365 if ((cpath = getName()) == null)
366 throw new NullPointerException("name can't be null");
367
368 this.mask = mask;
666 return (this.cpath.equals(that.cpath));
667 }
668 }
669 }
670
671 /**
672 * Returns the depth between an outer path p1 and an inner path p2. -1
673 * is returned if
674 *
675 * - p1 does not contains p2.
676 * - this is not decidable. For example, p1="../x", p2="y".
677 * - the depth is not decidable. For example, p1="/", p2="x".
678 *
679 * This method can return 2 if the depth is greater than 2.
680 *
681 * @param p1 the expected outer path, normalized
682 * @param p2 the expected inner path, normalized
683 * @return the depth in between
684 */
685 private static int containsPath(Path p1, Path p2) {
686
687 // Two paths must have the same root. For example,
688 // there is no contains relation between any two of
689 // "/x", "x", "C:/x", "C:x", and "//host/share/x".
690 if (!Objects.equals(p1.getRoot(), p2.getRoot())) {
691 return -1;
692 }
693
694 // Empty path (i.e. "." or "") is a strange beast,
695 // because its getNameCount()==1 but getName(0) is null.
696 // It's better to deal with it separately.
697 if (p1.equals(EMPTY_PATH)) {
698 if (p2.equals(EMPTY_PATH)) {
699 return 0;
700 } else if (p2.getName(0).equals(DOTDOT_PATH)) {
701 // "." contains p2 iif p2 has no "..". Since a
702 // a normalized path can only have 0 or more
703 // ".." at the beginning. We only need to look
704 // at the head.
705 return -1;
706 } else {
707 // and the distance is p2's name count. i.e.
708 // 3 between "." and "a/b/c".
709 return p2.getNameCount();
710 }
711 } else if (p2.equals(EMPTY_PATH)) {
712 int c1 = p1.getNameCount();
713 if (!p1.getName(c1 - 1).equals(DOTDOT_PATH)) {
714 // "." is inside p1 iif p1 is 1 or more "..".
715 // For the same reason above, we only need to
716 // look at the tail.
717 return -1;
718 }
719 // and the distance is the count of ".."
720 return c1;
721 }
722
723 // Good. No more empty paths.
724
725 // Common heads are removed
726
727 int c1 = p1.getNameCount();
728 int c2 = p2.getNameCount();
729
730 int n = Math.min(c1, c2);
731 int i = 0;
732 while (i < n) {
733 if (!p1.getName(i).equals(p2.getName(i)))
734 break;
735 i++;
736 }
737
738 // for p1 containing p2, p1 must be 0-or-more "..",
739 // and p2 cannot have "..". For the same reason, we only
740 // check tail of p1 and head of p2.
741 if (i < c1 && !p1.getName(c1 - 1).equals(DOTDOT_PATH)) {
742 return -1;
743 }
744
745 if (i < c2 && p2.getName(i).equals(DOTDOT_PATH)) {
746 return -1;
747 }
748
749 // and the distance is the name counts added (after removing
750 // the common heads).
751
752 // For example: p1 = "../../..", p2 = "../a".
753 // After removing the common heads, they become "../.." and "a",
754 // and the distance is (3-1)+(2-1) = 3.
755 return c1 - i + c2 - i;
756 }
757
758 /**
759 * Checks two FilePermission objects for equality. Checks that <i>obj</i> is
760 * a FilePermission, and has the same pathname and actions as this object.
761 *
762 * @implNote More specifically, two pathnames are the same if and only if
763 * they have the same wildcard flag and their {@code cpath}
764 * (if {@code jdk.io.permissionsUseCanonicalPath} is {@code true}) or
765 * {@code npath} (if {@code jdk.io.permissionsUseCanonicalPath}
766 * is {@code false}) are equal. Or they are both {@literal "<<ALL FILES>>"}.
767 * <p>
768 * When {@code jdk.io.permissionsUseCanonicalPath} is {@code false}, an
769 * invalid {@code FilePermission} does not equal to any object except
770 * for itself, even if they are created using the same invalid path.
771 *
772 * @param obj the object we are testing for equality with this object.
773 * @return <code>true</code> if obj is a FilePermission, and has the same
774 * pathname and actions as this FilePermission object,
775 * <code>false</code> otherwise.
|