Check if given game version is malformed

This commit is contained in:
huanghongxun 2019-09-05 17:49:59 +08:00
parent ce3b9e3b1f
commit df39be708f
7 changed files with 72 additions and 1 deletions

View File

@ -30,8 +30,11 @@ import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.construct.Validator;
import org.jackhuang.hmcl.ui.wizard.WizardController;
import org.jackhuang.hmcl.ui.wizard.WizardPage;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import java.nio.file.Paths;
import java.util.Map;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@ -83,7 +86,9 @@ public class InstallersPage extends StackPane implements WizardPage {
String gameVersion = ((RemoteVersion) controller.getSettings().get("game")).getGameVersion();
Validator hasVersion = new Validator(s -> !repository.hasVersion(s) && StringUtils.isNotBlank(s));
hasVersion.setMessage(i18n("install.new_game.already_exists"));
txtName.getValidators().add(hasVersion);
Validator nameValidator = new Validator(OperatingSystem::isNameValid);
nameValidator.setMessage(i18n("install.new_game.malformed"));
txtName.getValidators().addAll(hasVersion, nameValidator);
txtName.textProperty().addListener(e -> btnInstall.setDisable(!txtName.validate()));
txtName.setText(gameVersion);

View File

@ -152,6 +152,7 @@ install.modpack=Install a modpack
install.new_game=Install a New Game
install.new_game.already_exists=This version has already been existing.
install.new_game.current_game_version=Current Game Version
install.new_game.malformed=Name malformed
install.select=Select an operation
install.success=Installed successfully

View File

@ -150,6 +150,7 @@ install.modpack=安裝整合包
install.new_game=安裝新遊戲版本
install.new_game.already_exists=此版本已經存在,請換一個名字
install.new_game.current_game_version=目前遊戲版本
install.new_game.malformed=名字不合法
install.select=請選擇安裝方式
install.success=安裝成功

View File

@ -151,6 +151,7 @@ install.modpack=安装整合包
install.new_game=安装新游戏版本
install.new_game.already_exists=此版本已经存在,请换一个名字
install.new_game.current_game_version=当前游戏版本
install.new_game.malformed=名字不合法
install.select=请选择安装方式
install.success=安装成功

View File

@ -316,6 +316,9 @@ public class FileDownloadTask extends Task<Void> {
if (temp != null)
temp.toFile().delete();
exception = e;
if (e instanceof ResponseCodeException && ((ResponseCodeException) e).getResponseCode() == 404)
break;
} finally {
closeFiles();
}

View File

@ -179,6 +179,8 @@ public final class CompressingUtils {
throw new ZipException(error.getMessage());
} catch (UnsupportedOperationException ex) {
throw new IOException("Not a zip file", ex);
} catch (FileSystemNotFoundException ex) {
throw new IOException("Java Environment is broken");
}
}

View File

@ -28,8 +28,10 @@ import java.lang.management.ManagementFactory;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Locale;
import java.util.Optional;
import java.util.regex.Pattern;
/**
* Represents the operating system.
@ -98,6 +100,10 @@ public enum OperatingSystem {
*/
public static final String SYSTEM_ARCHITECTURE;
public static final Pattern INVALID_RESOURCE_CHARACTERS;
private static final String[] INVALID_RESOURCE_BASENAMES;
private static final String[] INVALID_RESOURCE_FULLNAMES;
static {
String name = System.getProperty("os.name").toLowerCase(Locale.US);
if (name.contains("win"))
@ -119,6 +125,24 @@ public enum OperatingSystem {
if (arch == null)
arch = System.getProperty("os.arch");
SYSTEM_ARCHITECTURE = arch;
// setup the invalid names
if (CURRENT_OS == WINDOWS) {
// valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp
INVALID_RESOURCE_CHARACTERS = Pattern.compile("[/\"<>|?*:\\\\]");
INVALID_RESOURCE_BASENAMES = new String[]{"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
"com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
"lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
Arrays.sort(INVALID_RESOURCE_BASENAMES);
//CLOCK$ may be used if an extension is provided
INVALID_RESOURCE_FULLNAMES = new String[]{"clock$"}; //$NON-NLS-1$
} else {
//only front slash and null char are invalid on UNIXes
//taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html
INVALID_RESOURCE_CHARACTERS = null;
INVALID_RESOURCE_BASENAMES = null;
INVALID_RESOURCE_FULLNAMES = null;
}
}
private static Optional<Long> getTotalPhysicalMemorySize() {
@ -154,4 +178,38 @@ public enum OperatingSystem {
return Paths.get(home, folder);
}
}
/**
* Returns true if the given name is a valid resource name on this operating system,
* and false otherwise.
*/
public static boolean isNameValid(String name) {
//. and .. have special meaning on all platforms
if (name.equals(".") || name.equals("..") || name.indexOf('/') == 0 || name.indexOf('\0') >= 0) //$NON-NLS-1$ //$NON-NLS-2$
return false;
if (CURRENT_OS == WINDOWS) {
//empty names are not valid
final int length = name.length();
if (length == 0)
return false;
final char lastChar = name.charAt(length - 1);
// filenames ending in dot are not valid
if (lastChar == '.')
return false;
// file names ending with whitespace are truncated (bug 118997)
if (Character.isWhitespace(lastChar))
return false;
int dot = name.indexOf('.');
// on windows, filename suffixes are not relevant to name validity
String basename = dot == -1 ? name : name.substring(0, dot);
if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase()) >= 0)
return false;
if (Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase()) >= 0)
return false;
if (INVALID_RESOURCE_CHARACTERS != null && INVALID_RESOURCE_CHARACTERS.matcher(name).find())
return false;
}
return true;
}
}