» Dateinamen filtern - Sonderzeichen usw entfernen

rmdirs() Verzeichnis rekursiv löschen (+ Unterverzeichnisse)Neuen Thread eröffnenNeue Antwort erstellenAnfänger braucht Hilfe :)
AutorNachricht
Administrator 

Name: Marc
Geschlecht:
Anmeldedatum: 28.08.2004
Beiträge: 52423
Wohnort: Lohmar


Meine eBay-Auktionen:
06.02.2017, 07:49
zitieren

Eigentlich ist es gar nicht so schwer Dateinamen zu filtern. Die einzige Regel, die man beachten muss, sind die reservierten Zeichen in den verschiedenen Dateisystemen (NTFS, EXT, etc.) und der Betriebssysteme (Windows, Mac, Linux, etc.).

Dieser Wikipedia-Artikel beschreibt das sehr gut:
https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words


Auch dort erwähnt ist diese Quelle, wo auf die in Windows nicht erlaubten Control Zeichen 0-31 vom ASCII Zeichensatz eingegangen wird:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
ZitatUse any character in the current code page for a name, including Unicode characters and characters in the extended character set (128–255), except for the following:

...

  • Integer value zero, sometimes referred to as the ASCII NUL character.
  • Characters whose integer representations are in the range from 1 through 31

Außerdem müssen wir noch beachten, dass die meisten aktuellen Dateisysteme keine Dateinamen erlauben, die länger als 255 Bytes sind:
http://serverfault.com/a/9548/44086
ZitatBTRFS 255 bytes
exFAT 255 UTF-16 characters
ext2 255 bytes
ext3 255 bytes
ext3cow 255 bytes
ext4 255 bytes
FAT32 8.3 (255 UCS-2 code units with VFAT LFNs)
NTFS 255 characters
XFS 255 bytes

Und damit ergibt sich nun diese Funktion:
function filter_filename($filename) {
// remove illegal file system characters https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
$filename = str_replace(array_merge(
array_map('chr', range(0, 31)),
array('<', '>', ':', '"', '/', '\\', '|', '?', '*')
), '', $filename);
// maximum filename length of 255 bytes http://serverfault.com/a/9548/44086
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$filename = mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)) . ($ext ? '.' . $ext : '');
return $filename;
}

Fertig? Im Grunde schon, wären da nicht Sicherheitslücken, die man dadurch riskiert. Denn da man die Sprache PHP in der Regel im Web-Kontext verwendet, sollte man auch andere Zeichen wie z.B. das einfache Anführungszeichen entfernen, denn sonst könnte aus dem Dateinamen
NotExist' onerror='alert(1).jpg
, falls
htmlspecialchars()
oder nur dessen Parameter
ENT_QUOTES
vergessen wurde, daraus die XSS Lücke
<img src='NotExist' onerror='alert(1)' />
werden. Und ja, dieser Dateiname ist in jedem Betriebssystem erlaubt. Probiere es aus.Aus dem Grund empfiehlt es sich einfach alle Zeichen zu entfernen, die zu den URI reservierten:
https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters

und in URL unsicheren Zeichen zählen:
https://tools.ietf.org/html/rfc1738

