Check filename is not invalid for windows platform
This commit is contained in:
+28
-13
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user