Just for reference - this came up while debugging an issue, that one of
our users of Apache Ant project raised here
https://bz.apache.org/bugzilla/show_bug.cgi?id=62764#c8

-Jaikiran


On 04/10/18 3:06 PM, Jaikiran Pai wrote:
> Please consider the following trivial code:
>
> import java.util.jar.*;
> import java.io.*;
>
> public class JarFileTest {
>     public static void main(final String[] args) throws Exception {
>         final String tmpDir = System.getProperty("java.io.tmpdir");
>         try {
>             final JarFile jarFile = new JarFile(tmpDir + File.separator
> + "*");
>         } catch (IOException ioe) {
>             System.out.println("Got the expected IOException " + ioe);
>         }
>     }
> }
>
> The constructor of the JarFile is passed a string which intentionally is
> an (wildcard) invalid path. The above code (as expected) throws an
> IOException on *nix systems across various version of Java (tested
> against Java 8, 11). The same code throws an IOException (as expected)
> in Java 8 on Windows OS too. However, in Java 11, on Windows OS, this
> code throws a different exception (java.nio.file.InvalidPathException)
> which isn't IOException or a subclass of it:
>
> Exception in thread "main" java.nio.file.InvalidPathException: Illegal
> char <*> at index 38: C:\Users\someone\AppData\Local\Temp\1\*
> at
> java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
> at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
> at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
> at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
> at
> java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229)
> at java.base/java.io.File.toPath(File.java:2290)
> at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1220)
> at
> java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:727)
> at java.base/java.util.zip.ZipFile$CleanableResource.get(ZipFile.java:845)
> at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:245)
> at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:175)
> at java.base/java.util.jar.JarFile.<init>(JarFile.java:341)
> at java.base/java.util.jar.JarFile.<init>(JarFile.java:312)
> at java.base/java.util.jar.JarFile.<init>(JarFile.java:251)
> at JarFileTest.main(JarFileTest.java:8)
>
>
> The javadoc of JarFile constructor(s) mentions that:
>
>      * @throws IOException if an I/O error has occurred
>
> Given that the javadoc doesn't mention anything about this other
> exception, would this throwing of java.nio.file.InvalidPathException be
> considered a bug in the implementation?
>
> If this indeed is considered a bug, it appears to be the code in
> java.util.zip.ZipFile$Source.get method which calls File#toPath(), which
> as per its javadoc is indeed expected to throw an
> java.nio.file.InvalidPathException if a Path cannot be constructed out
> of the File. Looking at the implementation of the underlying
> java.nio.file.FileSystem on *nix and Windows, they differ when it comes
> to whether or not the exception gets thrown (Unix one seems to always
> return a result). But keeping the implementation of
> java.nio.file.FileSystem aside, I guess the
> java.util.zip.ZipFile$Source.get code needs to have a catch block for
> the InvalidPathException to wrap that into a IOException? Something like:
>
>
> # HG changeset patch
> # User Jaikiran Pai <jaikiran....@gmail.com>
> # Date 1538645309 -19800
> #      Thu Oct 04 14:58:29 2018 +0530
> # Node ID ff1bfd8cc9a3b385716fa5191bb68989d552f87e
> # Parent  8705c6d536c5c197d0210acccf145ebc48f90227
> Wrap and throw an IOException when a InvalidPathException is thrown
>
> diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java
> b/src/java.base/share/classes/java/util/zip/ZipFile.java
> --- a/src/java.base/share/classes/java/util/zip/ZipFile.java
> +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java
> @@ -35,6 +35,7 @@
>  import java.lang.ref.Cleaner.Cleanable;
>  import java.nio.charset.Charset;
>  import java.nio.charset.StandardCharsets;
> +import java.nio.file.InvalidPathException;
>  import java.nio.file.attribute.BasicFileAttributes;
>  import java.nio.file.Files;
>  import java.util.ArrayDeque;
> @@ -1218,8 +1219,13 @@
>  
>  
>          static Source get(File file, boolean toDelete) throws IOException {
> -            Key key = new Key(file,
> -                              Files.readAttributes(file.toPath(),
> BasicFileAttributes.class));
> +            final Key key;
> +            try {
> +                key = new Key(file,
> +                        Files.readAttributes(file.toPath(),
> BasicFileAttributes.class));
> +            } catch (InvalidPathException ipe) {
> +                throw new IOException(ipe);
> +            }
>              Source src;
>              synchronized (files) {
>                  src = files.get(key);
>
>
> Any thoughts?
>
>
> -Jaikiran
>

Reply via email to