1 /* |
1 /* |
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. |
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. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
206 DefaultFileSystemProvider.create() |
206 DefaultFileSystemProvider.create() |
207 .getFileSystem(URI.create("file:///")); |
207 .getFileSystem(URI.create("file:///")); |
208 |
208 |
209 private static final Path here = builtInFS.getPath( |
209 private static final Path here = builtInFS.getPath( |
210 GetPropertyAction.privilegedGetProperty("user.dir")); |
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(".."); |
211 |
215 |
212 /** |
216 /** |
213 * A private constructor that clones some and updates some, |
217 * A private constructor that clones some and updates some, |
214 * always with a different name. |
218 * always with a different name. |
215 * @param input |
219 * @param input |
339 // Windows. Some JDK codes generate such illegal names. |
343 // Windows. Some JDK codes generate such illegal names. |
340 npath = builtInFS.getPath(new File(name).getPath()) |
344 npath = builtInFS.getPath(new File(name).getPath()) |
341 .normalize(); |
345 .normalize(); |
342 // lastName should always be non-null now |
346 // lastName should always be non-null now |
343 Path lastName = npath.getFileName(); |
347 Path lastName = npath.getFileName(); |
344 if (lastName != null && lastName.toString().equals("-")) { |
348 if (lastName != null && lastName.equals(DASH_PATH)) { |
345 directory = true; |
349 directory = true; |
346 recursive = !rememberStar; |
350 recursive = !rememberStar; |
347 npath = npath.getParent(); |
351 npath = npath.getParent(); |
348 } |
352 } |
349 if (npath == null) { |
353 if (npath == null) { |
677 * @param p1 the expected outer path, normalized |
681 * @param p1 the expected outer path, normalized |
678 * @param p2 the expected inner path, normalized |
682 * @param p2 the expected inner path, normalized |
679 * @return the depth in between |
683 * @return the depth in between |
680 */ |
684 */ |
681 private static int containsPath(Path p1, Path p2) { |
685 private static int containsPath(Path p1, Path p2) { |
682 Path p; |
686 |
683 try { |
687 // Two paths must have the same root. For example, |
684 p = p2.relativize(p1).normalize(); |
688 // there is no contains relation between any two of |
685 if (p.getName(0).toString().isEmpty()) { |
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)) { |
686 return 0; |
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; |
687 } else { |
706 } else { |
688 for (Path item: p) { |
707 // and the distance is p2's name count. i.e. |
689 String s = item.toString(); |
708 // 3 between "." and "a/b/c". |
690 if (!s.equals("..")) { |
709 return p2.getNameCount(); |
691 return -1; |
710 } |
692 } |
711 } else if (p2.equals(EMPTY_PATH)) { |
693 } |
712 int c1 = p1.getNameCount(); |
694 return p.getNameCount(); |
713 if (!p1.getName(c1 - 1).equals(DOTDOT_PATH)) { |
695 } |
714 // "." is inside p1 iif p1 is 1 or more "..". |
696 } catch (IllegalArgumentException iae) { |
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)) { |
697 return -1; |
742 return -1; |
698 } |
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; |
699 } |
756 } |
700 |
757 |
701 /** |
758 /** |
702 * Checks two FilePermission objects for equality. Checks that <i>obj</i> is |
759 * 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. |
760 * a FilePermission, and has the same pathname and actions as this object. |