8278356: Improve file creation

Reviewed-by: bpb
This commit is contained in:
Rob McKenna 2022-02-08 00:23:34 +00:00
parent 515e5f5a39
commit 3564d325e6
4 changed files with 61 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2022, 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
@ -175,8 +175,9 @@ public class File
/**
* Check if the file has an invalid path. Currently, the inspection of
* a file path is very limited, and it only covers Nul character check.
* Returning true means the path is definitely invalid/garbage. But
* a file path is very limited, and it only covers Nul character check
* unless further checking is explicitly enabled by a system property.
* Returning true means the path is definitely invalid/garbage, but
* returning false does not guarantee that the path is valid.
*
* @return true if the file path is invalid.
@ -184,8 +185,7 @@ public class File
final boolean isInvalid() {
PathStatus s = status;
if (s == null) {
s = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
: PathStatus.INVALID;
s = fs.isInvalid(this) ? PathStatus.INVALID : PathStatus.CHECKED;
status = s;
}
return s == PathStatus.INVALID;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2022, 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
@ -87,6 +87,11 @@ abstract class FileSystem {
*/
public abstract boolean isAbsolute(File f);
/**
* Tell whether the given abstract pathname is invalid.
*/
public abstract boolean isInvalid(File f);
/**
* Resolve the given abstract pathname into absolute form. Invoked by the
* getAbsolutePath and getCanonicalPath methods in the File class.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2022, 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
@ -141,6 +141,11 @@ class UnixFileSystem extends FileSystem {
return (f.getPrefixLength() != 0);
}
@Override
public boolean isInvalid(File f) {
return f.getPath().indexOf('\u0000') < 0 ? false : true;
}
@Override
public String resolve(File f) {
if (isAbsolute(f)) return f.getPath();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2022, 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
@ -26,6 +26,7 @@
package java.io;
import java.io.File;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.BitSet;
import java.util.Locale;
@ -45,6 +46,21 @@ class WinNTFileSystem extends FileSystem {
private final char semicolon;
private final String userDir;
// Whether to enable alternative data streams (ADS) by suppressing
// checking the path for invalid characters, in particular ":".
// ADS support will be enabled if and only if the property is set and
// is the empty string or is equal, ignoring case, to the string "true".
// By default ADS support is disabled.
private static final boolean ENABLE_ADS;
static {
String enableADS = GetPropertyAction.privilegedGetProperty("jdk.io.File.enableADS");
if (enableADS != null) {
ENABLE_ADS = "".equals(enableADS) || Boolean.parseBoolean(enableADS);
} else {
ENABLE_ADS = false;
}
}
public WinNTFileSystem() {
Properties props = GetPropertyAction.privilegedGetProperties();
slash = props.getProperty("file.separator").charAt(0);
@ -305,6 +321,33 @@ class WinNTFileSystem extends FileSystem {
|| (pl == 3));
}
@Override
public boolean isInvalid(File f) {
if (f.getPath().indexOf('\u0000') >= 0)
return true;
if (ENABLE_ADS)
return false;
// Invalid if there is a ":" at a position greater than 1, or if there
// is a ":" at position 1 and the first character is not a letter
String pathname = f.getPath();
int lastColon = pathname.lastIndexOf(":");
if (lastColon > 1 ||
(lastColon == 1 && !isLetter(pathname.charAt(0))))
return true;
// Invalid if path creation fails
Path path = null;
try {
path = sun.nio.fs.DefaultFileSystemProvider.theFileSystem().getPath(pathname);
return false;
} catch (InvalidPathException ignored) {
}
return true;
}
@Override
public String resolve(File f) {
String path = f.getPath();