mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Fix script dialog path validation to handle spaces correctly
This commit is contained in:
parent
9dc9434b1b
commit
23fd2a9175
@ -105,8 +105,12 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
|
||||
if (p_string.length() == 0)
|
||||
return false;
|
||||
|
||||
String path_chars = "\"res://";
|
||||
bool is_val_path = ScriptServer::get_language(language_menu->get_selected())->can_inherit_from_file();
|
||||
if (ScriptServer::get_language(language_menu->get_selected())->can_inherit_from_file() && p_string.is_quoted()) {
|
||||
String p = p_string.substr(1, p_string.length() - 2);
|
||||
if (_validate_path(p, true) == "")
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_string.length(); i++) {
|
||||
|
||||
if (i == 0) {
|
||||
@ -114,17 +118,7 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
|
||||
return false; // no start with number plz
|
||||
}
|
||||
|
||||
if (i == p_string.length() - 1 && is_val_path)
|
||||
return p_string[i] == '\"';
|
||||
|
||||
if (is_val_path && i < path_chars.length()) {
|
||||
if (p_string[i] != path_chars[i])
|
||||
is_val_path = false;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || p_string[i] == '-' || (is_val_path && (p_string[i] == '/' || p_string[i] == '.'));
|
||||
bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || p_string[i] == '-';
|
||||
|
||||
if (!valid_char)
|
||||
return false;
|
||||
@ -133,6 +127,70 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist) {
|
||||
|
||||
String p = p_path.strip_edges();
|
||||
|
||||
if (p == "") return TTR("Path is empty.");
|
||||
if (p.get_file().get_basename() == "") return TTR("Filename is empty.");
|
||||
|
||||
p = ProjectSettings::get_singleton()->localize_path(p);
|
||||
if (!p.begins_with("res://")) return TTR("Path is not local.");
|
||||
|
||||
DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (d->change_dir(p.get_base_dir()) != OK) {
|
||||
memdelete(d);
|
||||
return TTR("Invalid base path.");
|
||||
}
|
||||
memdelete(d);
|
||||
|
||||
/* Does file already exist */
|
||||
DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (f->dir_exists(p)) {
|
||||
memdelete(f);
|
||||
return TTR("A directory with the same name exists.");
|
||||
} else if (p_file_must_exist && !f->file_exists(p)) {
|
||||
memdelete(f);
|
||||
return TTR("File does not exist.");
|
||||
}
|
||||
memdelete(f);
|
||||
|
||||
/* Check file extension */
|
||||
String extension = p.get_extension();
|
||||
List<String> extensions;
|
||||
|
||||
// get all possible extensions for script
|
||||
for (int l = 0; l < language_menu->get_item_count(); l++) {
|
||||
ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
bool match = false;
|
||||
int index = 0;
|
||||
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
|
||||
if (E->get().nocasecmp_to(extension) == 0) {
|
||||
//FIXME (?) - changing language this way doesn't update controls, needs rework
|
||||
//language_menu->select(index); // change Language option by extension
|
||||
found = true;
|
||||
if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
|
||||
match = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (!found) return TTR("Invalid extension.");
|
||||
if (!match) return TTR("Wrong extension chosen.");
|
||||
|
||||
/* Let ScriptLanguage do custom validation */
|
||||
String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
|
||||
if (path_error != "") return path_error;
|
||||
|
||||
/* All checks passed */
|
||||
return "";
|
||||
}
|
||||
|
||||
void ScriptCreateDialog::_class_name_changed(const String &p_name) {
|
||||
|
||||
if (_validate(class_name->get_text())) {
|
||||
@ -400,97 +458,22 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
|
||||
|
||||
is_path_valid = false;
|
||||
is_new_script_created = true;
|
||||
String p = p_path.strip_edges();
|
||||
|
||||
if (p == "") {
|
||||
_msg_path_valid(false, TTR("Path is empty."));
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
if (p.get_file().get_basename() == "") {
|
||||
_msg_path_valid(false, TTR("Filename is empty."));
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
p = ProjectSettings::get_singleton()->localize_path(p);
|
||||
if (!p.begins_with("res://")) {
|
||||
_msg_path_valid(false, TTR("Path is not local."));
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (d->change_dir(p.get_base_dir()) != OK) {
|
||||
_msg_path_valid(false, TTR("Invalid base path."));
|
||||
memdelete(d);
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
memdelete(d);
|
||||
|
||||
/* Does file already exist */
|
||||
|
||||
DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (f->dir_exists(p)) {
|
||||
is_new_script_created = false;
|
||||
is_path_valid = false;
|
||||
_msg_path_valid(false, TTR("A directory with the same name exists."));
|
||||
} else if (f->file_exists(p)) {
|
||||
is_new_script_created = false;
|
||||
is_path_valid = true;
|
||||
_msg_path_valid(true, TTR("File exists, it will be reused."));
|
||||
}
|
||||
memdelete(f);
|
||||
_update_dialog();
|
||||
|
||||
/* Check file extension */
|
||||
|
||||
String extension = p.get_extension();
|
||||
List<String> extensions;
|
||||
|
||||
// get all possible extensions for script
|
||||
for (int l = 0; l < language_menu->get_item_count(); l++) {
|
||||
ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
bool match = false;
|
||||
int index = 0;
|
||||
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
|
||||
if (E->get().nocasecmp_to(extension) == 0) {
|
||||
//FIXME (?) - changing language this way doesn't update controls, needs rework
|
||||
//language_menu->select(index); // change Language option by extension
|
||||
found = true;
|
||||
if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
|
||||
match = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
_msg_path_valid(false, TTR("Invalid extension."));
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
_msg_path_valid(false, TTR("Wrong extension chosen."));
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
|
||||
String path_error = _validate_path(p_path, false);
|
||||
if (path_error != "") {
|
||||
_msg_path_valid(false, path_error);
|
||||
_update_dialog();
|
||||
return;
|
||||
}
|
||||
|
||||
/* All checks passed */
|
||||
/* Does file already exist */
|
||||
DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
String p = ProjectSettings::get_singleton()->localize_path(p_path.strip_edges());
|
||||
if (f->file_exists(p)) {
|
||||
is_new_script_created = false;
|
||||
_msg_path_valid(true, TTR("File exists, it will be reused."));
|
||||
}
|
||||
memdelete(f);
|
||||
|
||||
is_path_valid = true;
|
||||
_update_dialog();
|
||||
|
@ -87,6 +87,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
|
||||
void _lang_changed(int l = 0);
|
||||
void _built_in_pressed();
|
||||
bool _validate(const String &p_string);
|
||||
String _validate_path(const String &p_path, bool p_file_must_exist);
|
||||
void _class_name_changed(const String &p_name);
|
||||
void _parent_name_changed(const String &p_parent);
|
||||
void _template_changed(int p_template = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user