Refresh data management dialogs
This commit is contained in:
parent
3a61056ce5
commit
cab313d69d
7 changed files with 720 additions and 103 deletions
|
|
@ -117,6 +117,18 @@ func resolve() -> bool:
|
|||
var expected: String = str(bootstrap.get("expected_root_id", ""))
|
||||
if selected.is_empty():
|
||||
return _fail("The data-folder pointer is incomplete.")
|
||||
if not _validate_persistent_root_path(selected):
|
||||
# A historical direct validation could leave a real bootstrap pointer
|
||||
# aimed at /tmp. Do not keep retrying an unsafe location on every
|
||||
# launch: leave its files alone, remove only the pointer, and return to
|
||||
# the normal first-run persistent-folder choice.
|
||||
_clear_bootstrap_pointer()
|
||||
requires_selection = true
|
||||
error_message = (
|
||||
"A temporary data folder was ignored. Choose a persistent folder."
|
||||
)
|
||||
status_changed.emit(error_message)
|
||||
return false
|
||||
mode = (
|
||||
Mode.APP_DATA
|
||||
if selected == ProjectSettings.globalize_path(APP_DATA_PORTABLE_PATH)
|
||||
|
|
@ -213,6 +225,8 @@ func select_new_root(path: String, app_data: bool = false) -> bool:
|
|||
var normalized: String = _normalize(path)
|
||||
if app_data:
|
||||
normalized = ProjectSettings.globalize_path(APP_DATA_PORTABLE_PATH)
|
||||
if not _validate_persistent_root_path(normalized):
|
||||
return false
|
||||
if not _validate_candidate(normalized, true):
|
||||
return false
|
||||
var manifest_path: String = _existing_manifest_path(normalized)
|
||||
|
|
@ -277,6 +291,8 @@ func use_existing_root(path: String) -> bool:
|
|||
if device_id.length() != 32:
|
||||
device_id = Crypto.new().generate_random_bytes(16).hex_encode()
|
||||
var normalized: String = _normalize(path)
|
||||
if not _validate_persistent_root_path(normalized):
|
||||
return false
|
||||
if not _activate_existing(normalized, "", true):
|
||||
return false
|
||||
if not _write_bootstrap(root_path, root_id):
|
||||
|
|
@ -370,6 +386,34 @@ func _activate_existing(path: String, expected_id: String, permit_creation: bool
|
|||
return true
|
||||
|
||||
|
||||
func _validate_persistent_root_path(path: String) -> bool:
|
||||
# Test fixtures intentionally use temporary folders, but they must only be
|
||||
# process-local. A real saved data-root pointer should never target a
|
||||
# temporary directory that the operating system can purge at any time.
|
||||
if _isolated_validation_requested():
|
||||
return true
|
||||
if _is_temporary_directory(path):
|
||||
return _fail(
|
||||
"Temporary folders cannot be used for persistent straywild data."
|
||||
)
|
||||
return true
|
||||
|
||||
|
||||
static func _is_temporary_directory(path: String) -> bool:
|
||||
var case_insensitive: bool = OS.get_name() == "Windows"
|
||||
var normalized: String = _normalize_comparison_path(
|
||||
path, case_insensitive
|
||||
)
|
||||
var temporary: String = _normalize_comparison_path(
|
||||
OS.get_temp_dir(), case_insensitive
|
||||
)
|
||||
return (
|
||||
not normalized.is_empty()
|
||||
and not temporary.is_empty()
|
||||
and (normalized == temporary or normalized.begins_with(temporary + "/"))
|
||||
)
|
||||
|
||||
|
||||
func _validate_candidate(path: String, create: bool) -> bool:
|
||||
var normalized: String = _normalize(path)
|
||||
if normalized.is_empty() or not normalized.is_absolute_path():
|
||||
|
|
@ -512,6 +556,17 @@ func _write_bootstrap(path: String, id: String) -> bool:
|
|||
)
|
||||
|
||||
|
||||
func _clear_bootstrap_pointer() -> void:
|
||||
for path: String in [
|
||||
BOOTSTRAP_PATH,
|
||||
BOOTSTRAP_PATH + ".backup",
|
||||
BOOTSTRAP_TEMP_PATH,
|
||||
]:
|
||||
var absolute: String = ProjectSettings.globalize_path(path)
|
||||
if FileAccess.file_exists(absolute):
|
||||
DirAccess.remove_absolute(absolute)
|
||||
|
||||
|
||||
func _load_bootstrap_identity() -> void:
|
||||
var data: Dictionary = _read_json(BOOTSTRAP_PATH, 64 * 1024)
|
||||
if data.is_empty():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue