filepermission.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 822 行 · 第 1/2 页
JAVA
822 行
/* * @(#)FilePermission.java 1.76 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ package java.io;import java.security.*;import java.util.Enumeration;import java.util.List;import java.util.ArrayList;import java.util.StringTokenizer;import java.util.Vector;import java.util.Collections;import java.io.ObjectStreamField;import java.io.ObjectOutputStream;import java.io.ObjectInputStream;import java.io.IOException;import sun.security.util.SecurityConstants;/** * This class represents access to a file or directory. A FilePermission consists * of a pathname and a set of actions valid for that pathname. * <P> * Pathname is the pathname of the file or directory granted the specified * actions. A pathname that ends in "/*" (where "/" is * the file separator character, <code>File.separatorChar</code>) indicates * all the files and directories contained in that directory. A pathname * that ends with "/-" indicates (recursively) all files * and subdirectories contained in that directory. A pathname consisting of * the special token "<<ALL FILES>>" matches <b>any</b> file. * <P> * Note: A pathname consisting of a single "*" indicates all the files * in the current directory, while a pathname consisting of a single "-" * indicates all the files in the current directory and * (recursively) all files and subdirectories contained in the current * directory. * <P> * The actions to be granted are passed to the constructor in a string containing * a list of one or more comma-separated keywords. The possible keywords are * "read", "write", "execute", and "delete". Their meaning is defined as follows: * <P> * <DL> * <DT> read <DD> read permission * <DT> write <DD> write permission * <DT> execute * <DD> execute permission. Allows <code>Runtime.exec</code> to * be called. Corresponds to <code>SecurityManager.checkExec</code>. * <DT> delete * <DD> delete permission. Allows <code>File.delete</code> to * be called. Corresponds to <code>SecurityManager.checkDelete</code>. * </DL> * <P> * The actions string is converted to lowercase before processing. * <P> * Be careful when granting FilePermissions. Think about the implications * of granting read and especially write access to various files and * directories. The "<<ALL FILES>>" permission with write action is * especially dangerous. This grants permission to write to the entire * file system. One thing this effectively allows is replacement of the * system binary, including the JVM runtime environment. * * <p>Please note: Code can always read a file from the same * directory it's in (or a subdirectory of that directory); it does not * need explicit permission to do so. * * @see java.security.Permission * @see java.security.Permissions * @see java.security.PermissionCollection * * @version 1.67 00/02/02 * * @since 1.2 * * @serial exclude */public final class FilePermission extends Permission implements Serializable { /** * Execute action. */ private final static int EXECUTE = 0x1; /** * Write action. */ private final static int WRITE = 0x2; /** * Read action. */ private final static int READ = 0x4; /** * Delete action. */ private final static int DELETE = 0x8; /** * All actions (read,write,execute,delete) */ private final static int ALL = READ|WRITE|EXECUTE|DELETE; /** * No actions. */ private final static int NONE = 0x0; // the actions mask private transient int mask; // does path indicate a directory? (wildcard or recursive) private transient boolean directory; // is it a recursive directory specification? private transient boolean recursive; /** * the actions string. * * @serial */ private String actions; // Left null as long as possible, then // created and re-used in the getAction function. // canonicalized dir path. In the case of // directories, it is the name "/blah/*" or "/blah/-" without // the last character (the "*" or "-"). private transient String cpath; // static Strings used by init(int mask) private static final char RECURSIVE_CHAR = '-'; private static final char WILD_CHAR = '*';/* public String toString() { StringBuffer sb = new StringBuffer(); sb.append("***\n"); sb.append("cpath = "+cpath+"\n"); sb.append("mask = "+mask+"\n"); sb.append("actions = "+getActions()+"\n"); sb.append("directory = "+directory+"\n"); sb.append("recursive = "+recursive+"\n"); sb.append("***\n"); return sb.toString(); }*/ private static final long serialVersionUID = 7930732926638008763L; /** * initialize a FilePermission object. Common to all constructors. * Also called during de-serialization. * * @param mask the actions mask to use. * */ private void init(int mask) { if ((mask & ALL) != mask) throw new IllegalArgumentException("invalid actions mask"); if (mask == NONE) throw new IllegalArgumentException("invalid actions mask"); if ((cpath = getName()) == null) throw new NullPointerException("name can't be null"); this.mask = mask; if (cpath.equals("<<ALL FILES>>")) { directory = true; recursive = true; cpath = ""; return; } int len = cpath.length(); char last = ((len > 0) ? cpath.charAt(len - 1) : 0); if (last == RECURSIVE_CHAR && (len == 1 || cpath.charAt(len - 2) == File.separatorChar)) { directory = true; recursive = true; cpath = cpath.substring(0, --len); } else if (last == WILD_CHAR && (len == 1 || cpath.charAt(len - 2) == File.separatorChar)) { directory = true; //recursive = false; cpath = cpath.substring(0, --len); } else { // overkill since they are initialized to false, but // commented out here to remind us... //directory = false; //recursive = false; } if (len == 0) { cpath = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("user.dir")); } // store only the canonical cpath if possible // need a doPrivileged block as getCanonicalPath // might attempt to access user.dir to turn a relative // path into an absolute path. cpath = (String) AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { try { File file = new File(cpath); String canonical_path = file.getCanonicalPath(); int ln; if (directory && ((ln=canonical_path.length()) == 0 || canonical_path.charAt(ln - 1) != File.separatorChar)) { return canonical_path + File.separator; } else { return canonical_path; } } catch (IOException ioe) { // ignore if we can't canonicalize path? } return cpath; } }); // At this point the path should be absolute. die if it isn't? } /** * Creates a new FilePermission object with the specified actions. * <i>path</i> is the pathname of a * file or directory, and <i>actions</i> contains a comma-separated list of the * desired actions granted on the file or directory. Possible actions are * "read", "write", "execute", and "delete". * * <p>A pathname that ends in "/*" (where "/" is * the file separator character, <code>File.separatorChar</code>) indicates * a directory and all the files contained in that directory. A pathname * that ends with "/-" indicates a directory and (recursively) all files * and subdirectories contained in that directory. The special pathname * "<<ALL FILES>>" matches all files. * * <p>A pathname consisting of a single "*" indicates all the files * in the current directory, while a pathname consisting of a single "-" * indicates all the files in the current directory and * (recursively) all files and subdirectories contained in the current * directory. * * @param path the pathname of the file/directory. * @param actions the action string. */ public FilePermission(String path, String actions) { super(path); init(getMask(actions)); } /** * Creates a new FilePermission object using an action mask. * More efficient than the FilePermission(String, String) constructor. * Can be used from within * code that needs to create a FilePermission object to pass into the * <code>implies</code> method. * * @param path the pathname of the file/directory. * @param mask the action mask to use. */ // package private for use by the FilePermissionCollection add method FilePermission(String path, int mask) { super(path); init(mask); } /** * Checks if this FilePermission object "implies" the specified permission. * <P> * More specifically, this method returns true if:<p> * <ul> * <li> <i>p</i> is an instanceof FilePermission,<p> * <li> <i>p</i>'s actions are a proper subset of this * object's actions, and <p> * <li> <i>p</i>'s pathname is implied by this object's * pathname. For example, "/tmp/*" implies "/tmp/foo", since * "/tmp/*" encompasses the "/tmp" directory and all files in that * directory, including the one named "foo". * </ul> * @param p the permission to check against. * * @return true if the specified permission is implied by this object, * false if not. */ public boolean implies(Permission p) { if (!(p instanceof FilePermission)) return false; FilePermission that = (FilePermission) p; // we get the effective mask. i.e., the "and" of this and that. // They must be equal to that.mask for implies to return true. return ((this.mask & that.mask) == that.mask) && impliesIgnoreMask(that); } /** * Checks if the Permission's actions are a proper subset of the * this object's actions. Returns the effective mask iff the * this FilePermission's path also implies that FilePermission's path. * * @param that the FilePermission to check against. * @param exact return immediatly if the masks are not equal * @return the effective mask */ boolean impliesIgnoreMask(FilePermission that) { if (this.directory) { if (this.recursive) { // make sure that.path is longer then path so // something like /foo/- does not imply /foo if (that.directory) { return (that.cpath.length() >= this.cpath.length()) && that.cpath.startsWith(this.cpath); } else { return ((that.cpath.length() > this.cpath.length()) && that.cpath.startsWith(this.cpath)); } } else { if (that.directory) { // if the permission passed in is a directory // specification, make sure that a non-recursive // permission (i.e., this object) can't imply a recursive // permission. if (that.recursive) return false; else return (this.cpath.equals(that.cpath)); } else { int last = that.cpath.lastIndexOf(File.separatorChar); if (last == -1) return false; else { // this.cpath.equals(that.cpath.substring(0, last+1)); // Use regionMatches to avoid creating new string return (this.cpath.length() == (last + 1)) && this.cpath.regionMatches(0, that.cpath, 0, last+1); } } } } else { return (this.cpath.equals(that.cpath)); } } /** * Checks two FilePermission objects for equality. Checks that <i>obj</i> is * a FilePermission, and has the same pathname and actions as this object. * <P> * @param obj the object we are testing for equality with this object. * @return true if obj is a FilePermission, and has the same pathname and * actions as this FilePermission object. */ public boolean equals(Object obj) { if (obj == this) return true; if (! (obj instanceof FilePermission)) return false; FilePermission that = (FilePermission) obj; return (this.mask == that.mask) && this.cpath.equals(that.cpath) && (this.directory == that.directory) && (this.recursive == that.recursive); } /** * Returns the hash code value for this object. * * @return a hash code value for this object. */ public int hashCode() {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?