From 484df3b9fd1db5ad733b338e2043cb3015222a90 Mon Sep 17 00:00:00 2001 From: Vitali Graf Date: Fri, 10 Apr 2026 21:02:36 +0200 Subject: [PATCH] fix: escape special characters in save_config TOML output --- tests/test_config.py | 8 ++++++++ whisper_local/config.py | 15 ++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index f42e1db..e0fbb2b 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -105,3 +105,11 @@ class TestSaveConfig: path = tmp_path / "subdir" / "config.toml" save_config(Config(), path) assert path.exists() + + def test_save_handles_special_characters_in_microphone(self, tmp_path): + from whisper_local.config import save_config + path = tmp_path / "config.toml" + config = Config(microphone='USB "Pro" Mic') + save_config(config, path) + loaded = load_config(path) + assert loaded.microphone == 'USB "Pro" Mic' diff --git a/whisper_local/config.py b/whisper_local/config.py index 948e5a5..9c81b23 100644 --- a/whisper_local/config.py +++ b/whisper_local/config.py @@ -63,17 +63,22 @@ def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config: return config +def _toml_str(value: str) -> str: + """Escaped einen String-Wert für TOML (verhindert ungültiges TOML bei Sonderzeichen).""" + return value.replace("\\", "\\\\").replace('"', '\\"') + + def save_config(config: Config, path: Path = DEFAULT_CONFIG_PATH) -> None: """Schreibt Config als TOML-Datei. Erstellt Verzeichnisse bei Bedarf.""" path.parent.mkdir(parents=True, exist_ok=True) content = ( - f'[hotkey]\nkey = "{config.hotkey}"\n\n' - f'[whisper]\nmodel = "{config.whisper_model}"\n' - f'language = "{config.language}"\n' - f'compute_type = "{config.compute_type}"\n\n' + f'[hotkey]\nkey = "{_toml_str(config.hotkey)}"\n\n' + f'[whisper]\nmodel = "{_toml_str(config.whisper_model)}"\n' + f'language = "{_toml_str(config.language)}"\n' + f'compute_type = "{_toml_str(config.compute_type)}"\n\n' f'[audio]\nsample_rate = {config.sample_rate}\n' f'channels = {config.channels}\n' f'min_duration = {config.min_duration}\n' - f'device = "{config.microphone}"\n' + f'device = "{_toml_str(config.microphone)}"\n' ) path.write_text(content, encoding="utf-8")