src/share/classes/java/io/File.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1994, 2012, 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) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 163,172 ****
--- 163,198 ----
* @serial
*/
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.
*/
private final transient int prefixLength;
*** 584,593 ****
--- 610,622 ----
*
* @since JDK1.1
* @see Path#toRealPath
*/
public String getCanonicalPath() throws IOException {
+ if (isInvalid()) {
+ throw new IOException("Invalid file path");
+ }
return fs.canonicalize(fs.resolve(this));
}
/**
* Returns the canonical form of this abstract pathname. Equivalent to
*** 649,658 ****
--- 678,690 ----
* {@link #toURI() toURI} method, and then converting the URI into a URL
* via the {@link java.net.URI#toURL() URI.toURL} method.
*/
@Deprecated
public URL toURL() throws MalformedURLException {
+ if (isInvalid()) {
+ throw new MalformedURLException("Invalid file path");
+ }
return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
}
/**
* Constructs a <tt>file:</tt> URI that represents this abstract pathname.
*** 728,737 ****
--- 760,772 ----
public boolean canRead() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.checkAccess(this, FileSystem.ACCESS_READ);
}
/**
* Tests whether the application can modify the file denoted by this
*** 753,762 ****
--- 788,800 ----
public boolean canWrite() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}
/**
* Tests whether the file or directory denoted by this abstract pathname
*** 773,782 ****
--- 811,823 ----
public boolean exists() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}
/**
* Tests whether the file denoted by this abstract pathname is a
*** 800,809 ****
--- 841,853 ----
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
!= 0);
}
/**
*** 830,839 ****
--- 874,886 ----
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
}
/**
* Tests whether the file named by this abstract pathname is a hidden
*** 856,865 ****
--- 903,915 ----
public boolean isHidden() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
}
/**
* Returns the time that the file denoted by this abstract pathname was
*** 885,894 ****
--- 935,947 ----
public long lastModified() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getLastModifiedTime(this);
}
/**
* Returns the length of the file denoted by this abstract pathname.
*** 913,922 ****
--- 966,978 ----
public long length() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getLength(this);
}
/* -- File operations -- */
*** 948,957 ****
--- 1004,1016 ----
* @since 1.2
*/
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);
}
/**
* Deletes the file or directory denoted by this abstract pathname. If
*** 974,983 ****
--- 1033,1045 ----
public boolean delete() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.delete(this);
}
/**
* Requests that the file or directory denoted by this abstract
*** 1009,1018 ****
--- 1071,1083 ----
public void deleteOnExit() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
+ if (isInvalid()) {
+ return;
+ }
DeleteOnExitHook.add(path);
}
/**
* Returns an array of strings naming the files and directories in the
*** 1049,1058 ****
--- 1114,1126 ----
public String[] list() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ if (isInvalid()) {
+ return null;
+ }
return fs.list(this);
}
/**
* Returns an array of strings naming the files and directories in the
*** 1240,1249 ****
--- 1308,1320 ----
public boolean mkdir() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.createDirectory(this);
}
/**
* Creates the directory named by this abstract pathname, including any
*** 1315,1324 ****
--- 1386,1401 ----
SecurityManager security = System.getSecurityManager();
if (security != null) {
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);
}
/**
* Sets the last-modified time of the file or directory named by this
*** 1350,1359 ****
--- 1427,1439 ----
if (time < 0) throw new IllegalArgumentException("Negative time");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setLastModifiedTime(this, time);
}
/**
* Marks the file or directory named by this abstract pathname so that
*** 1377,1386 ****
--- 1457,1469 ----
public boolean setReadOnly() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setReadOnly(this);
}
/**
* Sets the owner's or everybody's write permission for this abstract
*** 1417,1426 ****
--- 1500,1512 ----
public boolean setWritable(boolean writable, boolean ownerOnly) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
}
/**
* A convenience method to set the owner's write permission for this abstract
*** 1491,1500 ****
--- 1577,1589 ----
public boolean setReadable(boolean readable, boolean ownerOnly) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
}
/**
* A convenience method to set the owner's read permission for this abstract
*** 1568,1577 ****
--- 1657,1669 ----
public boolean setExecutable(boolean executable, boolean ownerOnly) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
}
/**
* A convenience method to set the owner's execute permission for this
*** 1627,1636 ****
--- 1719,1731 ----
public boolean canExecute() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExec(path);
}
+ if (isInvalid()) {
+ return false;
+ }
return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
}
/* -- Filesystem interface -- */
*** 1703,1712 ****
--- 1798,1810 ----
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getSpace(this, FileSystem.SPACE_TOTAL);
}
/**
* Returns the number of unallocated bytes in the partition <a
*** 1719,1729 ****
* inaccurate by any external I/O operations including those made
* on the system outside of this virtual machine. This method
* makes no guarantee that write operations to this file system
* will succeed.
*
! * @return The number of unallocated bytes on the partition <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}.
*
* @throws SecurityException
--- 1817,1827 ----
* inaccurate by any external I/O operations including those made
* on the system outside of this virtual machine. This method
* makes no guarantee that write operations to this file system
* will succeed.
*
! * @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}.
*
* @throws SecurityException
*** 1738,1747 ****
--- 1836,1848 ----
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getSpace(this, FileSystem.SPACE_FREE);
}
/**
* Returns the number of bytes available to this virtual machine on the
*** 1776,1796 ****
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
return fs.getSpace(this, FileSystem.SPACE_USABLE);
}
/* -- Temporary files -- */
private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
! private static final File tmpdir = new File(fs.normalize(AccessController
! .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
static File location() {
return tmpdir;
}
// file name generation
--- 1877,1900 ----
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
+ if (isInvalid()) {
+ return 0L;
+ }
return fs.getSpace(this, FileSystem.SPACE_USABLE);
}
/* -- Temporary files -- */
private static class TempDirectory {
private TempDirectory() { }
// temporary directory location
! private static final File tmpdir = new File(AccessController
! .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
static File location() {
return tmpdir;
}
// file name generation
*** 1897,1906 ****
--- 2001,2013 ----
if (directory == null)
throw new SecurityException("Unable to create temporary file");
throw se;
}
}
+ if (f.isInvalid()) {
+ throw new IOException("Unable to create temporary file");
+ }
} while (!fs.createFileExclusively(f.getPath()));
return f;
}
/**