提交 11547923 编写于 作者: D dxu

8003992: File and other classes in java.io do not handle embedded nulls properly

Summary: Have every file operation done with File, FileInputStream, FileOutputStream, or RandomAccessFile that involves a file path containing NUL fail. Also reviewed by fweimer@redhat.com
Reviewed-by: alanb, sherman, ahgross, mduigou, dholmes, aph, plevart, martin
上级 b9440f2f
/*
* 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
......@@ -164,6 +164,32 @@ public class File
*/
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 @@ public class File
* @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 @@ public class File
*/
@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 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_READ);
}
......@@ -755,6 +790,9 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}
......@@ -775,6 +813,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}
......@@ -802,6 +843,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
!= 0);
}
......@@ -832,6 +876,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
}
......@@ -858,6 +905,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
}
......@@ -887,6 +937,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getLastModifiedTime(this);
}
......@@ -915,6 +968,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getLength(this);
}
......@@ -950,6 +1006,9 @@ public class File
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 @@ public class File
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return false;
}
return fs.delete(this);
}
......@@ -1011,6 +1073,9 @@ public class File
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return;
}
DeleteOnExitHook.add(path);
}
......@@ -1051,6 +1116,9 @@ public class File
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return null;
}
return fs.list(this);
}
......@@ -1242,6 +1310,9 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.createDirectory(this);
}
......@@ -1317,6 +1388,12 @@ public class File
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 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setLastModifiedTime(this, time);
}
......@@ -1379,6 +1459,9 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setReadOnly(this);
}
......@@ -1419,6 +1502,9 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
}
......@@ -1493,6 +1579,9 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
}
......@@ -1570,6 +1659,9 @@ public class File
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
}
......@@ -1629,6 +1721,9 @@ public class File
if (security != null) {
security.checkExec(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
}
......@@ -1705,6 +1800,9 @@ public class File
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getSpace(this, FileSystem.SPACE_TOTAL);
}
......@@ -1721,7 +1819,7 @@ public class File
* 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 @@ public class File
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getSpace(this, FileSystem.SPACE_FREE);
}
......@@ -1778,6 +1879,9 @@ public class File
sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
sm.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getSpace(this, FileSystem.SPACE_USABLE);
}
......@@ -1787,8 +1891,8 @@ public class File
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 @@ public class File
throw se;
}
}
if (f.isInvalid()) {
throw new IOException("Unable to create temporary file");
}
} while (!fs.createFileExclusively(f.getPath()));
return f;
}
......
/*
* Copyright (c) 1994, 2011, 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
......@@ -123,6 +123,9 @@ class FileInputStream extends InputStream
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
open(name);
......
/*
* Copyright (c) 1994, 2011, 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
......@@ -196,6 +196,9 @@ class FileOutputStream extends OutputStream
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
this.fd = new FileDescriptor();
fd.attach(this);
this.append = append;
......
/*
* 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
......@@ -228,6 +228,9 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
open(name, imode);
......
/*
* Copyright (c) 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.
*
* This code 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 in the LICENSE file that
* accompanied this code).
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8003992
* @summary Test a file whose path name is embedded with NUL character, and
* ensure it is handled correctly.
* @author Dan Xu
*/
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.InvalidPathException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
public class NulFile {
private static final char CHAR_NUL = '\u0000';
private static final String ExceptionMsg = "Invalid file path";
public static void main(String[] args) {
testFile();
testFileInUnix();
testFileInWindows();
testTempFile();
}
private static void testFile() {
test(new File(new StringBuilder().append(CHAR_NUL).toString()));
test(new File(
new StringBuilder().append("").append(CHAR_NUL).toString()));
test(new File(
new StringBuilder().append(CHAR_NUL).append("").toString()));
}
private static void testFileInUnix() {
String osName = System.getProperty("os.name");
if (osName.startsWith("Windows"))
return;
String unixFile = "/";
test(unixFile);
unixFile = "//";
test(unixFile);
unixFile = "data/info";
test(unixFile);
unixFile = "/data/info";
test(unixFile);
unixFile = "//data//info";
test(unixFile);
}
private static void testFileInWindows() {
String osName = System.getProperty("os.name");
if (!osName.startsWith("Windows"))
return;
String windowsFile = "\\";
test(windowsFile);
windowsFile = "\\\\";
test(windowsFile);
windowsFile = "/";
test(windowsFile);
windowsFile = "//";
test(windowsFile);
windowsFile = "/\\";
test(windowsFile);
windowsFile = "\\/";
test(windowsFile);
windowsFile = "data\\info";
test(windowsFile);
windowsFile = "\\data\\info";
test(windowsFile);
windowsFile = "\\\\server\\data\\info";
test(windowsFile);
windowsFile = "z:data\\info";
test(windowsFile);
windowsFile = "z:\\data\\info";
test(windowsFile);
}
private static void test(final String name) {
int length = name.length();
for (int i = 0; i <= length; i++) {
StringBuilder sbName = new StringBuilder(name);
sbName.insert(i, CHAR_NUL);
String curName = sbName.toString();
// test File(String parent, String child)
File testFile = new File(curName, "child");
test(testFile);
testFile = new File("parent", curName);
test(testFile);
// test File(String pathname)
testFile = new File(curName);
test(testFile);
// test File(File parent, String child)
testFile = new File(new File(curName), "child");
test(testFile);
testFile = new File(new File("parent"), curName);
test(testFile);
// test FileInputStream
testFileInputStream(curName);
// test FileOutputStream
testFileOutputStream(curName);
// test RandomAccessFile
testRandomAccessFile(curName);
}
}
private static void testFileInputStream(final String str) {
boolean exceptionThrown = false;
FileInputStream is = null;
try {
is = new FileInputStream(str);
} catch (FileNotFoundException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("FileInputStream constructor"
+ " should throw FileNotFoundException");
}
if (is != null) {
throw new RuntimeException("FileInputStream constructor"
+ " should fail");
}
exceptionThrown = false;
is = null;
try {
is = new FileInputStream(new File(str));
} catch (FileNotFoundException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("FileInputStream constructor"
+ " should throw FileNotFoundException");
}
if (is != null) {
throw new RuntimeException("FileInputStream constructor"
+ " should fail");
}
}
private static void testFileOutputStream(final String str) {
boolean exceptionThrown = false;
FileOutputStream os = null;
try {
os = new FileOutputStream(str);
} catch (FileNotFoundException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("FileOutputStream constructor"
+ " should throw FileNotFoundException");
}
if (os != null) {
throw new RuntimeException("FileOutputStream constructor"
+ " should fail");
}
exceptionThrown = false;
os = null;
try {
os = new FileOutputStream(new File(str));
} catch (FileNotFoundException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("FileOutputStream constructor"
+ " should throw FileNotFoundException");
}
if (os != null) {
throw new RuntimeException("FileOutputStream constructor"
+ " should fail");
}
}
private static void testRandomAccessFile(final String str) {
boolean exceptionThrown = false;
RandomAccessFile raf = null;
String[] modes = {"r", "rw", "rws", "rwd"};
for (String mode : modes) {
try {
raf = new RandomAccessFile(str, mode);
} catch (FileNotFoundException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("RandomAccessFile constructor"
+ " should throw FileNotFoundException");
}
if (raf != null) {
throw new RuntimeException("RandomAccessFile constructor"
+ " should fail");
}
exceptionThrown = false;
raf = null;
try {
raf = new RandomAccessFile(new File(str), mode);
} catch (FileNotFoundException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("RandomAccessFile constructor"
+ " should throw FileNotFoundException");
}
if (raf != null) {
throw new RuntimeException("RandomAccessFile constructor"
+ " should fail");
}
}
}
private static void test(File testFile) {
test(testFile, false);
// test serialization
testSerialization(testFile);
}
@SuppressWarnings("deprecation")
private static void test(File testFile, boolean derived) {
boolean exceptionThrown = false;
if (testFile == null) {
throw new RuntimeException("test file should not be null.");
}
// getPath()
if (testFile.getPath().indexOf(CHAR_NUL) < 0) {
throw new RuntimeException(
"File path should contain Nul character");
}
// getAbsolutePath()
if (testFile.getAbsolutePath().indexOf(CHAR_NUL) < 0) {
throw new RuntimeException(
"File absolute path should contain Nul character");
}
// getAbsoluteFile()
File derivedAbsFile = testFile.getAbsoluteFile();
if (derived) {
if (derivedAbsFile.getPath().indexOf(CHAR_NUL) < 0) {
throw new RuntimeException(
"Derived file path should also contain Nul character");
}
} else {
test(derivedAbsFile, true);
}
// getCanonicalPath()
try {
exceptionThrown = false;
testFile.getCanonicalPath();
} catch (IOException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException(
"getCanonicalPath() should throw IOException with"
+ " message \"" + ExceptionMsg + "\"");
}
// getCanonicalFile()
try {
exceptionThrown = false;
testFile.getCanonicalFile();
} catch (IOException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException(
"getCanonicalFile() should throw IOException with"
+ " message \"" + ExceptionMsg + "\"");
}
// toURL()
try {
exceptionThrown = false;
testFile.toURL();
} catch (MalformedURLException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("toURL() should throw IOException with"
+ " message \"" + ExceptionMsg + "\"");
}
// canRead()
if (testFile.canRead())
throw new RuntimeException("File should not be readable");
// canWrite()
if (testFile.canWrite())
throw new RuntimeException("File should not be writable");
// exists()
if (testFile.exists())
throw new RuntimeException("File should not be existed");
// isDirectory()
if (testFile.isDirectory())
throw new RuntimeException("File should not be a directory");
// isFile()
if (testFile.isFile())
throw new RuntimeException("File should not be a file");
// isHidden()
if (testFile.isHidden())
throw new RuntimeException("File should not be hidden");
// lastModified()
if (testFile.lastModified() != 0L)
throw new RuntimeException("File last modified time should be 0L");
// length()
if (testFile.length() != 0L)
throw new RuntimeException("File length should be 0L");
// createNewFile()
try {
exceptionThrown = false;
testFile.createNewFile();
} catch (IOException ex) {
if (ExceptionMsg.equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException(
"createNewFile() should throw IOException with"
+ " message \"" + ExceptionMsg + "\"");
}
// delete()
if (testFile.delete())
throw new RuntimeException("Delete operation should fail");
// list()
if (testFile.list() != null)
throw new RuntimeException("File list() should return null");
// list(FilenameFilter)
FilenameFilter fnFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return false;
}
};
if (testFile.list(fnFilter) != null) {
throw new RuntimeException("File list(FilenameFilter) should"
+ " return null");
}
// listFiles()
if (testFile.listFiles() != null)
throw new RuntimeException("File listFiles() should return null");
// listFiles(FilenameFilter)
if (testFile.listFiles(fnFilter) != null) {
throw new RuntimeException("File listFiles(FilenameFilter)"
+ " should return null");
}
// listFiles(FileFilter)
FileFilter fFilter = new FileFilter() {
@Override
public boolean accept(File file) {
return false;
}
};
if (testFile.listFiles(fFilter) != null) {
throw new RuntimeException("File listFiles(FileFilter)"
+ " should return null");
}
// mkdir()
if (testFile.mkdir()) {
throw new RuntimeException("File should not be able to"
+ " create directory");
}
// mkdirs()
if (testFile.mkdirs()) {
throw new RuntimeException("File should not be able to"
+ " create directories");
}
// renameTo(File)
if (testFile.renameTo(new File("dest")))
throw new RuntimeException("File rename should fail");
if (new File("dest").renameTo(testFile))
throw new RuntimeException("File rename should fail");
try {
exceptionThrown = false;
testFile.renameTo(null);
} catch (NullPointerException ex) {
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("File rename should thrown NPE");
}
// setLastModified(long)
if (testFile.setLastModified(0L)) {
throw new RuntimeException("File should fail to set"
+ " last modified time");
}
try {
exceptionThrown = false;
testFile.setLastModified(-1);
} catch (IllegalArgumentException ex) {
if ("Negative time".equals(ex.getMessage()))
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("File should fail to set"
+ " last modified time with message \"Negative time\"");
}
// setReadOnly()
if (testFile.setReadOnly())
throw new RuntimeException("File should fail to set read-only");
// setWritable(boolean writable, boolean ownerOnly)
if (testFile.setWritable(true, true))
throw new RuntimeException("File should fail to set writable");
if (testFile.setWritable(true, false))
throw new RuntimeException("File should fail to set writable");
if (testFile.setWritable(false, true))
throw new RuntimeException("File should fail to set writable");
if (testFile.setWritable(false, false))
throw new RuntimeException("File should fail to set writable");
// setWritable(boolean writable)
if (testFile.setWritable(false))
throw new RuntimeException("File should fail to set writable");
if (testFile.setWritable(true))
throw new RuntimeException("File should fail to set writable");
// setReadable(boolean readable, boolean ownerOnly)
if (testFile.setReadable(true, true))
throw new RuntimeException("File should fail to set readable");
if (testFile.setReadable(true, false))
throw new RuntimeException("File should fail to set readable");
if (testFile.setReadable(false, true))
throw new RuntimeException("File should fail to set readable");
if (testFile.setReadable(false, false))
throw new RuntimeException("File should fail to set readable");
// setReadable(boolean readable)
if (testFile.setReadable(false))
throw new RuntimeException("File should fail to set readable");
if (testFile.setReadable(true))
throw new RuntimeException("File should fail to set readable");
// setExecutable(boolean executable, boolean ownerOnly)
if (testFile.setExecutable(true, true))
throw new RuntimeException("File should fail to set executable");
if (testFile.setExecutable(true, false))
throw new RuntimeException("File should fail to set executable");
if (testFile.setExecutable(false, true))
throw new RuntimeException("File should fail to set executable");
if (testFile.setExecutable(false, false))
throw new RuntimeException("File should fail to set executable");
// setExecutable(boolean executable)
if (testFile.setExecutable(false))
throw new RuntimeException("File should fail to set executable");
if (testFile.setExecutable(true))
throw new RuntimeException("File should fail to set executable");
// canExecute()
if (testFile.canExecute())
throw new RuntimeException("File should not be executable");
// getTotalSpace()
if (testFile.getTotalSpace() != 0L)
throw new RuntimeException("The total space should be 0L");
// getFreeSpace()
if (testFile.getFreeSpace() != 0L)
throw new RuntimeException("The free space should be 0L");
// getUsableSpace()
if (testFile.getUsableSpace() != 0L)
throw new RuntimeException("The usable space should be 0L");
// compareTo(File null)
try {
exceptionThrown = false;
testFile.compareTo(null);
} catch (NullPointerException ex) {
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("compareTo(null) should throw NPE");
}
// toString()
if (testFile.toString().indexOf(CHAR_NUL) < 0) {
throw new RuntimeException(
"File path should contain Nul character");
}
// toPath()
try {
exceptionThrown = false;
testFile.toPath();
} catch (InvalidPathException ex) {
exceptionThrown = true;
}
if (!exceptionThrown) {
throw new RuntimeException("toPath() should throw"
+ " InvalidPathException");
}
}
private static void testSerialization(File testFile) {
String path = testFile.getPath();
try {
// serialize test file
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(testFile);
oos.close();
// deserialize test file
byte[] bytes = baos.toByteArray();
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(is);
File newFile = (File) ois.readObject();
// test
String newPath = newFile.getPath();
if (!path.equals(newPath)) {
throw new RuntimeException(
"Serialization should not change file path");
}
test(newFile, false);
} catch (IOException | ClassNotFoundException ex) {
System.err.println("Exception happens in testSerialization");
System.err.println(ex.getMessage());
}
}
private static void testTempFile() {
final String[] names = {"x", "xx", "xxx", "xxxx"};
final String shortPrefix = "sp";
final String prefix = "prefix";
final String suffix = "suffix";
File tmpDir = new File("tmpDir");
for (String name : names) {
int length = name.length();
for (int i = 0; i <= length; i++) {
StringBuilder sbName = new StringBuilder(name);
sbName.insert(i, CHAR_NUL);
String curName = sbName.toString();
// test prefix
testCreateTempFile(curName, suffix, tmpDir);
// test suffix
testCreateTempFile(shortPrefix, curName, tmpDir);
testCreateTempFile(prefix, curName, tmpDir);
// test directory
testCreateTempFile(shortPrefix, suffix, new File(curName));
testCreateTempFile(prefix, suffix, new File(curName));
}
}
}
private static void testCreateTempFile(String prefix, String suffix,
File directory) {
// createTempFile(String prefix, String suffix, File directory)
boolean exceptionThrown = false;
boolean shortPrefix = (prefix.length() < 3);
if (shortPrefix) {
try {
File.createTempFile(prefix, suffix, directory);
} catch (IllegalArgumentException ex) {
if ("Prefix string too short".equals(ex.getMessage()))
exceptionThrown = true;
} catch (IOException ioe) {
System.err.println("IOException happens in testCreateTempFile");
System.err.println(ioe.getMessage());
}
} else {
try {
File.createTempFile(prefix, suffix, directory);
} catch (IOException ex) {
if ("Unable to create temporary file".equals(ex.getMessage()))
exceptionThrown = true;
}
}
if (!exceptionThrown) {
throw new RuntimeException("createTempFile() should throw"
+ (shortPrefix ? " IllegalArgumentException"
: " IOException"));
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册