6590857: Drag & Drop arbitrary file copy
Reviewed-by: uta
This commit is contained in:
parent
29e370d911
commit
8ac601577f
@ -65,10 +65,13 @@ import java.lang.reflect.Modifier;
|
||||
|
||||
import java.rmi.MarshalledObject;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -111,6 +114,8 @@ import javax.imageio.stream.ImageOutputStream;
|
||||
import sun.awt.image.ImageRepresentation;
|
||||
import sun.awt.image.ToolkitImage;
|
||||
|
||||
import java.io.FilePermission;
|
||||
|
||||
|
||||
/**
|
||||
* Provides a set of functions to be shared among the DataFlavor class and
|
||||
@ -1177,8 +1182,10 @@ search:
|
||||
(String.class.equals(flavor.getRepresentationClass()) &&
|
||||
isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
|
||||
|
||||
String str = removeSuspectedData(flavor, contents, (String)obj);
|
||||
|
||||
return translateTransferableString(
|
||||
(String)obj,
|
||||
str,
|
||||
format);
|
||||
|
||||
// Source data is a Reader. Convert to a String and recur. In the
|
||||
@ -1286,6 +1293,11 @@ search:
|
||||
throw new IOException("data translation failed");
|
||||
}
|
||||
final List list = (List)obj;
|
||||
|
||||
final ArrayList fileList = new ArrayList();
|
||||
|
||||
final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
|
||||
|
||||
int nFiles = 0;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Object o = list.get(i);
|
||||
@ -1293,17 +1305,18 @@ search:
|
||||
nFiles++;
|
||||
}
|
||||
}
|
||||
final String[] files = new String[nFiles];
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws IOException {
|
||||
for (int i = 0, j = 0; i < list.size(); i++) {
|
||||
Object o = list.get(i);
|
||||
if (o instanceof File) {
|
||||
files[j++] = ((File)o).getCanonicalPath();
|
||||
} else if (o instanceof String) {
|
||||
files[j++] = (String)o;
|
||||
for (Object fileObject : list)
|
||||
{
|
||||
File file = castToFile(fileObject);
|
||||
if (null == System.getSecurityManager() ||
|
||||
!(isFileInWebstartedCache(file) ||
|
||||
isForbiddenToRead(file, userProtectionDomain)))
|
||||
{
|
||||
fileList.add(file.getCanonicalPath());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -1313,10 +1326,11 @@ search:
|
||||
throw new IOException(pae.getMessage());
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
byte[] bytes = files[i].getBytes();
|
||||
if (i != 0) bos.write(0);
|
||||
bos.write(bytes, 0, bytes.length);
|
||||
for (int i = 0; i < fileList.size(); i++)
|
||||
{
|
||||
byte[] bytes = ((String)fileList.get(i)).getBytes();
|
||||
if (i != 0) bos.write(0);
|
||||
bos.write(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
// Source data is an InputStream. For arbitrary flavors, just grab the
|
||||
@ -1366,6 +1380,123 @@ search:
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str)
|
||||
throws IOException
|
||||
{
|
||||
if (null == System.getSecurityManager()
|
||||
|| !flavor.isMimeTypeEqual("text/uri-list"))
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
String ret_val = "";
|
||||
final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
|
||||
|
||||
try {
|
||||
ret_val = (String) AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() {
|
||||
|
||||
StringBuffer allowedFiles = new StringBuffer(str.length());
|
||||
String [] uriArray = str.split("(\\s)+");
|
||||
|
||||
for (String fileName : uriArray)
|
||||
{
|
||||
File file = new File(fileName);
|
||||
if (file.exists() &&
|
||||
!(isFileInWebstartedCache(file) ||
|
||||
isForbiddenToRead(file, userProtectionDomain)))
|
||||
{
|
||||
|
||||
if (0 != allowedFiles.length())
|
||||
{
|
||||
allowedFiles.append("\\r\\n");
|
||||
}
|
||||
|
||||
allowedFiles.append(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
return allowedFiles.toString();
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw new IOException(pae.getMessage(), pae);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
private static ProtectionDomain getUserProtectionDomain(Transferable contents) {
|
||||
return contents.getClass().getProtectionDomain();
|
||||
}
|
||||
|
||||
private boolean isForbiddenToRead (File file, ProtectionDomain protectionDomain)
|
||||
{
|
||||
if (null == protectionDomain) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
FilePermission filePermission =
|
||||
new FilePermission(file.getCanonicalPath(), "read, delete");
|
||||
if (protectionDomain.implies(filePermission)) {
|
||||
return false;
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// It is important do not use user's successors
|
||||
// of File class.
|
||||
private File castToFile(Object fileObject) throws IOException {
|
||||
String filePath = null;
|
||||
if (fileObject instanceof File) {
|
||||
filePath = ((File)fileObject).getCanonicalPath();
|
||||
} else if (fileObject instanceof String) {
|
||||
filePath = (String) fileObject;
|
||||
}
|
||||
return new File(filePath);
|
||||
}
|
||||
|
||||
private final static String[] DEPLOYMENT_CACHE_PROPERTIES = {
|
||||
"deployment.system.cachedir",
|
||||
"deployment.user.cachedir",
|
||||
"deployment.javaws.cachedir",
|
||||
"deployment.javapi.cachedir"
|
||||
};
|
||||
|
||||
private final static ArrayList <File> deploymentCacheDirectoryList =
|
||||
new ArrayList<File>();
|
||||
|
||||
private static boolean isFileInWebstartedCache(File f) {
|
||||
|
||||
if (deploymentCacheDirectoryList.isEmpty()) {
|
||||
for (String cacheDirectoryProperty : DEPLOYMENT_CACHE_PROPERTIES) {
|
||||
String cacheDirectoryPath = System.getProperty(cacheDirectoryProperty);
|
||||
if (cacheDirectoryPath != null) {
|
||||
try {
|
||||
File cacheDirectory = (new File(cacheDirectoryPath)).getCanonicalFile();
|
||||
if (cacheDirectory != null) {
|
||||
deploymentCacheDirectoryList.add(cacheDirectory);
|
||||
}
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (File deploymentCacheDirectory : deploymentCacheDirectoryList) {
|
||||
for (File dir = f; dir != null; dir = dir.getParentFile()) {
|
||||
if (dir.equals(deploymentCacheDirectory)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public Object translateBytes(byte[] bytes, DataFlavor flavor,
|
||||
long format, Transferable localeTransferable)
|
||||
throws IOException
|
||||
|
Loading…
Reference in New Issue
Block a user