changeset 13826:d13abc740e42

8028480: (zipfs) NoSuchFileException on creating a file in ZipFileSystem with CREATE and WRITE 8034773: (zipfs) newOutputstream uses CREATE_NEW when no options specified Summary: to open the new steram with appropricate open options Reviewed-by: alanb, clanger
author sherman
date Tue, 29 Oct 2019 12:59:13 +0530
parents 07925e568508
children 1152345ed661
files src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java test/demo/zipfs/ZFSTests.java
diffstat 3 files changed, 63 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java	Mon Mar 28 12:36:33 2016 +0530
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java	Tue Oct 29 12:59:13 2019 +0530
@@ -497,6 +497,7 @@
         boolean hasCreateNew = false;
         boolean hasCreate = false;
         boolean hasAppend = false;
+        boolean hasTruncate = false;
         for (OpenOption opt: options) {
             if (opt == READ)
                 throw new IllegalArgumentException("READ not allowed");
@@ -506,7 +507,11 @@
                 hasCreate = true;
             if (opt == APPEND)
                 hasAppend = true;
+            if (opt == TRUNCATE_EXISTING)
+                hasTruncate = true;
         }
+        if (hasAppend && hasTruncate)
+            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
         beginRead();                 // only need a readlock, the "update()" will
         try {                        // try to obtain a writelock when the os is
             ensureOpen();            // being closed.
@@ -558,6 +563,8 @@
             if (!(option instanceof StandardOpenOption))
                 throw new IllegalArgumentException();
         }
+        if (options.contains(APPEND) && options.contains(TRUNCATE_EXISTING))
+            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
     }
 
     // Returns a Writable/ReadByteChannel for now. Might consdier to use
@@ -705,15 +712,19 @@
             if (forWrite) {
                 checkWritable();
                 if (e == null) {
-                if (!options.contains(StandardOpenOption.CREATE_NEW))
-                    throw new NoSuchFileException(getString(path));
+                    if (!options.contains(StandardOpenOption.CREATE) &&
+                        !options.contains(StandardOpenOption.CREATE_NEW)) {
+                        throw new NoSuchFileException(getString(path));
+                    }
                 } else {
-                    if (options.contains(StandardOpenOption.CREATE_NEW))
+                    if (options.contains(StandardOpenOption.CREATE_NEW)) {
                         throw new FileAlreadyExistsException(getString(path));
+                    }
                     if (e.isDir())
                         throw new FileAlreadyExistsException("directory <"
                             + getString(path) + "> exists");
                 }
+                options = new HashSet<>(options);
                 options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
             } else if (e == null || e.isDir()) {
                 throw new NoSuchFileException(getString(path));
--- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java	Mon Mar 28 12:36:33 2016 +0530
+++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java	Tue Oct 29 12:59:13 2019 +0530
@@ -788,7 +788,7 @@
     {
         if (options.length == 0)
             return zfs.newOutputStream(getResolvedPath(),
-                                       CREATE_NEW, WRITE);
+                                       CREATE, TRUNCATE_EXISTING, WRITE);
         return zfs.newOutputStream(getResolvedPath(), options);
     }
 
--- a/test/demo/zipfs/ZFSTests.java	Mon Mar 28 12:36:33 2016 +0530
+++ b/test/demo/zipfs/ZFSTests.java	Tue Oct 29 12:59:13 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -22,20 +22,23 @@
  */
 
 /* @test
-   @bug 7156873
+   @bug 7156873 8028480 8034773
    @summary ZipFileSystem regression tests
  */
 
-
+import java.io.OutputStream;
 import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
 import java.nio.file.*;
-import java.util.Map;
-import java.util.HashMap;
+import java.nio.file.spi.*;
+import java.util.*;
 
 public class ZFSTests {
 
     public static void main(String[] args) throws Throwable {
         test7156873();
+        testOpenOptions();
     }
 
     static void test7156873() throws Throwable {
@@ -53,4 +56,44 @@
             Files.deleteIfExists(dir);
         }
     }
+
+    static void testOpenOptions() throws Throwable {
+        Path path = Paths.get("file.zip");
+        try {
+            URI uri = URI.create("jar:" + path.toUri());
+            Map<String, Object> env = new HashMap<String, Object>();
+            env.put("create", "true");
+            try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
+                FileSystemProvider fsp = fs.provider();
+                Set<? extends OpenOption> options;
+                Path p = fs.getPath("test.txt");
+                // 8028480
+                options = EnumSet.of(StandardOpenOption.CREATE,
+                                     StandardOpenOption.WRITE,
+                                     StandardOpenOption.APPEND);
+                try (FileChannel ch = fsp.newFileChannel(p, options)) {
+                    ch.write(ByteBuffer.wrap("Hello!".getBytes("ASCII")));
+                }
+                // 8034773
+                try (OutputStream os = fsp.newOutputStream(p, new OpenOption[0])) {
+                    os.write("Hello2!".getBytes("ASCII"));
+                }
+                if (!"Hello2!".equals(new String(
+                        Files.readAllBytes(fs.getPath("test.txt"))))) {
+                    throw new RuntimeException("failed to open as truncate_existing");
+                }
+
+                options = EnumSet.of(StandardOpenOption.CREATE,
+                                     StandardOpenOption.APPEND,
+                                     StandardOpenOption.TRUNCATE_EXISTING);
+                try (FileChannel ch = fsp.newFileChannel(p, options)) {
+                    throw new RuntimeException("expected IAE not thrown!");
+                } catch (IllegalArgumentException x) {
+                    // expected x.printStackTrace();
+                }
+            }
+        } finally {
+            Files.deleteIfExists(path);
+        }
+    }
 }