mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 06:46:00 +00:00
Replace illegal fs chars in filenames
This commit is contained in:
@@ -25,6 +25,7 @@ from logger.logger import log
|
||||
from starlette.requests import ClientDisconnect
|
||||
from streaming_form_data import StreamingFormDataParser
|
||||
from streaming_form_data.targets import FileTarget, NullTarget
|
||||
from utils.filesystem import sanitize_filename
|
||||
from utils.hashing import crc32_to_hex
|
||||
from utils.nginx import ZipContentLine, ZipResponse
|
||||
from utils.router import APIRouter
|
||||
@@ -337,19 +338,25 @@ async def update_rom(
|
||||
}
|
||||
)
|
||||
|
||||
fs_safe_file_name = data.get("file_name", rom.file_name).strip().replace("/", "-")
|
||||
fs_safe_name = cleaned_data["name"].strip().replace("/", "-")
|
||||
|
||||
if rename_as_source:
|
||||
fs_safe_file_name = rom.file_name.replace(
|
||||
rom.file_name_no_tags or rom.file_name_no_ext, fs_safe_name
|
||||
)
|
||||
new_file_name = data.get("file_name", rom.file_name)
|
||||
|
||||
try:
|
||||
if rom.file_name != fs_safe_file_name:
|
||||
if rename_as_source:
|
||||
new_file_name = rom.file_name.replace(
|
||||
rom.file_name_no_tags or rom.file_name_no_ext,
|
||||
data.get("name", rom.name),
|
||||
)
|
||||
new_file_name = sanitize_filename(new_file_name)
|
||||
fs_rom_handler.rename_file(
|
||||
old_name=rom.file_name,
|
||||
new_name=fs_safe_file_name,
|
||||
new_name=new_file_name,
|
||||
file_path=rom.file_path,
|
||||
)
|
||||
elif rom.file_name != new_file_name:
|
||||
new_file_name = sanitize_filename(new_file_name)
|
||||
fs_rom_handler.rename_file(
|
||||
old_name=rom.file_name,
|
||||
new_name=new_file_name,
|
||||
file_path=rom.file_path,
|
||||
)
|
||||
except RomAlreadyExistsException as exc:
|
||||
@@ -360,12 +367,12 @@ async def update_rom(
|
||||
|
||||
cleaned_data.update(
|
||||
{
|
||||
"file_name": fs_safe_file_name,
|
||||
"file_name": new_file_name,
|
||||
"file_name_no_tags": fs_rom_handler.get_file_name_with_no_tags(
|
||||
fs_safe_file_name
|
||||
new_file_name
|
||||
),
|
||||
"file_name_no_ext": fs_rom_handler.get_file_name_with_no_extension(
|
||||
fs_safe_file_name
|
||||
new_file_name
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import re
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
|
||||
@@ -27,3 +28,35 @@ def iter_directories(path: str, recursive: bool = False) -> Iterator[tuple[Path,
|
||||
yield Path(root), directory
|
||||
if not recursive:
|
||||
break
|
||||
|
||||
|
||||
INVALID_CHARS = r'[\\/:*?"<>|]'
|
||||
|
||||
|
||||
def sanitize_filename(filename):
|
||||
"""
|
||||
Replace invalid characters in the filename to make it valid across common filesystems
|
||||
|
||||
Args:
|
||||
- filename (str): The filename to sanitize.
|
||||
|
||||
Returns:
|
||||
- str: The sanitized filename.
|
||||
"""
|
||||
# Replace some invalid characters with hyphen
|
||||
sanitized_filename = re.sub(r"[\\/:|]", "-", filename)
|
||||
|
||||
# Remove other invalid characters
|
||||
sanitized_filename = re.sub(r'[*?"<>]', "", sanitized_filename)
|
||||
|
||||
# Ensure null bytes are not included (ZFS allows any characters except null bytes)
|
||||
sanitized_filename = sanitized_filename.replace("\0", "")
|
||||
|
||||
# Remove leading/trailing whitespace
|
||||
sanitized_filename = sanitized_filename.strip()
|
||||
|
||||
# Ensure the filename is not empty
|
||||
if not sanitized_filename:
|
||||
raise ValueError("Filename cannot be empty after sanitization")
|
||||
|
||||
return sanitized_filename
|
||||
|
||||
@@ -20,10 +20,6 @@ const rom = ref<UpdateRom>();
|
||||
const romsStore = storeRoms();
|
||||
const imagePreviewUrl = ref<string | undefined>("");
|
||||
const removeCover = ref(false);
|
||||
const fileNameInputRules = {
|
||||
required: (value: string) => !!value || "Required",
|
||||
newFileName: (value: string) => !value.includes("/") || "Invalid characters",
|
||||
};
|
||||
const emitter = inject<Emitter<Events>>("emitter");
|
||||
emitter?.on("showEditRomDialog", (romToEdit: UpdateRom | undefined) => {
|
||||
show.value = true;
|
||||
@@ -62,16 +58,9 @@ async function removeArtwork() {
|
||||
async function updateRom() {
|
||||
if (!rom.value) return;
|
||||
|
||||
if (rom.value.file_name.includes("/")) {
|
||||
if (!rom.value.file_name) {
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: "Couldn't edit rom: invalid file name characters",
|
||||
icon: "mdi-close-circle",
|
||||
color: "red",
|
||||
});
|
||||
return;
|
||||
} else if (!rom.value.file_name) {
|
||||
emitter?.emit("snackbarShow", {
|
||||
msg: "Couldn't edit rom: file name required",
|
||||
msg: "Cannot save: file name is required",
|
||||
icon: "mdi-close-circle",
|
||||
color: "red",
|
||||
});
|
||||
@@ -145,8 +134,7 @@ function closeDialog() {
|
||||
v-model="rom.file_name"
|
||||
class="py-2"
|
||||
:rules="[
|
||||
fileNameInputRules.newFileName,
|
||||
fileNameInputRules.required,
|
||||
(value: string) => !!value
|
||||
]"
|
||||
label="File name"
|
||||
variant="outlined"
|
||||
@@ -177,7 +165,9 @@ function closeDialog() {
|
||||
<template #append-inner-right>
|
||||
<v-btn-group rounded="0" divided density="compact">
|
||||
<v-btn
|
||||
:disabled="!heartbeat.value.METADATA_SOURCES?.STEAMGRIDDB_ENABLED"
|
||||
:disabled="
|
||||
!heartbeat.value.METADATA_SOURCES?.STEAMGRIDDB_ENABLED
|
||||
"
|
||||
size="small"
|
||||
class="translucent-dark"
|
||||
@click="
|
||||
|
||||
Reference in New Issue
Block a user