TrueZIP
  1. TrueZIP
  2. TRUEZIP-68

Accessing an archive file with a colon in its base name throws up in several places

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: TrueZIP 7.0 RC 1, TrueZIP 7.0 RC 2
    • Fix Version/s: TrueZIP 7.0
    • Component/s: TrueZIP Kernel
    • Labels:
      None
    • Environment:

      All platforms.

      Description

      File names with colon are legal in Java, at least when running under Ubuntu. However, accessing a ZIP file with a colon in its name throws an exception. This can be triggered with the code

      File TMP = File.createTempFile("foo:bar", ".zip");
      new TFile(TMP).exists();
      

        Issue Links

          Activity

          Hide
          Christian Schlichtherle added a comment - - edited

          This seems to be a bug when parsing the path name and is platform independent, so it happens on Windows, too.

          While I am analyzing this, please note that this is not the proper way to create a temporary ZIP file anyway. Try the following instead:

          TFile tmp = new TFile(File.createTempFile("foo", ".zip"));
          tmp.delete(); // delete plain file
          tmp.mkdir(); // create archive file
          

          or alternatively:

          TFile tmp = new TFile(File.createTempFile("foo", ".zip"));
          tmp.delete(); // delete plain file
          OutputStream out = new TFileOutputStream(new TFile(tmp, "entry")); // create "foo*.zip/entry"
          try {
              // ...
          } finally {
              out.close();
          }
          
          Show
          Christian Schlichtherle added a comment - - edited This seems to be a bug when parsing the path name and is platform independent, so it happens on Windows, too. While I am analyzing this, please note that this is not the proper way to create a temporary ZIP file anyway. Try the following instead: TFile tmp = new TFile(File.createTempFile( "foo" , ".zip" )); tmp.delete(); // delete plain file tmp.mkdir(); // create archive file or alternatively: TFile tmp = new TFile(File.createTempFile( "foo" , ".zip" )); tmp.delete(); // delete plain file OutputStream out = new TFileOutputStream( new TFile(tmp, "entry" )); // create "foo*.zip/entry" try { // ... } finally { out.close(); }
          Hide
          Christian Schlichtherle added a comment -

          Edited.

          Show
          Christian Schlichtherle added a comment - Edited.
          Hide
          Christian Schlichtherle added a comment - - edited

          The simplest form for reproducing the NullPointerException is:

          new TFile("foo:bar.zip").exists();
          

          If you enable assertions, you will see an AssertionError instead because of a violated invariant of the class FsEntryName. The cause for this violation is a bug in the method java.net.URI.relativize(java.net.URI). Along the call sequence in TrueZIP, an equivalent of the following expression is computed:

          URI uri = new URI("file:/path/").relativize(new URI("file:/path/foo:bar.zip"));
          

          Now uri.getPath() returns "foo:bar.zip" as expected. However, uri.getRawPath() does not return "foo%3Abar.zip" as expected. When reusing the result of the expression later on, this results in subsequent errors and finally an AssertionError if assertions are enabled or a NullPointerException if assertions are disabled.

          I have filed a bug report to Oracle. It should soon be available at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7037120. Meanwhile, I will work on a work around.

          Show
          Christian Schlichtherle added a comment - - edited The simplest form for reproducing the NullPointerException is: new TFile( "foo:bar.zip" ).exists(); If you enable assertions, you will see an AssertionError instead because of a violated invariant of the class FsEntryName. The cause for this violation is a bug in the method java.net.URI.relativize(java.net.URI). Along the call sequence in TrueZIP, an equivalent of the following expression is computed: URI uri = new URI( "file:/path/" ).relativize( new URI( "file:/path/foo:bar.zip" )); Now uri.getPath() returns "foo:bar.zip" as expected. However, uri.getRawPath() does not return "foo%3Abar.zip" as expected. When reusing the result of the expression later on, this results in subsequent errors and finally an AssertionError if assertions are enabled or a NullPointerException if assertions are disabled. I have filed a bug report to Oracle. It should soon be available at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7037120 . Meanwhile, I will work on a work around.
          Hide
          Christian Schlichtherle added a comment - - edited

          Fixing this issue was a nightmare, but it should be done now.

          The root cause of this issue is a bug in the class java.net.URI: It's five parameter constructor does not quote a colon in the path component for relative URIs (i.e. those with an undefined scheme). To fix this, I've added three new classes UriBuilder, UriEncoder and UriDecoder with appropriate unit tests. I filed a bug report to bugs.sun.com, but it's not public yet and for some unknown reason I cannot even log in to this site anymore in order to quote the issue number - damn.

          After fixing this, I suppose it should now work on POSIX systems, i.e. Linux, Unix, Mac OS X.

          However, it still does not work under Windows, because the java.io.File class has some bugs when accessing paths with colons, too. E.g. when calling new java.io.File("foo:bar").createNewFile() a file with the path name "foo" is created instead of the path name "foo:bar". I recall to have read somewhere that a colon is not a legal character in a Windows path name anyway, but then I would expect the java.io.File constructor to throw an IllegalArgumentException instead of the createNewFile() method doing something unexpected. Because I cannot login to bugs.sun.com, I did not check or file another bug report for this.

          In summary, I can only recommend to avoid colons in path names.

          Show
          Christian Schlichtherle added a comment - - edited Fixing this issue was a nightmare, but it should be done now. The root cause of this issue is a bug in the class java.net.URI: It's five parameter constructor does not quote a colon in the path component for relative URIs (i.e. those with an undefined scheme). To fix this, I've added three new classes UriBuilder, UriEncoder and UriDecoder with appropriate unit tests. I filed a bug report to bugs.sun.com, but it's not public yet and for some unknown reason I cannot even log in to this site anymore in order to quote the issue number - damn. After fixing this, I suppose it should now work on POSIX systems, i.e. Linux, Unix, Mac OS X. However, it still does not work under Windows, because the java.io.File class has some bugs when accessing paths with colons, too. E.g. when calling new java.io.File("foo:bar").createNewFile() a file with the path name "foo" is created instead of the path name "foo:bar". I recall to have read somewhere that a colon is not a legal character in a Windows path name anyway, but then I would expect the java.io.File constructor to throw an IllegalArgumentException instead of the createNewFile() method doing something unexpected. Because I cannot login to bugs.sun.com, I did not check or file another bug report for this. In summary, I can only recommend to avoid colons in path names.
          Hide
          TokeEskildsen added a comment -

          Thank you for your hard work on this issue.

          A search on microsoft.com confirms that colon is indeed illegal under Windows file system (FAT32 & NTFS): http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx#naming_conventions so avoiding colon in file names seems like the right advice, even now that TrueZIP supports it. I have upstreamed the observation to our data delivery guy.

          Show
          TokeEskildsen added a comment - Thank you for your hard work on this issue. A search on microsoft.com confirms that colon is indeed illegal under Windows file system (FAT32 & NTFS): http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx#naming_conventions so avoiding colon in file names seems like the right advice, even now that TrueZIP supports it. I have upstreamed the observation to our data delivery guy.
          Hide
          Christian Schlichtherle added a comment -

          new FsArchiveFileSystem(EntryFactory<E> factory, EntryContainer<E> archive, Entry rootTemplate) throws an AssertionError when mounting an archive file with a colon in its path name.

          Show
          Christian Schlichtherle added a comment - new FsArchiveFileSystem(EntryFactory<E> factory, EntryContainer<E> archive, Entry rootTemplate) throws an AssertionError when mounting an archive file with a colon in its path name.
          Hide
          Christian Schlichtherle added a comment -

          Changeset: 3b07ffbe48e9
          Author: Christian Schlichtherle <christian AT schlichtherle DOT de>
          Date: 2011-05-21 05:22
          Message: Revisioned and extended MockArchiveDriver and associated classes.
          Issue #TRUEZIP-68 - Accessing an archive file with a colon in its base name throws up in several places

          Show
          Christian Schlichtherle added a comment - Changeset: 3b07ffbe48e9 Author: Christian Schlichtherle <christian AT schlichtherle DOT de> Date: 2011-05-21 05:22 Message: Revisioned and extended MockArchiveDriver and associated classes. Issue # TRUEZIP-68 - Accessing an archive file with a colon in its base name throws up in several places

            People

            • Assignee:
              Christian Schlichtherle
              Reporter:
              TokeEskildsen
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: