Check filename is not invalid for windows platform

This commit is contained in:
Adrien Ufferte
2025-10-24 12:02:39 +02:00
parent fff6ec906d
commit d9389c2b53
3 changed files with 86 additions and 30 deletions
+28 -13
View File
@@ -14,9 +14,10 @@ func extract(zip_path: String, extract_path: String, extract_in_subfolder: bool
Log.trace("FolderUnzipper: Extracting %s to %s" % [zip_path, extract_path])
var err: Error = open(zip_path)
if err != OK:
Log.error("FolderUnzipper: Error " + error_string(err) + " while opening file: %s" % zip_path)
Log.error("FolderUnzipper: Error %s while opening %s" % [error_string(err), zip_path])
close()
return ""
var extract_folder: String = extract_path.path_join(zip_path.get_file().get_basename()) if extract_in_subfolder else extract_path
var all_files: PackedStringArray = get_files()
@@ -26,32 +27,46 @@ func extract(zip_path: String, extract_path: String, extract_in_subfolder: bool
var copied_file: int = 0
var first_folder: String = ""
var last_sub_path: String = ""
for sub_path: String in all_files:
last_sub_path = sub_path
if _is_directory_path(sub_path):
first_folder = sub_path.trim_suffix("/")
break
if not first_folder and last_sub_path != "":
first_folder = last_sub_path.split("/")[0]
for sub_path: String in all_files:
var file_name: String = extract_folder.path_join(sub_path)
var folder_name: String = file_name.get_base_dir()
if not DirAccess.dir_exists_absolute(folder_name):
DirAccess.make_dir_recursive_absolute(folder_name)
if _is_directory_path(sub_path):
continue
var file_name: String = extract_folder.path_join(sub_path)
file_name = Utils.get_safe_file_path(file_name)
var folder_name: String = file_name.get_base_dir()
if not DirAccess.dir_exists_absolute(folder_name):
var mkdir_err: Error = DirAccess.make_dir_recursive_absolute(folder_name)
if mkdir_err != OK:
Log.error("FolderUnzipper: Cannot create directory %s. Error: %s" % [folder_name, error_string(mkdir_err)])
continue
var file: FileAccess = FileAccess.open(file_name, FileAccess.WRITE)
var error: Error = FileAccess.get_open_error()
if error != OK:
if error != OK or file == null:
Log.error("FolderUnzipper: Extract: Cannot open file %s. Error: %s" % [file_name, error_string(error)])
close()
return ""
if file == null:
Log.error("FolderUnzipper: Extract: Cannot open file %s. File is null" % file_name)
close()
return ""
file.store_buffer(read_file(sub_path))
continue
var data: PackedByteArray = read_file(sub_path)
if typeof(data) != TYPE_PACKED_BYTE_ARRAY or data.is_empty():
Log.warn("FolderUnzipper: Empty or invalid data for %s" % sub_path)
file.close()
continue
file.store_buffer(data)
file.close()
Log.trace("FolderUnzipper: Copied %s" % file_name)
copied_file += 1
file_copied.emit(copied_file, file_name)
+28 -17
View File
@@ -596,35 +596,46 @@ func get_kalulu_speech_path(speech_category: String, speech_name: String) -> Str
func load_external_sound(path: String) -> AudioStreamMP3:
Log.trace("Database: Load External Sound: %s" % path)
path = Utils.get_safe_file_path(path)
if not FileAccess.file_exists(path):
path = UnicodeNormalizer.to_nfd_basic(path)
Log.trace("Database: Load External Sound: file not found: trying to normalize path to unicode NFD: %s" % path)
Log.trace("Database: Load External Sound: File not found, retrying with Unicode NFD: %s" % path)
if not FileAccess.file_exists(path):
path = UnicodeNormalizer.to_nfd_extended(path)
Log.trace("Database: Load External Sound: file not found: trying to normalize path to unicode NFD extended: %s" % path)
Log.trace("Database: Load External Sound: File not found, retrying with Unicode NFD extended: %s" % path)
if not FileAccess.file_exists(path):
Log.error("Database: Load External Sound: file not found even after unicode normalization")
Log.error("Database: Load External Sound: File not found after normalization attempts")
return null
Log.trace("Database: Load External Sound: file found.")
Log.trace("Database: Load External Sound: Opening file.")
var file: FileAccess = FileAccess.open(path, FileAccess.READ)
var error: Error = FileAccess.get_open_error()
if error != OK:
if error != OK or file == null:
Log.error("Database: Load External Sound: Cannot open file %s. Error: %s" % [path, error_string(error)])
return null
if file == null:
Log.error("Database: Load External Sound: Cannot open file %s. File is null")
return null
var file_length: int = file.get_length()
Log.trace("Database: Load External Sound: File length = %d" % file_length)
Log.trace("Database: Load External Sound: Creating audio stream")
var audio_stream: AudioStreamMP3 = AudioStreamMP3.new()
audio_stream.data = file.get_buffer(file_length)
if file_length <= 0:
Log.error("Database: Load External Sound: Invalid file length for %s" % path)
file.close()
return null
var data: PackedByteArray = file.get_buffer(file_length)
file.close()
if not audio_stream:
Log.error("Database: Load External Sound: Audio stream is not valid")
elif audio_stream == null:
Log.error("Database: Load External Sound: Audio stream is null")
if data.is_empty():
Log.error("Database: Load External Sound: Empty buffer read for %s" % path)
return null
var audio_stream: AudioStreamMP3 = AudioStreamMP3.new()
audio_stream.data = data
if not audio_stream or audio_stream == null:
Log.error("Database: Load External Sound: Failed to create AudioStreamMP3 for %s" % path)
return null
Log.trace("Database: Load External Sound: Loaded %s successfully (%d bytes)" % [path, file_length])
return audio_stream
+30
View File
@@ -61,3 +61,33 @@ func compare_versions(version_a: String, version_b: String) -> int:
elif ai > bi:
return 1
return 0
func get_safe_file_path(file_path: String) -> String:
var dir: String = file_path.get_base_dir()
var file: String = file_path.get_file()
var base: String = file.get_basename()
var ext: String = file.get_extension()
var reserved_names: Array[String] = [
"CON", "PRN", "AUX", "NUL",
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"
]
var invalid_chars: Array[String] = ["/", "\\", ":", "*", "?", "\"", "<", ">", "|"]
for chara: String in invalid_chars:
base = base.replace(chara, "_")
var modified: bool = false
if base.to_upper() in reserved_names:
base = "_" + base
modified = true
var new_name: String = "%s.%s" % [base, ext] if ext != "" else base
var new_path: String = dir.path_join(new_name) if dir != "" else new_name
if modified or new_path != file_path:
Log.trace("Utils: GetSafeFilePath: Renamed invalid file path: '%s' → '%s'" % [file_path, new_path])
return new_path