8189953: FileHandler constructor throws NoSuchFileException with absolute path
Reviewed-by: mchung
This commit is contained in:
parent
6c99853a4c
commit
ccdb0ef8e2
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
@ -616,79 +616,96 @@ public class FileHandler extends StreamHandler {
|
||||
* @throws IOException
|
||||
*/
|
||||
private File generate(String pattern, int generation, int unique)
|
||||
throws IOException {
|
||||
File file = null;
|
||||
String word = "";
|
||||
int ix = 0;
|
||||
throws IOException
|
||||
{
|
||||
return generate(pattern, count, generation, unique);
|
||||
}
|
||||
|
||||
// The static method here is provided for whitebox testing of the algorithm.
|
||||
static File generate(String pat, int count, int generation, int unique)
|
||||
throws IOException
|
||||
{
|
||||
Path path = Paths.get(pat);
|
||||
Path result = null;
|
||||
boolean sawg = false;
|
||||
boolean sawu = false;
|
||||
while (ix < pattern.length()) {
|
||||
char ch = pattern.charAt(ix);
|
||||
ix++;
|
||||
char ch2 = 0;
|
||||
if (ix < pattern.length()) {
|
||||
ch2 = Character.toLowerCase(pattern.charAt(ix));
|
||||
StringBuilder word = new StringBuilder();
|
||||
Path prev = null;
|
||||
for (Path elem : path) {
|
||||
if (prev != null) {
|
||||
prev = prev.resolveSibling(word.toString());
|
||||
result = result == null ? prev : result.resolve(prev);
|
||||
}
|
||||
if (ch == '/') {
|
||||
if (file == null) {
|
||||
file = new File(word);
|
||||
} else {
|
||||
file = new File(file, word);
|
||||
String pattern = elem.toString();
|
||||
int ix = 0;
|
||||
word.setLength(0);
|
||||
while (ix < pattern.length()) {
|
||||
char ch = pattern.charAt(ix);
|
||||
ix++;
|
||||
char ch2 = 0;
|
||||
if (ix < pattern.length()) {
|
||||
ch2 = Character.toLowerCase(pattern.charAt(ix));
|
||||
}
|
||||
word = "";
|
||||
continue;
|
||||
} else if (ch == '%') {
|
||||
if (ch2 == 't') {
|
||||
String tmpDir = System.getProperty("java.io.tmpdir");
|
||||
if (tmpDir == null) {
|
||||
tmpDir = System.getProperty("user.home");
|
||||
if (ch == '%') {
|
||||
if (ch2 == 't') {
|
||||
String tmpDir = System.getProperty("java.io.tmpdir");
|
||||
if (tmpDir == null) {
|
||||
tmpDir = System.getProperty("user.home");
|
||||
}
|
||||
result = Paths.get(tmpDir);
|
||||
ix++;
|
||||
word.setLength(0);
|
||||
continue;
|
||||
} else if (ch2 == 'h') {
|
||||
result = Paths.get(System.getProperty("user.home"));
|
||||
if (jdk.internal.misc.VM.isSetUID()) {
|
||||
// Ok, we are in a set UID program. For safety's sake
|
||||
// we disallow attempts to open files relative to %h.
|
||||
throw new IOException("can't use %h in set UID program");
|
||||
}
|
||||
ix++;
|
||||
word.setLength(0);
|
||||
continue;
|
||||
} else if (ch2 == 'g') {
|
||||
word = word.append(generation);
|
||||
sawg = true;
|
||||
ix++;
|
||||
continue;
|
||||
} else if (ch2 == 'u') {
|
||||
word = word.append(unique);
|
||||
sawu = true;
|
||||
ix++;
|
||||
continue;
|
||||
} else if (ch2 == '%') {
|
||||
word = word.append('%');
|
||||
ix++;
|
||||
continue;
|
||||
}
|
||||
file = new File(tmpDir);
|
||||
ix++;
|
||||
word = "";
|
||||
continue;
|
||||
} else if (ch2 == 'h') {
|
||||
file = new File(System.getProperty("user.home"));
|
||||
if (jdk.internal.misc.VM.isSetUID()) {
|
||||
// Ok, we are in a set UID program. For safety's sake
|
||||
// we disallow attempts to open files relative to %h.
|
||||
throw new IOException("can't use %h in set UID program");
|
||||
}
|
||||
ix++;
|
||||
word = "";
|
||||
continue;
|
||||
} else if (ch2 == 'g') {
|
||||
word = word + generation;
|
||||
sawg = true;
|
||||
ix++;
|
||||
continue;
|
||||
} else if (ch2 == 'u') {
|
||||
word = word + unique;
|
||||
sawu = true;
|
||||
ix++;
|
||||
continue;
|
||||
} else if (ch2 == '%') {
|
||||
word = word + "%";
|
||||
ix++;
|
||||
continue;
|
||||
}
|
||||
word = word.append(ch);
|
||||
}
|
||||
word = word + ch;
|
||||
prev = elem;
|
||||
}
|
||||
|
||||
if (count > 1 && !sawg) {
|
||||
word = word + "." + generation;
|
||||
word = word.append('.').append(generation);
|
||||
}
|
||||
if (unique > 0 && !sawu) {
|
||||
word = word + "." + unique;
|
||||
word = word.append('.').append(unique);
|
||||
}
|
||||
if (word.length() > 0) {
|
||||
if (file == null) {
|
||||
file = new File(word);
|
||||
} else {
|
||||
file = new File(file, word);
|
||||
}
|
||||
String n = word.toString();
|
||||
Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n);
|
||||
result = result == null ? p : result.resolve(p);
|
||||
} else if (result == null) {
|
||||
result = Paths.get("");
|
||||
}
|
||||
|
||||
if (path.getRoot() == null) {
|
||||
return result.toFile();
|
||||
} else {
|
||||
return path.getRoot().resolve(result).toFile();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
|
232
test/jdk/java/util/logging/FileHandlerPatternGeneration.java
Normal file
232
test/jdk/java/util/logging/FileHandlerPatternGeneration.java
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8189953
|
||||
* @summary tests the pattern generation algorithm
|
||||
* @modules java.logging/java.util.logging:open
|
||||
* @run main/othervm FileHandlerPatternGeneration
|
||||
* @author danielfuchs
|
||||
*/
|
||||
public class FileHandlerPatternGeneration {
|
||||
|
||||
/**
|
||||
* An array of strings where the elements at even indices are the input
|
||||
* to give to FileHandler::generate(pattern, count, generation, unique),
|
||||
* and the elements at the next odd index are a partially computed expected
|
||||
* output, where %t, %h, %u, %g and file separator still need to be replaced.
|
||||
* The final expected output is obtained by passing the partially computed
|
||||
* output to FileHandlerPatternGeneration::generateExpected
|
||||
* <p>
|
||||
* The test verifies that {@code
|
||||
* FileHandler.generate(PATTERN[i], c, g, u).toString()
|
||||
* }
|
||||
* is equal to {@code
|
||||
* FileHandlerPatternGeneration.generateExpected(PATTERN[i],
|
||||
* PATTERN[i+1],
|
||||
* c, g, u)
|
||||
* }
|
||||
*/
|
||||
static final String[] PATTERNS = {
|
||||
"C:/Workspace/hoge.log", "C:/Workspace/hoge.log",
|
||||
"C:/Workspace%g/hoge.log", "C:/Workspace%g/hoge.log",
|
||||
"C:/%uWorkspace/hoge.log", "C:/%uWorkspace/hoge.log",
|
||||
"C:/%uWorkspace%g/hoge.log", "C:/%uWorkspace%g/hoge.log",
|
||||
"C:/Workspace/%ghoge.log", "C:/Workspace/%ghoge.log",
|
||||
"C:/Workspace/%ghoge%u.log", "C:/Workspace/%ghoge%u.log",
|
||||
"C:/Workspace-%g/hoge.log", "C:/Workspace-%g/hoge.log",
|
||||
"C:/Work%hspace/hoge.log", "%h/space/hoge.log",
|
||||
"C:/Works%tpace%g/hoge.log", "%t/pace%g/hoge.log",
|
||||
"C:/%uWork%hspace/hoge.log", "%h/space/hoge.log",
|
||||
"C:/%uWorkspace%g/%thoge.log", "%t/hoge.log",
|
||||
"C:/Workspace/%g%h%%hoge.log", "%h/%%hoge.log",
|
||||
"C:/Work%h%%hspace/hoge.log", "%h/%%hspace/hoge.log",
|
||||
"C:/Works%t%%hpace%g/hoge.log", "%t/%%hpace%g/hoge.log",
|
||||
"C:/%uWork%h%%tspace/hoge.log", "%h/%%tspace/hoge.log",
|
||||
"C:/%uWorkspace%g/%t%%hoge.log", "%t/%%hoge.log",
|
||||
"C:/Workspace/%g%h%%hoge.log", "%h/%%hoge.log",
|
||||
"ahaha", "ahaha",
|
||||
"ahaha/ahabe", "ahaha/ahabe",
|
||||
"../ahaha/ahabe", "../ahaha/ahabe",
|
||||
"/x%ty/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"/x/%ty/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"/x%t/y/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"/x/%t/y/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"%ty/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"%t/y/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"/x%hy/w/hoge.log", "%h/y/w/hoge.log",
|
||||
"/x/%hy/w/hoge.log", "%h/y/w/hoge.log",
|
||||
"/x%h/y/w/hoge.log", "%h/y/w/hoge.log",
|
||||
"/x/%h/y/w/hoge.log", "%h/y/w/hoge.log",
|
||||
"%hy/w/hoge.log", "%h/y/w/hoge.log",
|
||||
"%h/y/w/hoge.log", "%h/y/w/hoge.log",
|
||||
"ahaha-%u-%g", "ahaha-%u-%g",
|
||||
"ahaha-%g/ahabe-%u", "ahaha-%g/ahabe-%u",
|
||||
"../ahaha-%u/ahabe", "../ahaha-%u/ahabe",
|
||||
"/x%ty/w/hoge-%g.log", "%t/y/w/hoge-%g.log",
|
||||
"/x/%ty/w/hoge-%u.log", "%t/y/w/hoge-%u.log",
|
||||
"%u-%g/x%t/y/w/hoge.log", "%t/y/w/hoge.log",
|
||||
"/x/%g%t%u/y/w/hoge.log", "%t/%u/y/w/hoge.log",
|
||||
"%ty/w-%g/hoge.log", "%t/y/w-%g/hoge.log",
|
||||
"%t/y/w-%u/hoge.log", "%t/y/w-%u/hoge.log",
|
||||
"/x%hy/%u-%g-w/hoge.log", "%h/y/%u-%g-w/hoge.log",
|
||||
"/x/%hy/w-%u-%g/hoge.log", "%h/y/w-%u-%g/hoge.log",
|
||||
"/x%h/y/w/%u-%ghoge.log", "%h/y/w/%u-%ghoge.log",
|
||||
"/x/%h/y/w/hoge-%u-%g.log", "%h/y/w/hoge-%u-%g.log",
|
||||
"%hy/w/%u-%g-hoge.log", "%h/y/w/%u-%g-hoge.log",
|
||||
"%h/y/w/hoge-%u-%g.log", "%h/y/w/hoge-%u-%g.log",
|
||||
"/x/y/z/hoge-%u.log", "/x/y/z/hoge-%u.log",
|
||||
};
|
||||
|
||||
// the (count, generation, unique) parameters to pass to
|
||||
// FileHandler.generate(pattern, count, generation, unique)
|
||||
static final int[][] GENERATIONS = {
|
||||
{0, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{1, 1, 0},
|
||||
{1, 1, 1},
|
||||
{1, 1, 2},
|
||||
{1, 2, 3},
|
||||
{3, 4, 0},
|
||||
{3, 4, 1},
|
||||
{3, 4, 2},
|
||||
{3, 0, 5},
|
||||
{3, 1, 5},
|
||||
{3, 2, 5},
|
||||
};
|
||||
|
||||
static final Class<FileHandler> FILE_HANDLER_CLASS = FileHandler.class;
|
||||
static final Method GENERATE;
|
||||
static final String USER_HOME;
|
||||
static final String TMP;
|
||||
static {
|
||||
Method generate;
|
||||
try {
|
||||
generate = FILE_HANDLER_CLASS.getDeclaredMethod("generate",
|
||||
String.class,
|
||||
int.class,
|
||||
int.class,
|
||||
int.class);
|
||||
generate.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
GENERATE = generate;
|
||||
USER_HOME = System.getProperty("user.home");
|
||||
TMP = System.getProperty("java.io.tmpdir", USER_HOME);
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
|
||||
for (int i=0; i < PATTERNS.length; i+=2) {
|
||||
String s = PATTERNS[i];
|
||||
String partial = PATTERNS[i+1];
|
||||
System.out.println("generate: " + s);
|
||||
for (int[] gen : GENERATIONS) {
|
||||
String expected = generateExpected(s, partial, gen[0], gen[1], gen[2]);
|
||||
String output = generate(s, gen[0], gen[1], gen[2]).toString();
|
||||
System.out.println("\t" + Arrays.toString(gen)+ ": " + output);
|
||||
if (!expected.equals(output)) {
|
||||
throw new RuntimeException("test failed for \""
|
||||
+ s +"\" " + Arrays.toString(gen) + ": "
|
||||
+ "\n\tgenerated: \"" + output +"\""
|
||||
+ "\n\t expected: \"" + expected +"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Strip the trailing separator from the string, if present
|
||||
static String stripTrailingSeparator(String s) {
|
||||
if (s.endsWith("/")) {
|
||||
return s.substring(0, s.length() -1);
|
||||
} else if (s.endsWith(File.separator)) {
|
||||
return s.substring(0, s.length() - File.separator.length());
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the final expected output from a partially computed output found
|
||||
* at PATTERNS[i+1]
|
||||
* @param s The pattern string, found at PATTERN[i]
|
||||
* (with i % 2 == 0)
|
||||
* @param partial The partially computed output, found at PATTERN[i+1]
|
||||
* @param count The count parameter given to FileHandler::generate
|
||||
* @param generation The generation parameter given to FileHandler::generate
|
||||
* @param unique The unique parameter given to FileHandler::generate
|
||||
* @return The expected output that FileHandler.generate(s, count, gen, unique)
|
||||
* should produce.
|
||||
*/
|
||||
static String generateExpected(String s, String partial,
|
||||
int count, int generation, int unique)
|
||||
{
|
||||
boolean sawu = s.replace("%%", "$$$$").contains("%u");
|
||||
boolean sawg = s.replace("%%", "$$$$").contains("%g");
|
||||
String result = partial.replace("%%", "$$$$");
|
||||
String tmp = stripTrailingSeparator(TMP);
|
||||
String home = stripTrailingSeparator(USER_HOME);
|
||||
result = result.replace("%h", home);
|
||||
result = result.replace("%t", tmp);
|
||||
result = result.replace("%g", String.valueOf(generation));
|
||||
result = result.replace("%u", String.valueOf(unique));
|
||||
result = result.replace("$$$$", "%");
|
||||
result = result.replace("/", File.separator);
|
||||
if (count > 1 && !sawg) {
|
||||
result = result + "." + generation;
|
||||
}
|
||||
if (unique > 0 && !sawu) {
|
||||
result = result + "." + unique;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calls FileHandler.generate(s, count, generation, unique) through reflection
|
||||
static File generate(String s, int count, int generation, int unique)
|
||||
throws Throwable
|
||||
{
|
||||
try {
|
||||
return (File) GENERATE.invoke(null, s, count, generation, unique);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user