Daraus ergibt sich dann die folgende Funktion:
function filter_filename($filename, $beautify=true) {
// sanitize filename
$filename = preg_replace(
'~
[<>:"/\\|?*]|            # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
[\x00-\x1F]|             # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
[\x7F\xA0\xAD]|          # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
[#\[\]@!$&\'()+,;=]|     # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
[{}^\~`]                 # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
~x',
'-', $filename);
// avoids ".", ".." or ".hiddenFiles"
$filename = ltrim($filename, '.-');
// optional beautification
if ($beautify) $filename = beautify_filename($filename);
// general maximum filename length is 255 bytes http://serverfault.com/a/9548/44086
// we maximise to 200 bytes as windows includes the path https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$filename = mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 200 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)) . ($ext ? '.' . $ext : '');
return $filename;
}

Neben den besagten Zeichen wird hier noch weiteres gefiltert:
  • die nicht sichtbaren Zeichen "DEL", "NO-BREAK-SPACE" und "SOFT HYPHEN"
  • die Dateinamen ".", "..", da sie in Linux für das aktuelle bzw. das darüber liegende Verzeichnis stehen
  • alle Dateien die mit "." beginnen, da es sich dabei in Linux um versteckte Dateien handelt
  • der Dateiname wird auf 200 statt 255 Bytes gekürzt, da in Windows auch der Pfadname Platz benötigt
Wie man sieht kann man noch mit
beautify_filename()
zusätzlich den Dateinamen weiter verschönern. Das habe ich bewusst in eine separate Funktion gepackt, da es nicht zwingend für das Dateisystem notwendig ist:
function beautify_filename($filename) {
// reduce consecutive characters
$filename = preg_replace(array(
// remove whitespace
'/ +/',
// remove underline
'/_+/',
// "file---name.zip" becomes "file-name.zip"
'/-+/'
), '-', $filename);
$filename = preg_replace(array(
// "file-.-.-.-name..zip" becomes "file...name..zip"
'/-?\.-?/',
// "file...name..zip" becomes "file.name.zip"
'/\.{2,}/'
), '.', $filename);
// lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
// ".file-name.-" becomes "file-name"
$filename = trim($filename, '.-');
return $filename;
}

Wer es perfekt machen möchte, der legt die Dateinamenlänge an Hand des aktuell genutzten Pfades fest bzw. bleibt bei exakt 255 Zeichen, da er davon ausgeht, dass Windows irgendwann standardmäßig lange Pfadnamen unterstützt, was sich seit Windows 10 ja optional einstellen lässt:
https://mspoweruser.com/ntfs-260-character-windows-10/

Außerdem könnte man auch das grundsätzliche Verkleinern von Dateinamen davon abhängig machen ob eine gleichlautende Datei bereits im Verzeichnis ist. Allerdings gestaltet sich das insbesondere in Linux als schwierig, wenn man mehrere Hundert Dateien im Verzeichnis hat und theoretisch ja
Dateiname, dateiname, DateiName, dateiName, usw
alle in einem Verzeichnis liegen können. D.h. man müsste erst alle Dateien einlesen, den Namen verkleinern und dann abgleichen. Das ist denke ich nicht praktikabel, weshalb eine grundsätzliche Verkleinerung der Dateinamen ratsam erscheint, wenn man mal von Linux auf Windows wechselt oder Backups hier lagert bzw verarbeiten möchten.


 
2017-02-06 08_48_55-Filename - Wikipedia.png
2017-02-06 08_48_55-Filename - Wikipedia.png - [Bild vergrößern]



Verfasst am: 12.08.2019, 19:33
zitieren

Ich nutze bei Datei-Uploads zur Prüfung von Dateinamen nun das:
function filter_filename($filename) {
    $filename = preg_replace(
        '~
        [<>:"/\\|?*]|            # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
        [\x00-\x1F]|             # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
        [\x7F\xA0\xAD]|          # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
        [#\[\]@!$&\'()+,;=]|     # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
        [{}^\~`]                 # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
        ~xu',
        '', $filename);
    // avoids ".", ".." or ".hiddenFiles"
    $filename = ltrim($filename, '.');
    // maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
    $len = $ext && ($ext = '.' . $ext) ? 255 - strlen($ext) : 255;
    return mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, $len, mb_detect_encoding($filename)) . $ext;
}

Nutzung:
if (filter_filename($filename) != $filename) {
    exit('Error: Filename not allowed');
}

Vom Prinzip hat sich nicht viel geändert. Der Code wurde nur etwas umgestellt und für UTF8 der u-Modifikator hinzugefügt.

 2x  bearbeitet
pn email
Gast 
12.08.2019, 19:33
zitieren

Mach mit!

Wenn Dir die Beiträge zum Thread "Dateinamen filtern - Sonderzeichen usw entfernen" gefallen haben oder Du noch Fragen hast oder Ergänzungen machen möchtest, solltest Du Dich gleich bei uns anmelden:



Registrierte Mitglieder genießen die folgenden Vorteile:
✔ kostenlose Mitgliedschaft
keine Werbung
✔ direkter Austausch mit Gleichgesinnten
✔ neue Fragen stellen oder Diskussionen starten
✔ schnelle Hilfe bei Problemen
✔ Bilder und Videos hochladen
✔ und vieles mehr...


Neuen Thread eröffnenNeue Antwort erstellen
Ähnliche BeiträgeRe:
Letzter Beitrag
Dateinamen mit Umlauten
Muss aus Platzgründen unsere Wiki auf einen anderen Server umziehen. Nun sind schon etliche Dateien in die bisherige Wiki hochgeladen worden, bei denen Umlaute im Dateinamen vorkommen. Bisher gab es mit Links wie [[bild:übersicht.gif]] keine Probleme,...
von kringelkopp
8
3.593
18.03.2008, 15:46
mgutt
Suche nach Sonderzeichen (runden Klammern): So gehts
Hi, hab eine Weile gebraucht um das Herauszufinden, daher hier mein Ergebnis. Wer in Windows Vista oder Windows 7 nach Sonderzeichen wie z.B. der runden Klammer suchen möchte muss den folgenden Syntax benutzen: ...
von mgutt
0
5.743
15.09.2011, 08:12
mgutt
Dattenrettung mit PhotoRec: Wo sind die Dateinamen?
Hi, ich habe für einen Bekannten Dateien auf einer Festplatte mit PhotoRec wiederhergestellt. Einiges konnte gerettet werden. Allerdings sind 90% der Dateinamen einfach nur durchnummeriert. Wie kommt das? Auch verstehe ich die Ordnerstruktur nicht. Er...
von mgutt
3
1.474
09.10.2010, 17:15
mgutt
Personenbezogene Daten aus Internet filtern
Hallo, ich suche für ein privates Projekt einen Programmierer, der nach meinen Vorgaben eine kleine Software für mich entwickelt, die personenbezogene Daten aus dem Internet filtert. Die Software sollte lokal installiert werden können. Ich möchte z.B....
[Allgemein]von Peter_Z
5
645
26.03.2010, 12:46
mgutt
Marktplatz / Kleinanzeigen modellspezifisch filtern
Ausgehend von einer Diskussion im Jazz Forum kam die Idee die Verkaufsanzeigen im Marktplatz je nach Fahrzeug filterbar zu machen. Dazu wäre es nötig bei der Eingabe ein Pflichtfeld einzuführen, wo man die passende Fahrzeugkategorie auswählt. Im...
von mgutt
14
590
23.01.2011, 11:45
situx
Welcher unterschied zwischen den K&N Filtern ???
Hey leute. Ich habe heute mal nach nem k&n filter für meinen eg3 geguckt. Da hab ich allerdings zwei stück gefunden. Allerdings seh ich bei den beiden kein unterschied. außer das der eine n euro teurer ist. ich hoffe, ihr könnt mir helfen....
von CIVIC - Christian
4
553
27.11.2006, 12:57
deacone
Paypal Transaktionen (gesendete Zahlungen) nach Wort filtern?
Irgendwie bin ich zu blöd das zu finden oder gibt es wirklich keine Filterfunktion bei Paypal, damit ich mir alle Zahlungen ausgeben lassen kann, die an einen bestimmten Empfänger gegangen...
von mgutt
0
800
15.12.2014, 09:54
mgutt
Server überlastet wg. fehlerhafter Suche "auch in Dateinamen"
Hallo, der Server war gerade offline, weil es einen Fehler in der erweiterten Suche gibt. Die Suche nach "auch in Dateinamen" ist daher erstmal...
von mgutt
0
194
31.07.2013, 07:43
mgutt
ECU WFS entfernen
Suche jemanden der mir die wegfahrsperre an ner b18 c4 ECU entfernen kann weil ich nen nen B18 aus nen Aerodeck in nen eg hängen will, kennt sich einer damit aus der das machen kann bzw krieg ich das selber hin?? Wäre cool wenn mir jemand helfen kann ...
von Blue-Sonic
0
358
07.11.2010, 20:21
Blue-Sonic
Kat entfernen..
moin moin, habe ein kleines Problem und zwar ist mein Kat aus irgendeinem Grund kaputt. Nun möchte ich mir einen neuen einbauen allerdings kriege ích den alten nicht gelöst. Habe es schon mit WD40 probiert sowie mit so einem Druckluftdrehteil (mir fällt...
von yolo
6
472
20.11.2013, 13:53
xen_hb
© 2004 - 2025 www.programmierer-forum.de | Communities | Impressum |