Ich suche nach einer PHP-Funktion, die einen String bereinigt und für einen Dateinamen einsatzbereit macht. Kennt jemand einen handlichen?
(Ich könnte einen schreiben, aber ich mache mir Sorgen, dass ich einen Charakter übersehen werde!)
Bearbeiten: Zum Speichern von Dateien in einem Windows NTFS-Dateisystem.
php
string
sanitization
user151841
quelle
quelle
Antworten:
Anstatt sich Gedanken über das Übersehen von Zeichen zu machen - wie wäre es mit einer Whitelist von Zeichen, die Sie gerne verwenden? Zum Beispiel könnten Sie einfach gute alte erlauben
a-z
,0-9
,_
, und eine einzelne Instanz einer Periode (.
). Das ist natürlich einschränkender als die meisten Dateisysteme, sollte Sie aber schützen.quelle
Wenn Sie die Lösung von Tor Valamo geringfügig anpassen, um das von Dominic Rodger festgestellte Problem zu beheben, können Sie Folgendes verwenden:
quelle
..
danach die Prüfung durchführen . Zum Beispiel.?.
würde am Ende sein..
. Da Sie filtern,/
kann ich zwar nicht sehen, wie Sie das jetzt weiter ausnutzen würden, aber es zeigt, warum die Überprüfung..
hier unwirksam ist. Besser noch wahrscheinlich nicht ersetzen, nur ablehnen, wenn es nicht qualifiziert ist.[^a-z0-9_-]
wenn Sie wirklich restriktiv sein möchten - oder einfach einen generierten Namen verwenden und den angegebenen Namen wegwerfen und all diese Probleme vermeiden . :-)Auf diese Weise können Sie nach Bedarf ein Dateisystem bereinigen
Alles andere ist in einem Dateisystem erlaubt, daher ist die Frage perfekt beantwortet ...
... aber es könnte gefährlich sein, beispielsweise einfache Anführungszeichen
'
in einem Dateinamen zuzulassen, wenn Sie ihn später in einem unsicheren HTML-Kontext verwenden, da dieser absolut legale Dateiname:wird ein XSS-Loch :
Aus diesem Grund entfernt die beliebte CMS-Software Wordpress sie, deckte jedoch erst nach einigen Updates alle relevanten Zeichen ab :
Schließlich enthält ihre Liste jetzt die meisten Zeichen, die Teil der Liste der URI-reservierten Zeichen und der URL-unsicheren Zeichen sind .
Natürlich können Sie all diese Zeichen einfach in der HTML-Ausgabe codieren, aber die meisten Entwickler und auch ich folgen der Redewendung "Besser sicher als leid" und löschen sie im Voraus.
Schließlich würde ich vorschlagen, dies zu verwenden:
Alles andere, was keine Probleme mit dem Dateisystem verursacht, sollte Teil einer zusätzlichen Funktion sein:
Zu diesem Zeitpunkt müssen Sie einen Dateinamen generieren, wenn das Ergebnis leer ist, und Sie können entscheiden, ob Sie UTF-8-Zeichen codieren möchten. Dies ist jedoch nicht erforderlich, da UTF-8 in allen Dateisystemen zulässig ist, die in Webhosting-Kontexten verwendet werden.
Das einzige, was Sie tun müssen, ist zu verwenden
urlencode()
(wie Sie es hoffentlich mit all Ihren URLs tun), damit der Dateinameსაბეჭდი_მანქანა.jpg
zu Ihrer URL wird<img src>
oder<a href>
: http://www.maxrev.de/html/img/%E1%83% A1% E1% 83% 90% E1% 83% 91% E1% 83% 94% E1% 83% AD% E1% 83% 93% E1% 83% 98_% E1% 83% 9B% E1% 83% 90% E1% 83% 9C% E1% 83% A5% E1% 83% 90% E1% 83% 9C% E1% 83% 90.jpgStackoverflow macht das, also kann ich diesen Link so posten, wie es ein Benutzer tun würde:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Dies ist also ein vollständiger legaler Dateiname und kein Problem, wie @ SequenceDigitale.com in seiner Antwort erwähnt .
quelle
r-u-l-e-s
und ich habe keine Ahnung, warum dies passiert. Sicher ist, dass es nicht an der Funktion liegt, sondern nur zu fragen - was könnte der Grund für ein solches Verhalten sein? Falsche Kodierung?preg_replace
Infilter_filename()
.Was ist mit rawurlencode ()? http://www.php.net/manual/en/function.rawurlencode.php
Hier ist eine Funktion, die sogar chinesische Zeichen bereinigt:
Hier ist die Erklärung
OK, einige Dateinamen sind nicht relevant, aber in den meisten Fällen funktionieren sie.
Ex. Ursprünglicher Name: "საბეჭდი-და-ტიპოგრაფიული. Jpg"
Ausgabename: "-E1-83-A1-E1-83-90-E1-83-91-E1-83-94-E1-83-AD-E1-83-93-E1-83-98 - E1- 83-93-E1-83-90 - E1-83-A2-E1-83-98-E1-83-9E-E1-83-9D-E1-83-92-E1-83-A0-E1-83 -90-E1-83-A4-E1-83-98-E1-83-A3-E1-83-9A-E1-83-98.jpg
Es ist besser so als ein 404-Fehler.
Hoffe das war hilfreich.
Carl.
quelle
http://www.maxrev.de/html/img/საბეჭდი_მანქანა.jpg
umhttp://www.maxrev.de/html/img/%E1%83%A1%E1%83%90%E1%83%91%E1%83%94%E1%83%AD%E1%83%93%E1%83%98_%E1%83%9B%E1%83%90%E1%83%9C%E1%83%A5%E1%83%90%E1%83%9C%E1%83%90.jpg
in dem HTML - Quellcode , wie Sie hoffentlich mit allen URLs tun.strip_tags()
und danach entfernen Sie[<>]
. Dasstrip_tags()
wird überhaupt nicht wirklich gebraucht. Der gleiche Punkt sind die Anführungszeichen. Beim Dekodieren mit sind keine Anführungszeichen mehr vorhandenENT_QUOTES
. Und das entferntstr_replace()
keine aufeinanderfolgenden Leerzeichen und dann verwenden Siestrtolower()
für Multibyte-Zeichenfolge. Und warum konvertieren Sie überhaupt in Kleinbuchstaben? Und schließlich hast du keinen reservierten Charakter gefangen, wie @BasilMusa erwähnt hat. Weitere Details in meiner Antwort: stackoverflow.com/a/42058764/318765LÖSUNG 1 - einfach und effektiv
$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );
[^a-z0-9]+
wird sicherstellen, dass der Dateiname nur Buchstaben und Zahlen enthält'-'
der Dateiname lesbar bleibtBeispiel:
LÖSUNG 2 - für sehr lange URLs
Sie möchten den URL-Inhalt zwischenspeichern und benötigen nur eindeutige Dateinamen. Ich würde diese Funktion verwenden:
$file_name = md5( strtolower( $url ) )
Dadurch wird ein Dateiname mit fester Länge erstellt. Der MD5-Hash ist in den meisten Fällen einzigartig genug für diese Art der Verwendung.
Beispiel:
quelle
Nun, tempnam () wird es für Sie tun.
http://us2.php.net/manual/en/function.tempnam.php
aber das schafft einen völlig neuen Namen.
Um eine vorhandene Zeichenfolge zu bereinigen, beschränken Sie einfach die Eingabe durch Ihre Benutzer und geben Sie Buchstaben, Zahlen, Punkte, Bindestriche und Unterstriche ein. Bereinigen Sie sie dann mit einem einfachen regulären Ausdruck. Überprüfen Sie, welche Zeichen maskiert werden müssen, da sonst Fehlalarme auftreten können.
quelle
Fügen Sie weitere gültige Zeichen hinzu oder entfernen Sie sie, je nachdem, was für Ihr System zulässig ist.
Alternativ können Sie versuchen, die Datei zu erstellen und dann einen Fehler zurückgeben, wenn er fehlerhaft ist.
quelle
..
, was ein Problem sein kann oder nicht.PHP bietet eine Funktion zum Bereinigen eines Textes in ein anderes Format
filter.filters.sanitize
Wie man :
quelle
Der folgende Ausdruck erstellt eine schöne, saubere und verwendbare Zeichenfolge:
Das heutige Finanzwesen verwandeln: Abrechnung in heutige Finanzabrechnung
quelle
preg_replace
das globale Flag ist implizit. G wird also nicht benötigt, wenn preg_replace verwendet wird. Wenn wir die Anzahl der Ersetzungen steuern möchten, hat preg_replace einenlimit
Parameter dafür. Weitere Informationen finden Sie in der Dokumentation zu preg_replace.Wenn Sie eine kleine Anpassung an Sean Vieiras Lösung vornehmen, um einzelne Punkte zu berücksichtigen, können Sie Folgendes verwenden:
quelle
sicher: Ersetzen Sie jede Folge von NICHT "a-zA-Z0-9_-" durch einen Bindestrich. Fügen Sie selbst eine Erweiterung hinzu.
quelle
Diese mögen etwas schwer sein, aber sie sind flexibel genug, um jede Saite in einen "Safe" zu verwandeln.
en
Dateinamen oder Ordnernamen im Stil zu bereinigen (oder zum Teufel sogar geschrubbte Schnecken und Dinge, wenn Sie sie biegen).1) Erstellen eines vollständigen Dateinamens (mit Fallback-Namen, falls die Eingabe vollständig abgeschnitten ist):
2) Oder verwenden Sie nur den Filter util, ohne einen vollständigen Dateinamen zu erstellen (im strengen Modus
true
sind [] oder () im Dateinamen nicht zulässig ):3) Und hier sind diese Funktionen:
Nehmen wir also an, einige Benutzereingaben lauten:
.....<div></div><script></script>& Weiß Göbel 中文百强网File name %20 %20 %21 %2C Décor \/. /. . z \... y \...... x ./ “This name” is & 462^^ not = that grrrreat -][09]()1234747) საბეჭდი-და-ტიპოგრაფიული
Und wir wollen es in etwas Freundlicheres konvertieren, um ein tar.gz mit einer Dateinamenlänge von 255 Zeichen zu erstellen. Hier ist ein Beispiel für die Verwendung. Hinweis: Dieses Beispiel enthält eine fehlerhafte tar.gz-Erweiterung als Proof of Concept. Sie sollten die ext trotzdem filtern, nachdem die Zeichenfolge anhand Ihrer Whitelist (s) erstellt wurde.
Die Ausgabe wäre:
_wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz
Sie können hier damit spielen: https://3v4l.org/iSgi8
Oder eine Zusammenfassung: https://gist.github.com/dhaupin/b109d3a8464239b7754a
BEARBEITEN:
Aktualisierter Skriptfilter für anstelle von Speicherplatz, aktualisierter 3v4l-Linkquelle
Das Beste, was ich heute weiß, ist die statische Methode Strings :: webalize aus dem Nette-Framework.
Übrigens übersetzt dies alle diakritischen Zeichen in ihre Grundzeichen. Š => s ü => u ß => ss usw.
Für Dateinamen müssen Sie den Punkt "." Hinzufügen. zu erlaubten Zeichen Parameter.
quelle
urlencode()
Sie einfach, bevor Sie den Dateinamen alssrc
oder verwendenhref
. Das einzige derzeit verwendete Dateisystem, das Probleme mit UTF-8 hat, ist FATx (von XBOX verwendet): en.wikipedia.org/wiki/Comparison_of_file_systems#Limits Und ich glaube nicht, dass dies von Webservern verwendet wirdEs scheint, dass dies alles von der Frage abhängt, ob es möglich ist, einen Dateinamen zu erstellen, der zum Hacken in einen Server verwendet werden kann (oder einen solchen anderen Schaden anrichtet). Wenn nicht, scheint es die einfache Antwort zu sein, die Datei dort zu erstellen, wo sie letztendlich verwendet wird (da dies zweifellos das Betriebssystem der Wahl sein wird). Lassen Sie das Betriebssystem das klären. Wenn es sich beschwert, portieren Sie diese Beschwerde als Validierungsfehler zurück an den Benutzer.
Dies hat den zusätzlichen Vorteil, dass es zuverlässig portierbar ist, da sich alle (ich bin mir ziemlich sicher) Betriebssysteme beschweren, wenn der Dateiname für dieses Betriebssystem nicht richtig gebildet wird.
Wenn es ist möglich schändliche Dinge mit einem Dateinamen zu tun, vielleicht gibt es Maßnahmen , die vor dem Testen den Dateinamen auf dem residenten Betriebssystem angewandt werden können - Maßnahmen weniger kompliziert als eine vollständige „Hygiene“ des Dateinamen.
quelle
Einweg
quelle
/
und..
im vom Benutzer angegebenen Dateinamen kann schädlich sein. Also sollten Sie diese durch etwas wie: loswerden.quelle
..name
den nichts ausbrechen würde. Das Entfernen aller Pfadtrennzeichen sollte ausreichen, um ein Durchlaufen des Verzeichnisses zu verhindern. (Das Entfernen von..
ist technisch unnötig.)./.
wird..
. Und schließlich fehlen bei dieser Antwort alle anderen für das Dateisystem reservierten Zeichen wie NULL. Mehr in meiner Antwort: stackoverflow.com/a/42058764/318765Da Benutzer den Schrägstrich möglicherweise verwenden, um zwei Wörter zu trennen, ist es besser, anstelle von NULL einen Bindestrich zu verwenden
quelle