--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/File/NulFile.java Mon May 06 14:17:59 2013 -0700
@@ -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"));
+ }
+ }
+}