/// Zentrale Sanitize-Funktion für Dateinamen. /// Verhindert Path-Traversal (../), Null-Bytes, Windows-reservierte Namen /// (CON, NUL, PRN, AUX, COM1-9, LPT1-9) und andere gefährliche Zeichen. String sanitizeDateiname(String name) { // 1. Extrahiere nur den Dateinamen (keine Pfad-Komponenten) var safe = name.split('/').last.split('\\').last; // 2. Entferne NULL-Bytes und andere gefährliche Steuerzeichen safe = safe.replaceAll(RegExp(r'[\x00-\x1F\x7F]'), ''); // 3. Entferne alles außer Wort-Zeichen, Leerzeichen und Bindestrichen // (unicode: true + \p{L}/\p{N} → auch Umlaute wie ü/ä/ö bleiben, // sonst würden deutsche Dateinamen wie "Müller.mp3" → "Mller.mp3") safe = safe.replaceAll(RegExp(r'[^\p{L}\p{N}_\s.-]', unicode: true), ''); // 4. Trimmen VOR der Punkt-Prüfung — sonst umgeht " .." (Leerzeichen vor // den Punkten) die Entfernung führender Punkte und ergäbe ".." als Namen. safe = safe.trim(); // 5. Entferne führende Punkte (versteckte Dateien) safe = safe.replaceAll(RegExp(r'^\.+'), ''); // 6. Nach Sonderzeichen-Entfernung können Punkt-Sequenzen übrig bleiben: // ".." / "..." als kompletter Name (oder führende "..") wäre // Pfad-Traversal → verwerfen. if (safe == '..' || safe == '...' || safe.startsWith('..')) { safe = 'unknown'; } // 7. Windows-reservierte Namen abfangen (CON, NUL, PRN, AUX, COM1-9, // LPT1-9) — auch mit Endung (z.B. "CON.txt") und case-insensitiv. // Windows behandelt diese Namen unabhängig von der Endung als Geräte. final basis = safe.split('.').first.toUpperCase(); if (RegExp(r'^(CON|NUL|PRN|AUX|COM[1-9]|LPT[1-9])$').hasMatch(basis)) { safe = 'unknown'; } // 8. Windows: Punkte/Leerzeichen am Ende entfernen (werden vom // Dateisystem ignoriert und erzeugen sonst Kollisionen) safe = safe.replaceAll(RegExp(r'[. ]+$'), ''); // 9. Trimmen und Default-Name falls leer safe = safe.trim(); if (safe.isEmpty) safe = 'unknown'; // 10. Auf sinnvolle Länge kürzen (255 Zeichen ist typisches Dateisystem-Limit) if (safe.length > 200) safe = safe.substring(0, 200); return safe; }