geforkt von Mirrors/FastAsyncWorldEdit
Unified file selection and checking API.
Dieser Commit ist enthalten in:
Ursprung
2bc75dd5db
Commit
d5173a8763
32
src/com/sk89q/worldedit/FileSelectionAbortedException.java
Normale Datei
32
src/com/sk89q/worldedit/FileSelectionAbortedException.java
Normale Datei
@ -0,0 +1,32 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
public class FileSelectionAbortedException extends FilenameException {
|
||||
private static final long serialVersionUID = 7377072269988014886L;
|
||||
|
||||
public FileSelectionAbortedException() {
|
||||
super("");
|
||||
}
|
||||
|
||||
public FileSelectionAbortedException(String msg) {
|
||||
super("", msg);
|
||||
}
|
||||
}
|
40
src/com/sk89q/worldedit/FilenameException.java
Normale Datei
40
src/com/sk89q/worldedit/FilenameException.java
Normale Datei
@ -0,0 +1,40 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
public class FilenameException extends WorldEditException {
|
||||
private static final long serialVersionUID = 6072601657326106265L;
|
||||
|
||||
private String filename;
|
||||
|
||||
public FilenameException(String filename) {
|
||||
super();
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public FilenameException(String filename, String msg) {
|
||||
super(msg);
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
}
|
32
src/com/sk89q/worldedit/FilenameNotFoundException.java
Normale Datei
32
src/com/sk89q/worldedit/FilenameNotFoundException.java
Normale Datei
@ -0,0 +1,32 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
public class FilenameNotFoundException extends FilenameException {
|
||||
private static final long serialVersionUID = 4673670296313383121L;
|
||||
|
||||
public FilenameNotFoundException(String filename) {
|
||||
super(filename);
|
||||
}
|
||||
|
||||
public FilenameNotFoundException(String filename, String msg) {
|
||||
super(filename, msg);
|
||||
}
|
||||
}
|
32
src/com/sk89q/worldedit/InvalidFilenameException.java
Normale Datei
32
src/com/sk89q/worldedit/InvalidFilenameException.java
Normale Datei
@ -0,0 +1,32 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldEdit
|
||||
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
public class InvalidFilenameException extends FilenameException {
|
||||
private static final long serialVersionUID = 7377072269988014886L;
|
||||
|
||||
public InvalidFilenameException(String filename) {
|
||||
super(filename);
|
||||
}
|
||||
|
||||
public InvalidFilenameException(String filename, String msg) {
|
||||
super(filename, msg);
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
import java.io.File;
|
||||
import com.sk89q.worldedit.bags.BlockBag;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.util.TargetBlock;
|
||||
@ -536,6 +537,17 @@ public abstract class LocalPlayer {
|
||||
*/
|
||||
public abstract boolean hasPermission(String perm);
|
||||
|
||||
/**
|
||||
* Open a file open dialog.
|
||||
*
|
||||
* @param extensions null to allow all
|
||||
* @return
|
||||
*/
|
||||
public File openFileDialog(String[] extensions) {
|
||||
printError("File dialogs are not supported in your environment.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the player can destroy bedrock.
|
||||
*
|
||||
|
@ -345,6 +345,56 @@ public class WorldEdit {
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to a file. This method will check to see if the filename
|
||||
* has valid characters and has an extension. It also prevents directory
|
||||
* traversal exploits by checking the root directory and the file directory.
|
||||
* On success, a <code>java.io.File</code> object will be returned.
|
||||
*
|
||||
* @param dir sub-directory to look in
|
||||
* @param filename filename (user-submitted)
|
||||
* @param defaultExt append an extension if missing one, null to not use
|
||||
* @return
|
||||
* @throws FilenameException
|
||||
*/
|
||||
public File getSafeFile(LocalPlayer player, File dir, String filename,
|
||||
String defaultExt) throws FilenameException {
|
||||
File f;
|
||||
|
||||
if (filename.equals("#")) {
|
||||
f = player.openFileDialog(null);
|
||||
if (f == null) {
|
||||
throw new FileSelectionAbortedException("No file selected");
|
||||
}
|
||||
} else {
|
||||
if (defaultExt != null && filename.lastIndexOf('.') == -1) {
|
||||
filename += "." + defaultExt;
|
||||
}
|
||||
|
||||
if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+\\.[A-Za-z0-9]+$")) {
|
||||
throw new InvalidFilenameException(filename,
|
||||
"Invalid characters or extension missing");
|
||||
}
|
||||
|
||||
f = new File(dir, filename);
|
||||
}
|
||||
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
String dirPath = dir.getCanonicalPath();
|
||||
|
||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
||||
throw new FilenameNotFoundException(filename,
|
||||
"Path is outside allowable root");
|
||||
}
|
||||
|
||||
return f;
|
||||
} catch (IOException e) {
|
||||
throw new FilenameNotFoundException(filename,
|
||||
"Failed to resolve path");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the specified radius is within bounds.
|
||||
@ -774,6 +824,14 @@ public class WorldEdit {
|
||||
player.printError(e.getMessage());
|
||||
} catch (EmptyClipboardException e) {
|
||||
player.printError("Your clipboard is empty. Use //copy first.");
|
||||
} catch (InvalidFilenameException e) {
|
||||
player.printError("Filename '" + e.getFilename() + "' invalid: "
|
||||
+ e.getMessage());
|
||||
} catch (FilenameNotFoundException e) {
|
||||
player.printError("File '" + e.getFilename() + "' not found: "
|
||||
+ e.getMessage());
|
||||
} catch (FileSelectionAbortedException e) {
|
||||
player.printError("File selection aborted.");
|
||||
} catch (WorldEditException e) {
|
||||
player.printError(e.getMessage());
|
||||
} catch (Throwable excp) {
|
||||
@ -793,16 +851,9 @@ public class WorldEdit {
|
||||
* @param args
|
||||
* @throws WorldEditException
|
||||
*/
|
||||
public void runScript(LocalPlayer player, String filename, String[] args)
|
||||
public void runScript(LocalPlayer player, File f, String[] args)
|
||||
throws WorldEditException {
|
||||
File dir = getWorkingDirectoryFile(config.scriptsDir);
|
||||
File f = new File(dir, filename);
|
||||
|
||||
if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+\\.[A-Za-z0-9]+$")) {
|
||||
player.printError("Invalid filename. Don't forget the extension.");
|
||||
return;
|
||||
}
|
||||
|
||||
String filename = f.getPath();
|
||||
int index = filename.lastIndexOf(".");
|
||||
String ext = filename.substring(index + 1, filename.length());
|
||||
|
||||
@ -810,19 +861,6 @@ public class WorldEdit {
|
||||
player.printError("Only .js scripts are currently supported");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
String dirPath = dir.getCanonicalPath();
|
||||
|
||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
||||
player.printError("Script could not read or it does not exist.");
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
player.printError("Script could not read or it does not exist: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
String script;
|
||||
|
||||
|
@ -179,15 +179,9 @@ public class ClipboardCommands {
|
||||
|
||||
LocalConfiguration config = we.getConfiguration();
|
||||
|
||||
String filename = args.getString(0).replace("\0", "") + ".schematic";
|
||||
String filename = args.getString(0);
|
||||
File dir = we.getWorkingDirectoryFile(config.saveDir);
|
||||
File f = new File(dir, filename);
|
||||
|
||||
if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) {
|
||||
player.printError("Valid characters: A-Z, a-z, 0-9, spaces, "
|
||||
+ "./\'$@~!%^*()[]+{},?");
|
||||
return;
|
||||
}
|
||||
File f = we.getSafeFile(player, dir, filename, "schematic");
|
||||
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
@ -221,41 +215,28 @@ public class ClipboardCommands {
|
||||
|
||||
LocalConfiguration config = we.getConfiguration();
|
||||
|
||||
String filename = args.getString(0).replace("\0", "") + ".schematic";
|
||||
String filename = args.getString(0);
|
||||
|
||||
if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) {
|
||||
player.printError("Valid characters: A-Z, a-z, 0-9, spaces, "
|
||||
+ "./\'$@~!%^*()[]+{},?");
|
||||
return;
|
||||
}
|
||||
|
||||
File dir = we.getWorkingDirectoryFile(config.saveDir);
|
||||
File f = new File(dir, filename);
|
||||
File f = we.getSafeFile(player, dir, filename, "schematic");
|
||||
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkdir()) {
|
||||
player.printError("A schematics/ folder could not be created.");
|
||||
player.printError("The storage folder could not be created.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
String dirPath = dir.getCanonicalPath();
|
||||
|
||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
||||
player.printError("Invalid path for Schematic.");
|
||||
} else {
|
||||
// Create parent directories
|
||||
File parent = f.getParentFile();
|
||||
if (parent != null && !parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
session.getClipboard().saveSchematic(f);
|
||||
WorldEdit.logger.info(player.getName() + " saved " + filePath);
|
||||
player.print(filename + " saved.");
|
||||
// Create parent directories
|
||||
File parent = f.getParentFile();
|
||||
if (parent != null && !parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
session.getClipboard().saveSchematic(f);
|
||||
WorldEdit.logger.info(player.getName() + " saved " + f.getCanonicalPath());
|
||||
player.print(filename + " saved.");
|
||||
} catch (DataException se) {
|
||||
player.printError("Save error: " + se.getMessage());
|
||||
} catch (IOException e) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.commands;
|
||||
|
||||
import java.io.File;
|
||||
import com.sk89q.util.commands.Command;
|
||||
import com.sk89q.util.commands.CommandContext;
|
||||
import com.sk89q.worldedit.*;
|
||||
@ -45,8 +46,11 @@ public class ScriptingCommands {
|
||||
String[] scriptArgs = args.getSlice(1);
|
||||
|
||||
session.setLastScript(args.getString(0));
|
||||
|
||||
File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir);
|
||||
File f = we.getSafeFile(player, dir, args.getString(0), "js");
|
||||
|
||||
we.runScript(player, args.getString(0), scriptArgs);
|
||||
we.runScript(player, f, scriptArgs);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -70,8 +74,11 @@ public class ScriptingCommands {
|
||||
}
|
||||
|
||||
String[] scriptArgs = args.getSlice(0);
|
||||
|
||||
File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir);
|
||||
File f = we.getSafeFile(player, dir, lastScript, "js");
|
||||
|
||||
we.runScript(player, lastScript, scriptArgs);
|
||||
we.runScript(player, f, scriptArgs);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -20,13 +20,13 @@
|
||||
package com.sk89q.worldedit.scripting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import com.sk89q.worldedit.DisallowedItemException;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.FilenameException;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -200,37 +200,32 @@ public class CraftScriptContext extends CraftScriptEnvironment {
|
||||
* Gets the path to a file. This method will check to see if the filename
|
||||
* has valid characters and has an extension. It also prevents directory
|
||||
* traversal exploits by checking the root directory and the file directory.
|
||||
* On success, a <code>java.io.File</code> object will be returned,
|
||||
* otherwise a null will be returned and the player will be informed.
|
||||
* On success, a <code>java.io.File</code> object will be returned.
|
||||
*
|
||||
* <p>Use this method if you need to read a file from a directory.</p>
|
||||
*
|
||||
* @param folder subdirectory to look in
|
||||
* @param folder sub-directory to look in
|
||||
* @param filename filename (user-submitted)
|
||||
* @return
|
||||
* @throws FilenameException
|
||||
*/
|
||||
public File getSafeFile(String folder, String filename) {
|
||||
File dir = new File(folder);
|
||||
File f = new File(dir, filename);
|
||||
|
||||
if (!filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+\\.[A-Za-z0-9]+$")) {
|
||||
player.printError("Invalid filename specified.");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String filePath = f.getCanonicalPath();
|
||||
String dirPath = dir.getCanonicalPath();
|
||||
|
||||
if (!filePath.substring(0, dirPath.length()).equals(dirPath)) {
|
||||
player.printError("File could not read or it does not exist.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return f;
|
||||
} catch (IOException e) {
|
||||
player.printError("File could not read or it does not exist: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
public File getSafeFile(String folder, String filename) throws FilenameException {
|
||||
File dir = controller.getWorkingDirectoryFile(folder);
|
||||
return controller.getSafeFile(player, dir, filename, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This version will append an extension if one doesn't exist.
|
||||
*
|
||||
* @param folder sub-directory to look in
|
||||
* @param filename filename (user-submitted)
|
||||
* @param defaultExt default extension to append if there is none
|
||||
* @return
|
||||
* @throws FilenameException
|
||||
*/
|
||||
public File getSafeFile(String folder, String filename, String defaultExt)
|
||||
throws FilenameException {
|
||||
File dir = controller.getWorkingDirectoryFile(folder);
|
||||
return controller.getSafeFile(player, dir, filename, defaultExt);
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren