--- a/jdk/src/share/classes/java/io/File.java Mon May 06 06:05:06 2013 +0200
+++ b/jdk/src/share/classes/java/io/File.java Mon May 06 14:17:59 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, 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
@@ -156,7 +156,7 @@
private static final FileSystem fs = DefaultFileSystem.getFileSystem();
/**
- * This abstract pathname's normalized pathname string. A normalized
+ * This abstract pathname's normalized pathname string. A normalized
* pathname string uses the default name-separator character and does not
* contain any duplicate or redundant separators.
*
@@ -165,6 +165,32 @@
private final String path;
/**
+ * Enum type that indicates the status of a file path.
+ */
+ private static enum PathStatus { INVALID, CHECKED };
+
+ /**
+ * The flag indicating whether the file path is invalid.
+ */
+ private transient PathStatus status = null;
+
+ /**
+ * Check if the file has an invalid path. Currently, the inspection of
+ * a file path is very limited, and it only covers Nul character check.
+ * Returning true means the path is definitely invalid/garbage. But
+ * returning false does not guarantee that the path is valid.
+ *
+ * @return true if the file path is invalid.
+ */
+ final boolean isInvalid() {
+ if (status == null) {
+ status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
+ : PathStatus.INVALID;
+ }
+ return status == PathStatus.INVALID;
+ }
+
+ /**
* The length of this abstract pathname's prefix, or zero if it has no
* prefix.
*/
@@ -586,6 +612,9 @@
* @see Path#toRealPath
*/
public String getCanonicalPath() throws IOException {
+ if (isInvalid()) {
+ throw new IOException("Invalid file path");
+ }
return fs.canonicalize(fs.resolve(this));
}
@@ -651,6 +680,9 @@
*/
@Deprecated
public URL toURL() throws MalformedURLException {
+ if (isInvalid()) {
+ throw new MalformedURLException("Invalid file path");
+ }
return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
}
@@ -730,6 +762,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.checkAccess(this, FileSystem.ACCESS_READ);
}
@@ -755,6 +790,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}
@@ -775,6 +813,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}
@@ -802,6 +843,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
!= 0);
}
@@ -832,6 +876,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
}
@@ -858,6 +905,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
}
@@ -887,6 +937,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getLastModifiedTime(this);
}
@@ -915,6 +968,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getLength(this);
}
@@ -950,6 +1006,9 @@
public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(path);
+ if (isInvalid()) {
+ throw new IOException("Invalid file path");
+ }
return fs.createFileExclusively(path);
}
@@ -976,6 +1035,9 @@
if (security != null) {
security.checkDelete(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.delete(this);
}
@@ -1011,6 +1073,9 @@
if (security != null) {
security.checkDelete(path);
}
+ if (isInvalid()) {
+ return;
+ }
DeleteOnExitHook.add(path);
}
@@ -1051,6 +1116,9 @@
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return null;
+ }
return fs.list(this);
}
@@ -1242,6 +1310,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.createDirectory(this);
}
@@ -1317,6 +1388,12 @@
security.checkWrite(path);
security.checkWrite(dest.path);
}
+ if (dest == null) {
+ throw new NullPointerException();
+ }
+ if (this.isInvalid() || dest.isInvalid()) {
+ return false;
+ }
return fs.rename(this, dest);
}
@@ -1352,6 +1429,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setLastModifiedTime(this, time);
}
@@ -1379,6 +1459,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setReadOnly(this);
}
@@ -1419,6 +1502,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
}
@@ -1493,6 +1579,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
}
@@ -1570,6 +1659,9 @@
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
}
@@ -1629,6 +1721,9 @@
if (security != null) {
security.checkExec(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
}
@@ -1705,6 +1800,9 @@
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getSpace(this, FileSystem.SPACE_TOTAL);
}
@@ -1721,7 +1819,7 @@
* makes no guarantee that write operations to this file system
* will succeed.
*
- * @return The number of unallocated bytes on the partition <tt>0L</tt>
+ * @return The number of unallocated bytes on the partition or <tt>0L</tt>
* if the abstract pathname does not name a partition. This
* value will be less than or equal to the total file system size
* returned by {@link #getTotalSpace}.
@@ -1740,6 +1838,9 @@
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getSpace(this, FileSystem.SPACE_FREE);
}
@@ -1778,6 +1879,9 @@
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getSpace(this, FileSystem.SPACE_USABLE);
}
@@ -1787,8 +1891,8 @@
private TempDirectory() { }
// temporary directory location
- private static final File tmpdir = new File(fs.normalize(AccessController
- .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
+ private static final File tmpdir = new File(AccessController
+ .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
static File location() {
return tmpdir;
}
@@ -1899,6 +2003,9 @@
throw se;
}
}
+ if (f.isInvalid()) {
+ throw new IOException("Unable to create temporary file");
+ }
} while (!fs.createFileExclusively(f.getPath()));
return f;
}