# HG changeset patch # User jpai # Date 1572334153 -19800 # Tue Oct 29 12:59:13 2019 +0530 # Node ID cca3882217e7231c47ea4b881fb0d47ff1c327d7 # Parent e5867c8ddb03772ef5091278b51b433b56a0e716 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: diff --git a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java --- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java +++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -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)); diff --git a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java --- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java +++ b/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -788,7 +788,7 @@ { if (options.length == 0) return zfs.newOutputStream(getResolvedPath(), - CREATE_NEW, WRITE); + CREATE, TRUNCATE_EXISTING, WRITE); return zfs.newOutputStream(getResolvedPath(), options); } diff --git a/test/demo/zipfs/ZFSTests.java b/test/demo/zipfs/ZFSTests.java --- a/test/demo/zipfs/ZFSTests.java +++ b/test/demo/zipfs/ZFSTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, 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 env = new HashMap(); + env.put("create", "true"); + try (FileSystem fs = FileSystems.newFileSystem(uri, env)) { + FileSystemProvider fsp = fs.provider(); + Set 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); + } + } }