summaryrefslogtreecommitdiff
path: root/java/openjdk6/files/icedtea/openjdk/8003992-embedded_nulls.patch
diff options
context:
space:
mode:
Diffstat (limited to 'java/openjdk6/files/icedtea/openjdk/8003992-embedded_nulls.patch')
-rw-r--r--java/openjdk6/files/icedtea/openjdk/8003992-embedded_nulls.patch1026
1 files changed, 1026 insertions, 0 deletions
diff --git a/java/openjdk6/files/icedtea/openjdk/8003992-embedded_nulls.patch b/java/openjdk6/files/icedtea/openjdk/8003992-embedded_nulls.patch
new file mode 100644
index 000000000000..88c94927c7dd
--- /dev/null
+++ b/java/openjdk6/files/icedtea/openjdk/8003992-embedded_nulls.patch
@@ -0,0 +1,1026 @@
+# HG changeset patch
+# User dxu
+# Date 1383015918 0
+# Tue Oct 29 03:05:18 2013 +0000
+# Node ID 8ad2eb12bf42f2564fdf80a7236e4046046a4f4e
+# Parent 44a49c18eba21f97222a2cde09f6536a7f365363
+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
+
+diff -r 44a49c18eba2 -r 8ad2eb12bf42 src/share/classes/java/io/File.java
+--- jdk/src/share/classes/java/io/File.java Fri Sep 06 09:38:10 2013 -0700
++++ jdk/src/share/classes/java/io/File.java Tue Oct 29 03:05:18 2013 +0000
+@@ -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
+@@ -153,6 +153,32 @@
+ private 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.
+ */
+@@ -573,6 +599,9 @@
+ * @since JDK1.1
+ */
+ public String getCanonicalPath() throws IOException {
++ if (isInvalid()) {
++ throw new IOException("Invalid file path");
++ }
+ return fs.canonicalize(fs.resolve(this));
+ }
+
+@@ -637,6 +666,9 @@
+ */
+ @Deprecated
+ public URL toURL() throws MalformedURLException {
++ if (isInvalid()) {
++ throw new MalformedURLException("Invalid file path");
++ }
+ return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
+ }
+
+@@ -705,6 +737,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.checkAccess(this, FileSystem.ACCESS_READ);
+ }
+
+@@ -727,6 +762,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
+ }
+
+@@ -747,6 +785,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
+ }
+
+@@ -768,6 +809,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
+ != 0);
+ }
+@@ -792,6 +836,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
+ }
+
+@@ -818,6 +865,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
+ }
+
+@@ -840,6 +890,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return 0L;
++ }
+ return fs.getLastModifiedTime(this);
+ }
+
+@@ -862,6 +915,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return 0L;
++ }
+ return fs.getLength(this);
+ }
+
+@@ -897,6 +953,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, false);
+ }
+
+@@ -918,6 +977,9 @@
+ if (security != null) {
+ security.checkDelete(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.delete(this);
+ }
+
+@@ -953,6 +1015,9 @@
+ if (security != null) {
+ security.checkDelete(path);
+ }
++ if (isInvalid()) {
++ return;
++ }
+ DeleteOnExitHook.add(path);
+ }
+
+@@ -987,6 +1052,9 @@
+ if (security != null) {
+ security.checkRead(path);
+ }
++ if (isInvalid()) {
++ return null;
++ }
+ return fs.list(this);
+ }
+
+@@ -1168,6 +1236,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.createDirectory(this);
+ }
+
+@@ -1239,6 +1310,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);
+ }
+
+@@ -1274,6 +1351,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.setLastModifiedTime(this, time);
+ }
+
+@@ -1299,6 +1379,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.setReadOnly(this);
+ }
+
+@@ -1333,6 +1416,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
+ }
+
+@@ -1399,6 +1485,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
+ }
+
+@@ -1468,6 +1557,9 @@
+ if (security != null) {
+ security.checkWrite(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
+ }
+
+@@ -1522,6 +1614,9 @@
+ if (security != null) {
+ security.checkExec(path);
+ }
++ if (isInvalid()) {
++ return false;
++ }
+ return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
+ }
+
+@@ -1597,6 +1692,9 @@
+ sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
+ sm.checkRead(path);
+ }
++ if (isInvalid()) {
++ return 0L;
++ }
+ return fs.getSpace(this, FileSystem.SPACE_TOTAL);
+ }
+
+@@ -1613,7 +1711,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}.
+@@ -1632,6 +1730,9 @@
+ sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
+ sm.checkRead(path);
+ }
++ if (isInvalid()) {
++ return 0L;
++ }
+ return fs.getSpace(this, FileSystem.SPACE_FREE);
+ }
+
+@@ -1670,6 +1771,9 @@
+ sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
+ sm.checkRead(path);
+ }
++ if (isInvalid()) {
++ return 0L;
++ }
+ return fs.getSpace(this, FileSystem.SPACE_USABLE);
+ }
+
+@@ -1682,9 +1786,9 @@
+
+ static final String temporaryDirectory = temporaryDirectory();
+ static String temporaryDirectory() {
+- return fs.normalize(
++ return
+ AccessController.doPrivileged(
+- new GetPropertyAction("java.io.tmpdir")));
++ new GetPropertyAction("java.io.tmpdir"));
+ }
+ }
+
+@@ -1735,6 +1839,9 @@
+ File f;
+ do {
+ f = generateFile(prefix, s, directory);
++ if (f.isInvalid()) {
++ throw new IOException("Unable to create temporary file");
++ }
+ } while (!checkAndCreate(f.getPath(), sm, restrictive));
+ return f;
+ }
+diff -r 44a49c18eba2 -r 8ad2eb12bf42 src/share/classes/java/io/FileInputStream.java
+--- jdk/src/share/classes/java/io/FileInputStream.java Fri Sep 06 09:38:10 2013 -0700
++++ jdk/src/share/classes/java/io/FileInputStream.java Tue Oct 29 03:05:18 2013 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1994, 2007, 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
+@@ -132,6 +132,9 @@
+ if (name == null) {
+ throw new NullPointerException();
+ }
++ if (file.isInvalid()) {
++ throw new FileNotFoundException("Invalid file path");
++ }
+ fd = new FileDescriptor();
+ fd.incrementAndGetUseCount();
+ open(name);
+diff -r 44a49c18eba2 -r 8ad2eb12bf42 src/share/classes/java/io/FileOutputStream.java
+--- jdk/src/share/classes/java/io/FileOutputStream.java Fri Sep 06 09:38:10 2013 -0700
++++ jdk/src/share/classes/java/io/FileOutputStream.java Tue Oct 29 03:05:18 2013 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1994, 2007, 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
+@@ -200,6 +200,9 @@
+ if (name == null) {
+ throw new NullPointerException();
+ }
++ if (file.isInvalid()) {
++ throw new FileNotFoundException("Invalid file path");
++ }
+ fd = new FileDescriptor();
+ fd.incrementAndGetUseCount();
+ this.append = append;
+diff -r 44a49c18eba2 -r 8ad2eb12bf42 src/share/classes/java/io/RandomAccessFile.java
+--- jdk/src/share/classes/java/io/RandomAccessFile.java Fri Sep 06 09:38:10 2013 -0700
++++ jdk/src/share/classes/java/io/RandomAccessFile.java Tue Oct 29 03:05:18 2013 +0000
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1994, 2007, 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 @@
+ if (name == null) {
+ throw new NullPointerException();
+ }
++ if (file.isInvalid()) {
++ throw new FileNotFoundException("Invalid file path");
++ }
+ fd = new FileDescriptor();
+ fd.incrementAndGetUseCount();
+ open(name, imode);
+diff -r 44a49c18eba2 -r 8ad2eb12bf42 test/java/io/File/NulFile.java
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ jdk/test/java/io/File/NulFile.java Tue Oct 29 03:05:18 2013 +0000
+@@ -0,0 +1,625 @@
++/*
++ * 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"));
++ }
++ }
++}