blob: c7cff6aa81dc57caf858bf0dc7596fe7dcd196ab [file] [log] [blame]
dxu8d584d82013-05-06 14:17:59 -07001/*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* @test
25 * @bug 8003992
26 * @summary Test a file whose path name is embedded with NUL character, and
27 * ensure it is handled correctly.
28 * @author Dan Xu
29 */
30
31import java.io.File;
32import java.io.FileFilter;
33import java.io.FileInputStream;
34import java.io.FileOutputStream;
35import java.io.RandomAccessFile;
36import java.io.FileNotFoundException;
37import java.io.FilenameFilter;
38import java.io.IOException;
39import java.net.MalformedURLException;
40import java.nio.file.InvalidPathException;
41import java.io.ByteArrayInputStream;
42import java.io.ByteArrayOutputStream;
43import java.io.ObjectOutputStream;
44import java.io.ObjectInputStream;
45
46public class NulFile {
47
48 private static final char CHAR_NUL = '\u0000';
49
50 private static final String ExceptionMsg = "Invalid file path";
51
52 public static void main(String[] args) {
53 testFile();
54 testFileInUnix();
55 testFileInWindows();
56 testTempFile();
57 }
58
59 private static void testFile() {
60 test(new File(new StringBuilder().append(CHAR_NUL).toString()));
61 test(new File(
62 new StringBuilder().append("").append(CHAR_NUL).toString()));
63 test(new File(
64 new StringBuilder().append(CHAR_NUL).append("").toString()));
65 }
66
67 private static void testFileInUnix() {
68 String osName = System.getProperty("os.name");
69 if (osName.startsWith("Windows"))
70 return;
71
72 String unixFile = "/";
73 test(unixFile);
74
75 unixFile = "//";
76 test(unixFile);
77
78 unixFile = "data/info";
79 test(unixFile);
80
81 unixFile = "/data/info";
82 test(unixFile);
83
84 unixFile = "//data//info";
85 test(unixFile);
86 }
87
88 private static void testFileInWindows() {
89 String osName = System.getProperty("os.name");
90 if (!osName.startsWith("Windows"))
91 return;
92
93 String windowsFile = "\\";
94 test(windowsFile);
95
96 windowsFile = "\\\\";
97 test(windowsFile);
98
99 windowsFile = "/";
100 test(windowsFile);
101
102 windowsFile = "//";
103 test(windowsFile);
104
105 windowsFile = "/\\";
106 test(windowsFile);
107
108 windowsFile = "\\/";
109 test(windowsFile);
110
111 windowsFile = "data\\info";
112 test(windowsFile);
113
114 windowsFile = "\\data\\info";
115 test(windowsFile);
116
117 windowsFile = "\\\\server\\data\\info";
118 test(windowsFile);
119
120 windowsFile = "z:data\\info";
121 test(windowsFile);
122
123 windowsFile = "z:\\data\\info";
124 test(windowsFile);
125 }
126
127 private static void test(final String name) {
128 int length = name.length();
129
130 for (int i = 0; i <= length; i++) {
131 StringBuilder sbName = new StringBuilder(name);
132 sbName.insert(i, CHAR_NUL);
133 String curName = sbName.toString();
134
135 // test File(String parent, String child)
136 File testFile = new File(curName, "child");
137 test(testFile);
138 testFile = new File("parent", curName);
139 test(testFile);
140
141 // test File(String pathname)
142 testFile = new File(curName);
143 test(testFile);
144
145 // test File(File parent, String child)
146 testFile = new File(new File(curName), "child");
147 test(testFile);
148 testFile = new File(new File("parent"), curName);
149 test(testFile);
150
151 // test FileInputStream
152 testFileInputStream(curName);
153
154 // test FileOutputStream
155 testFileOutputStream(curName);
156
157 // test RandomAccessFile
158 testRandomAccessFile(curName);
159 }
160 }
161
162 private static void testFileInputStream(final String str) {
163 boolean exceptionThrown = false;
164 FileInputStream is = null;
165 try {
166 is = new FileInputStream(str);
167 } catch (FileNotFoundException ex) {
168 if (ExceptionMsg.equals(ex.getMessage()))
169 exceptionThrown = true;
170 }
171 if (!exceptionThrown) {
172 throw new RuntimeException("FileInputStream constructor"
173 + " should throw FileNotFoundException");
174 }
175 if (is != null) {
176 throw new RuntimeException("FileInputStream constructor"
177 + " should fail");
178 }
179
180 exceptionThrown = false;
181 is = null;
182 try {
183 is = new FileInputStream(new File(str));
184 } catch (FileNotFoundException ex) {
185 if (ExceptionMsg.equals(ex.getMessage()))
186 exceptionThrown = true;
187 }
188 if (!exceptionThrown) {
189 throw new RuntimeException("FileInputStream constructor"
190 + " should throw FileNotFoundException");
191 }
192 if (is != null) {
193 throw new RuntimeException("FileInputStream constructor"
194 + " should fail");
195 }
196 }
197
198 private static void testFileOutputStream(final String str) {
199 boolean exceptionThrown = false;
200 FileOutputStream os = null;
201 try {
202 os = new FileOutputStream(str);
203 } catch (FileNotFoundException ex) {
204 if (ExceptionMsg.equals(ex.getMessage()))
205 exceptionThrown = true;
206 }
207 if (!exceptionThrown) {
208 throw new RuntimeException("FileOutputStream constructor"
209 + " should throw FileNotFoundException");
210 }
211 if (os != null) {
212 throw new RuntimeException("FileOutputStream constructor"
213 + " should fail");
214 }
215
216 exceptionThrown = false;
217 os = null;
218 try {
219 os = new FileOutputStream(new File(str));
220 } catch (FileNotFoundException ex) {
221 if (ExceptionMsg.equals(ex.getMessage()))
222 exceptionThrown = true;
223 }
224 if (!exceptionThrown) {
225 throw new RuntimeException("FileOutputStream constructor"
226 + " should throw FileNotFoundException");
227 }
228 if (os != null) {
229 throw new RuntimeException("FileOutputStream constructor"
230 + " should fail");
231 }
232 }
233
234 private static void testRandomAccessFile(final String str) {
235 boolean exceptionThrown = false;
236 RandomAccessFile raf = null;
237 String[] modes = {"r", "rw", "rws", "rwd"};
238
239 for (String mode : modes) {
240 try {
241 raf = new RandomAccessFile(str, mode);
242 } catch (FileNotFoundException ex) {
243 if (ExceptionMsg.equals(ex.getMessage()))
244 exceptionThrown = true;
245 }
246 if (!exceptionThrown) {
247 throw new RuntimeException("RandomAccessFile constructor"
248 + " should throw FileNotFoundException");
249 }
250 if (raf != null) {
251 throw new RuntimeException("RandomAccessFile constructor"
252 + " should fail");
253 }
254
255 exceptionThrown = false;
256 raf = null;
257 try {
258 raf = new RandomAccessFile(new File(str), mode);
259 } catch (FileNotFoundException ex) {
260 if (ExceptionMsg.equals(ex.getMessage()))
261 exceptionThrown = true;
262 }
263 if (!exceptionThrown) {
264 throw new RuntimeException("RandomAccessFile constructor"
265 + " should throw FileNotFoundException");
266 }
267 if (raf != null) {
268 throw new RuntimeException("RandomAccessFile constructor"
269 + " should fail");
270 }
271 }
272 }
273
274 private static void test(File testFile) {
275 test(testFile, false);
276 // test serialization
277 testSerialization(testFile);
278 }
279
280 @SuppressWarnings("deprecation")
281 private static void test(File testFile, boolean derived) {
282 boolean exceptionThrown = false;
283
284 if (testFile == null) {
285 throw new RuntimeException("test file should not be null.");
286 }
287
288 // getPath()
289 if (testFile.getPath().indexOf(CHAR_NUL) < 0) {
290 throw new RuntimeException(
291 "File path should contain Nul character");
292 }
293 // getAbsolutePath()
294 if (testFile.getAbsolutePath().indexOf(CHAR_NUL) < 0) {
295 throw new RuntimeException(
296 "File absolute path should contain Nul character");
297 }
298 // getAbsoluteFile()
299 File derivedAbsFile = testFile.getAbsoluteFile();
300 if (derived) {
301 if (derivedAbsFile.getPath().indexOf(CHAR_NUL) < 0) {
302 throw new RuntimeException(
303 "Derived file path should also contain Nul character");
304 }
305 } else {
306 test(derivedAbsFile, true);
307 }
308 // getCanonicalPath()
309 try {
310 exceptionThrown = false;
311 testFile.getCanonicalPath();
312 } catch (IOException ex) {
313 if (ExceptionMsg.equals(ex.getMessage()))
314 exceptionThrown = true;
315 }
316 if (!exceptionThrown) {
317 throw new RuntimeException(
318 "getCanonicalPath() should throw IOException with"
319 + " message \"" + ExceptionMsg + "\"");
320 }
321 // getCanonicalFile()
322 try {
323 exceptionThrown = false;
324 testFile.getCanonicalFile();
325 } catch (IOException ex) {
326 if (ExceptionMsg.equals(ex.getMessage()))
327 exceptionThrown = true;
328 }
329 if (!exceptionThrown) {
330 throw new RuntimeException(
331 "getCanonicalFile() should throw IOException with"
332 + " message \"" + ExceptionMsg + "\"");
333 }
334 // toURL()
335 try {
336 exceptionThrown = false;
337 testFile.toURL();
338 } catch (MalformedURLException ex) {
339 if (ExceptionMsg.equals(ex.getMessage()))
340 exceptionThrown = true;
341 }
342 if (!exceptionThrown) {
343 throw new RuntimeException("toURL() should throw IOException with"
344 + " message \"" + ExceptionMsg + "\"");
345 }
346 // canRead()
347 if (testFile.canRead())
348 throw new RuntimeException("File should not be readable");
349 // canWrite()
350 if (testFile.canWrite())
351 throw new RuntimeException("File should not be writable");
352 // exists()
353 if (testFile.exists())
354 throw new RuntimeException("File should not be existed");
355 // isDirectory()
356 if (testFile.isDirectory())
357 throw new RuntimeException("File should not be a directory");
358 // isFile()
359 if (testFile.isFile())
360 throw new RuntimeException("File should not be a file");
361 // isHidden()
362 if (testFile.isHidden())
363 throw new RuntimeException("File should not be hidden");
364 // lastModified()
365 if (testFile.lastModified() != 0L)
366 throw new RuntimeException("File last modified time should be 0L");
367 // length()
368 if (testFile.length() != 0L)
369 throw new RuntimeException("File length should be 0L");
370 // createNewFile()
371 try {
372 exceptionThrown = false;
373 testFile.createNewFile();
374 } catch (IOException ex) {
375 if (ExceptionMsg.equals(ex.getMessage()))
376 exceptionThrown = true;
377 }
378 if (!exceptionThrown) {
379 throw new RuntimeException(
380 "createNewFile() should throw IOException with"
381 + " message \"" + ExceptionMsg + "\"");
382 }
383 // delete()
384 if (testFile.delete())
385 throw new RuntimeException("Delete operation should fail");
386 // list()
387 if (testFile.list() != null)
388 throw new RuntimeException("File list() should return null");
389 // list(FilenameFilter)
390 FilenameFilter fnFilter = new FilenameFilter() {
391 @Override
392 public boolean accept(File dir, String name) {
393 return false;
394 }
395 };
396 if (testFile.list(fnFilter) != null) {
397 throw new RuntimeException("File list(FilenameFilter) should"
398 + " return null");
399 }
400 // listFiles()
401 if (testFile.listFiles() != null)
402 throw new RuntimeException("File listFiles() should return null");
403 // listFiles(FilenameFilter)
404 if (testFile.listFiles(fnFilter) != null) {
405 throw new RuntimeException("File listFiles(FilenameFilter)"
406 + " should return null");
407 }
408 // listFiles(FileFilter)
409 FileFilter fFilter = new FileFilter() {
410 @Override
411 public boolean accept(File file) {
412 return false;
413 }
414 };
415 if (testFile.listFiles(fFilter) != null) {
416 throw new RuntimeException("File listFiles(FileFilter)"
417 + " should return null");
418 }
419 // mkdir()
420 if (testFile.mkdir()) {
421 throw new RuntimeException("File should not be able to"
422 + " create directory");
423 }
424 // mkdirs()
425 if (testFile.mkdirs()) {
426 throw new RuntimeException("File should not be able to"
427 + " create directories");
428 }
429 // renameTo(File)
430 if (testFile.renameTo(new File("dest")))
431 throw new RuntimeException("File rename should fail");
432 if (new File("dest").renameTo(testFile))
433 throw new RuntimeException("File rename should fail");
434 try {
435 exceptionThrown = false;
436 testFile.renameTo(null);
437 } catch (NullPointerException ex) {
438 exceptionThrown = true;
439 }
440 if (!exceptionThrown) {
441 throw new RuntimeException("File rename should thrown NPE");
442 }
443 // setLastModified(long)
444 if (testFile.setLastModified(0L)) {
445 throw new RuntimeException("File should fail to set"
446 + " last modified time");
447 }
448 try {
449 exceptionThrown = false;
450 testFile.setLastModified(-1);
451 } catch (IllegalArgumentException ex) {
452 if ("Negative time".equals(ex.getMessage()))
453 exceptionThrown = true;
454 }
455 if (!exceptionThrown) {
456 throw new RuntimeException("File should fail to set"
457 + " last modified time with message \"Negative time\"");
458 }
459 // setReadOnly()
460 if (testFile.setReadOnly())
461 throw new RuntimeException("File should fail to set read-only");
462 // setWritable(boolean writable, boolean ownerOnly)
463 if (testFile.setWritable(true, true))
464 throw new RuntimeException("File should fail to set writable");
465 if (testFile.setWritable(true, false))
466 throw new RuntimeException("File should fail to set writable");
467 if (testFile.setWritable(false, true))
468 throw new RuntimeException("File should fail to set writable");
469 if (testFile.setWritable(false, false))
470 throw new RuntimeException("File should fail to set writable");
471 // setWritable(boolean writable)
472 if (testFile.setWritable(false))
473 throw new RuntimeException("File should fail to set writable");
474 if (testFile.setWritable(true))
475 throw new RuntimeException("File should fail to set writable");
476 // setReadable(boolean readable, boolean ownerOnly)
477 if (testFile.setReadable(true, true))
478 throw new RuntimeException("File should fail to set readable");
479 if (testFile.setReadable(true, false))
480 throw new RuntimeException("File should fail to set readable");
481 if (testFile.setReadable(false, true))
482 throw new RuntimeException("File should fail to set readable");
483 if (testFile.setReadable(false, false))
484 throw new RuntimeException("File should fail to set readable");
485 // setReadable(boolean readable)
486 if (testFile.setReadable(false))
487 throw new RuntimeException("File should fail to set readable");
488 if (testFile.setReadable(true))
489 throw new RuntimeException("File should fail to set readable");
490 // setExecutable(boolean executable, boolean ownerOnly)
491 if (testFile.setExecutable(true, true))
492 throw new RuntimeException("File should fail to set executable");
493 if (testFile.setExecutable(true, false))
494 throw new RuntimeException("File should fail to set executable");
495 if (testFile.setExecutable(false, true))
496 throw new RuntimeException("File should fail to set executable");
497 if (testFile.setExecutable(false, false))
498 throw new RuntimeException("File should fail to set executable");
499 // setExecutable(boolean executable)
500 if (testFile.setExecutable(false))
501 throw new RuntimeException("File should fail to set executable");
502 if (testFile.setExecutable(true))
503 throw new RuntimeException("File should fail to set executable");
504 // canExecute()
505 if (testFile.canExecute())
506 throw new RuntimeException("File should not be executable");
507 // getTotalSpace()
508 if (testFile.getTotalSpace() != 0L)
509 throw new RuntimeException("The total space should be 0L");
510 // getFreeSpace()
511 if (testFile.getFreeSpace() != 0L)
512 throw new RuntimeException("The free space should be 0L");
513 // getUsableSpace()
514 if (testFile.getUsableSpace() != 0L)
515 throw new RuntimeException("The usable space should be 0L");
516 // compareTo(File null)
517 try {
518 exceptionThrown = false;
519 testFile.compareTo(null);
520 } catch (NullPointerException ex) {
521 exceptionThrown = true;
522 }
523 if (!exceptionThrown) {
524 throw new RuntimeException("compareTo(null) should throw NPE");
525 }
526 // toString()
527 if (testFile.toString().indexOf(CHAR_NUL) < 0) {
528 throw new RuntimeException(
529 "File path should contain Nul character");
530 }
531 // toPath()
532 try {
533 exceptionThrown = false;
534 testFile.toPath();
535 } catch (InvalidPathException ex) {
536 exceptionThrown = true;
537 }
538 if (!exceptionThrown) {
539 throw new RuntimeException("toPath() should throw"
540 + " InvalidPathException");
541 }
542 }
543
544 private static void testSerialization(File testFile) {
545 String path = testFile.getPath();
546 try {
547 // serialize test file
548 ByteArrayOutputStream baos = new ByteArrayOutputStream();
549 ObjectOutputStream oos = new ObjectOutputStream(baos);
550 oos.writeObject(testFile);
551 oos.close();
552 // deserialize test file
553 byte[] bytes = baos.toByteArray();
554 ByteArrayInputStream is = new ByteArrayInputStream(bytes);
555 ObjectInputStream ois = new ObjectInputStream(is);
556 File newFile = (File) ois.readObject();
557 // test
558 String newPath = newFile.getPath();
559 if (!path.equals(newPath)) {
560 throw new RuntimeException(
561 "Serialization should not change file path");
562 }
563 test(newFile, false);
564 } catch (IOException | ClassNotFoundException ex) {
565 System.err.println("Exception happens in testSerialization");
566 System.err.println(ex.getMessage());
567 }
568 }
569
570 private static void testTempFile() {
571 final String[] names = {"x", "xx", "xxx", "xxxx"};
572 final String shortPrefix = "sp";
573 final String prefix = "prefix";
574 final String suffix = "suffix";
575 File tmpDir = new File("tmpDir");
576
577 for (String name : names) {
578 int length = name.length();
579 for (int i = 0; i <= length; i++) {
580 StringBuilder sbName = new StringBuilder(name);
581 sbName.insert(i, CHAR_NUL);
582 String curName = sbName.toString();
583
584 // test prefix
585 testCreateTempFile(curName, suffix, tmpDir);
586 // test suffix
587 testCreateTempFile(shortPrefix, curName, tmpDir);
588 testCreateTempFile(prefix, curName, tmpDir);
589 // test directory
590 testCreateTempFile(shortPrefix, suffix, new File(curName));
591 testCreateTempFile(prefix, suffix, new File(curName));
592 }
593 }
594 }
595
596 private static void testCreateTempFile(String prefix, String suffix,
597 File directory) {
598 // createTempFile(String prefix, String suffix, File directory)
599 boolean exceptionThrown = false;
600 boolean shortPrefix = (prefix.length() < 3);
601 if (shortPrefix) {
602 try {
603 File.createTempFile(prefix, suffix, directory);
604 } catch (IllegalArgumentException ex) {
605 if ("Prefix string too short".equals(ex.getMessage()))
606 exceptionThrown = true;
607 } catch (IOException ioe) {
608 System.err.println("IOException happens in testCreateTempFile");
609 System.err.println(ioe.getMessage());
610 }
611 } else {
612 try {
613 File.createTempFile(prefix, suffix, directory);
614 } catch (IOException ex) {
dxu598ed162013-06-10 11:06:26 -0700615 if (ExceptionMsg.equals(ex.getMessage()))
dxu8d584d82013-05-06 14:17:59 -0700616 exceptionThrown = true;
617 }
618 }
619 if (!exceptionThrown) {
620 throw new RuntimeException("createTempFile() should throw"
621 + (shortPrefix ? " IllegalArgumentException"
622 : " IOException"));
623 }
624 }
625}