From ccab6bc563e18381de796c7ddebd81f7e561ec5a Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Wed, 10 Dec 2014 15:01:26 +0000 Subject: [PATCH] 8066915: (fs) Files.newByteChannel opens directories for cases where subsequent reads may fail Reviewed-by: chegar --- .../classes/sun/nio/fs/UnixChannelFactory.java | 16 ++++++++++++++++ jdk/test/java/nio/file/Files/SBC.java | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java index bc194f960ae..90a9c787ff0 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java @@ -270,6 +270,22 @@ class UnixChannelFactory { throw x; } + // fail if the file is a directory + if (flags.read) { + UnixException exc = null; + try { + if (UnixFileAttributes.get(fd).isDirectory()) { + exc = new UnixException(EISDIR); + } + } catch (UnixException x) { + exc = x; + } + if (exc != null) { + close(fd); + throw exc; + } + } + // unlink file immediately if delete on close. The spec is clear that // an implementation cannot guarantee to unlink the correct file when // replaced by an attacker after it is opened. diff --git a/jdk/test/java/nio/file/Files/SBC.java b/jdk/test/java/nio/file/Files/SBC.java index d26428d5f60..64672d27947 100644 --- a/jdk/test/java/nio/file/Files/SBC.java +++ b/jdk/test/java/nio/file/Files/SBC.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 + * @bug 4313887 8066915 * @summary Unit test for java.nio.file.Files.newByteChannel * @library .. */ @@ -59,6 +59,7 @@ public class SBC { dosSharingOptionTests(dir); // misc. tests + directoryOpenTests(dir); badCombinations(dir); unsupportedOptions(dir); nullTests(dir); @@ -278,6 +279,21 @@ public class SBC { } } + // test opening a directory for read or write + static void directoryOpenTests(Path dir) throws Exception { + try (SeekableByteChannel sbc = Files.newByteChannel(dir, READ)) { + throw new RuntimeException("Opened directory for read"); + } catch (IOException expected) { } + + try (SeekableByteChannel sbc = Files.newByteChannel(dir, WRITE)) { + throw new RuntimeException("Opened directory for write"); + } catch (IOException expected) { } + + try (SeekableByteChannel sbc = Files.newByteChannel(dir, APPEND)) { + throw new RuntimeException("Opened directory for append "); + } catch (IOException expected) { } + } + // Windows specific options for the use by applications that really want // to use legacy DOS sharing options static void dosSharingOptionTests(Path dir) throws Exception {