diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java index b02b91624ed..2fba50a3832 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java @@ -51,8 +51,19 @@ class WindowsUserDefinedFileAttributeView throw new NullPointerException("'name' is null"); return file + ":" + name; } + private String join(WindowsPath file, String name) throws WindowsException { - return join(file.getPathForWin32Calls(), name); + if (name == null) + throw new NullPointerException("'name' is null"); + WindowsFileSystem wfs = file.getFileSystem(); + WindowsPath namePath = WindowsPath.parse(wfs, name); + if (namePath.getRoot() != null) + throw new IllegalArgumentException("'name' has a root component"); + if (namePath.getParent() != null) + throw new IllegalArgumentException("'name' has more than one element"); + String path = join(file.getPathForWin32Calls(), name); + WindowsPath wp = WindowsPath.createFromNormalizedPath(wfs, path); + return wp.getPathForWin32Calls(); } private final WindowsPath file; diff --git a/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java b/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java index 5f40d193cf0..bc47b8719f2 100644 --- a/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java +++ b/test/jdk/java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2021, 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,21 +22,27 @@ */ /* @test - * @bug 4313887 6838333 + * @bug 4313887 6838333 8273922 * @summary Unit test for java.nio.file.attribute.UserDefinedFileAttributeView - * @library ../.. + * @library ../.. /test/lib * @key randomness + * @build jdk.test.lib.Platform + * @run main Basic */ +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.Charset; -import java.nio.file.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; import static java.nio.file.LinkOption.*; import java.nio.file.attribute.*; import java.util.Arrays; import java.util.Map; import java.util.Random; -import java.io.IOException; +import jdk.test.lib.Platform; public class Basic { @@ -144,9 +150,16 @@ public class Basic { throw new RuntimeException("Unexpected attribute value"); } - static void miscTests(final Path file) throws IOException { + private static void setEA(Path longPath, String s) throws IOException { + System.out.println("Setting short EA '" + s + + "' on path of length " + longPath.toString().length()); + Files.setAttribute(longPath, s, + ByteBuffer.wrap("ea-value".getBytes(StandardCharsets.UTF_8))); + } + + static void miscTests(final Path dir) throws IOException { final UserDefinedFileAttributeView view = - Files.getFileAttributeView(file, UserDefinedFileAttributeView.class); + Files.getFileAttributeView(dir, UserDefinedFileAttributeView.class); view.write(ATTR_NAME, ByteBuffer.wrap(ATTR_VALUE.getBytes())); // NullPointerException @@ -178,31 +191,31 @@ public class Basic { }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.getAttribute(file, null); + Files.getAttribute(dir, null); }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.getAttribute(file, "user:" + ATTR_NAME, (LinkOption[])null); + Files.getAttribute(dir, "user:" + ATTR_NAME, (LinkOption[])null); }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.setAttribute(file, "user:" + ATTR_NAME, null); + Files.setAttribute(dir, "user:" + ATTR_NAME, null); }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.setAttribute(file, null, new byte[0]); + Files.setAttribute(dir, null, new byte[0]); }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.setAttribute(file, "user: " + ATTR_NAME, new byte[0], (LinkOption[])null); + Files.setAttribute(dir, "user: " + ATTR_NAME, new byte[0], (LinkOption[])null); }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.readAttributes(file, (String)null); + Files.readAttributes(dir, (String)null); }}); expectNullPointerException(new Task() { public void run() throws IOException { - Files.readAttributes(file, "*", (LinkOption[])null); + Files.readAttributes(dir, "*", (LinkOption[])null); }}); // Read-only buffer @@ -221,6 +234,37 @@ public class Basic { buf.position(buf.capacity()); view.read(ATTR_NAME, buf); }}); + + // Long attribute name + if (Platform.isWindows()) { + Path tmp = Files.createTempDirectory(dir, "ea-length-bug"); + int len = tmp.toString().length(); + + // We need to run up to MAX_PATH for directories, + // but not quite go over it. + int MAX_PATH = 247; + int requiredLen = MAX_PATH - len - 2; + + // Create a really long directory name. + Path longPath = tmp.resolve("x".repeat(requiredLen)); + + // Make sure the directory exists. + Files.createDirectory(longPath); + + try { + // Try to set absolute path as extended attribute; expect IAE + tryCatch(IllegalArgumentException.class, new Task() { + public void run() throws IOException { + setEA(longPath, "user:C:\\"); + }}); + + // Try to set an extended attribute on it. + setEA(longPath, "user:short"); + setEA(longPath, "user:reallyquitelonglongattrname"); + } finally { + Files.delete(longPath); + } + } } public static void main(String[] args) throws IOException {