JDK-5077609 : File constructors allow path names which are not supported on the file system
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-07-23
  • Updated: 2009-02-16
  • Resolved: 2009-02-16
Related Reports
Duplicate :  
Relates :  
Description
Name: js151677			Date: 07/23/2004


FULL PRODUCT VERSION :
java version "1.4.2_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_01-b06)
Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Creating a java.io.File with characters, that are not supported by the
Windows Operating System, leads to no error. canWrite() returns true and
an opened outputstream can actually be written to.

In the filesystem is a file being created with the name of the file
up to the character leading to the problem and with file-size 0. All data being
written to is lost, but the application itself will never get some kind of error
as exception or other to be aware of that fact.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
 - Open a FileOutputStream with an invalid filename, e.g. "foo:bar.txt"
 - Write to it happliy
 - Look into the filesystem and see an empty file with name "foo"

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
canWrite should return false for the invalid file.
Opening a FileOutputStream for writing to a file with invalid filename should
throw an IOException
ACTUAL -
See description and steps to reproduce

ERROR MESSAGES/STACK TRACES THAT OCCUR :
There are no error-messages, that's the problem

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Excerpt from my JUnit-testcase. To reproduce the empty file after
writing comment out the assertEquals checking the canWrite of File.

    public void testInvalidFileNameWriting() throws Exception{
        File file = new File("/temp/bla:fasel.txt");
        assertEquals("check canWrite", false, file.canWrite());
        FileOutputStream fos = new FileOutputStream(file);
        for (int i = 0; i < 1000; i++){
            fos.write(i % Byte.MAX_VALUE);
            System.out.println("(" + i + ") ");
        }
        System.out.println();
        fos.close();
    }

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No workaround found so far, except checking the validity of a filename
by hand giving up platform-independency.
(Incident Review ID: 286773) 
======================================================================

Comments
EVALUATION The problem cited isn't completely solvable because the underlying file system/volume isn't known until the file is accessed. However, the new file system API will reject path strings that aren't syntactically correct or contain reserved characters that are not allowed by the operating system (on Windows for example, paths cannot reserved characters such as < > : \ " | ? * etc.
16-02-2009

EVALUATION It's not completely obvious which behavior is correct. It seems likely that Java is just reflecting the semantics of the underlying filesystem, in the same way that opening "FOO" succeeds when the file on disk is actually called "foo". Should that throw? ###@###.### 2004-07-23
23-07-2004