Je recherche une fonction php qui nettoiera une chaîne et la rendra prête à être utilisée pour un nom de fichier. Quelqu'un en connait un pratique?
(Je pourrais en écrire un, mais j'ai peur d'oublier un personnage!)
Edit: pour enregistrer des fichiers sur un système de fichiers Windows NTFS.
php
string
sanitization
user151841
la source
la source
Réponses:
Au lieu de vous soucier d'oublier les caractères, que diriez-vous d'utiliser une liste blanche de caractères que vous êtes heureux d'utiliser? Par exemple, vous pouvez permettre juste bon vieux
a-z
,0-9
,_
et une seule instance d'une période (.
). C'est évidemment plus limitant que la plupart des systèmes de fichiers, mais cela devrait vous protéger.la source
En apportant un petit ajustement à la solution de Tor Valamo pour résoudre le problème remarqué par Dominic Rodger, vous pouvez utiliser:
la source
..
après. Par exemple.?.
finirait par l'être..
. Bien que depuis que vous filtrez,/
je ne vois pas comment vous pourriez exploiter cela davantage pour le moment, mais cela montre pourquoi la vérification..
est inefficace ici. Mieux encore probablement, ne remplacez pas, rejetez simplement s'il n'est pas admissible.[^a-z0-9_-]
si vous voulez être vraiment restrictif - ou simplement utiliser un nom généré et jeter le nom donné et éviter tous ces problèmes. :-)Voici comment vous pouvez nettoyer un système de fichiers comme demandé
Tout le reste est autorisé dans un système de fichiers, donc la question est parfaitement répondue ...
... mais il pourrait être dangereux d'autoriser, par exemple, des guillemets simples
'
dans un nom de fichier si vous l'utilisez plus tard dans un contexte HTML dangereux car ce nom de fichier absolument légal:devient un trou XSS :
Pour cette raison, le logiciel CMS populaire Wordpress les supprime, mais ils ne couvrent tous les caractères pertinents qu'après quelques mises à jour :
Enfin leur liste inclut désormais la plupart des personnages qui font partie de l' URI rerserved-caractères et URL caractères dangereux liste.
Bien sûr, vous pouvez simplement encoder tous ces caractères sur la sortie HTML, mais la plupart des développeurs et moi aussi, suivons l'idiome "Mieux vaut prévenir que guérir" et les supprimer à l'avance.
Alors enfin, je suggérerais d'utiliser ceci:
Tout le reste qui ne pose pas de problème avec le système de fichiers doit faire partie d'une fonction supplémentaire:
Et à ce stade, vous devez générer un nom de fichier si le résultat est vide et vous pouvez décider si vous souhaitez encoder des caractères UTF-8. Mais vous n'en avez pas besoin car UTF-8 est autorisé dans tous les systèmes de fichiers utilisés dans les contextes d'hébergement Web.
La seule chose que vous devez faire est d'utiliser
urlencode()
(comme vous le faites avec toutes vos URL) afin que le nom de fichierსაბეჭდი_მანქანა.jpg
devienne cette URL en tant que votre<img src>
ou<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 fait cela, donc je peux publier ce lien comme le ferait un utilisateur:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
C'est donc un nom de fichier légal complet et pas un problème comme @ SequenceDigitale.com l'a mentionné dans sa réponse .
la source
r-u-l-e-s
et je n'ai aucune idée pourquoi cela se produit. Bien sûr, ce n'est pas la faute de la fonction, mais simplement demander - quelle pourrait être la raison d'un tel comportement? Mauvais encodage?preg_replace
entréefilter_filename()
.Qu'en est-il de l'utilisation de rawurlencode ()? http://www.php.net/manual/en/function.rawurlencode.php
Voici une fonction qui désinfecte même les caractères chinois:
Voici l'explication
OK, certains noms de fichiers ne seront pas pertinents mais dans la plupart des cas, cela fonctionnera.
ex. Nom d'origine: "საბეჭდი-და-ტიპოგრაფიული. Jpg"
Nom de la sortie: "-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 "
C'est mieux comme ça qu'une erreur 404.
J'espère que cela a été utile.
Carl.
la source
http://www.maxrev.de/html/img/საბეჭდი_მანქანა.jpg
à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.jpg
dans le code source HTML comme vous le faites si possible avec toutes vos URL.strip_tags()
que vous supprimiez[<>]
. Par celastrip_tags()
n'est pas vraiment nécessaire du tout. Le même point sont les citations. Il ne reste plus de guillemets lorsque vous décodez avecENT_QUOTES
. Et lestr_replace()
ne supprime pas les espaces blancs consécutifs, puis vous utilisezstrtolower()
pour une chaîne multi-octets. Et pourquoi vous convertissez-vous en minuscules? Et finalement, vous n'avez attrapé aucun personnage réservé comme l'a mentionné @BasilMusa. Plus de détails dans ma réponse: stackoverflow.com/a/42058764/318765SOLUTION 1 - simple et efficace
$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );
[^a-z0-9]+
assurera, le nom de fichier ne garde que les lettres et les chiffres'-'
garde le nom de fichier lisibleExemple:
SOLUTION 2 - pour les URL très longues
Vous voulez mettre en cache le contenu de l'URL et avez juste besoin d'avoir des noms de fichiers uniques. J'utiliserais cette fonction:
$file_name = md5( strtolower( $url ) )
cela créera un nom de fichier de longueur fixe. Le hachage MD5 est dans la plupart des cas assez unique pour ce type d'utilisation.
Exemple:
la source
Eh bien, tempnam () le fera pour vous.
http://us2.php.net/manual/en/function.tempnam.php
mais cela crée un nom entièrement nouveau.
Pour nettoyer une chaîne existante, limitez simplement ce que vos utilisateurs peuvent entrer et faites-en des lettres, des chiffres, un point, un trait d'union et un trait de soulignement, puis nettoyez avec une simple regex. Vérifiez quels caractères doivent être échappés ou vous pourriez obtenir de faux positifs.
la source
Ajoutez / supprimez plus de caractères valides en fonction de ce qui est autorisé pour votre système.
Vous pouvez également essayer de créer le fichier, puis renvoyer une erreur si elle est incorrecte.
la source
..
, ce qui peut ou non être un problème.PHP fournit une fonction pour nettoyer un texte dans un format différent
filter.filters.sanitize
Comment :
la source
sûr: remplacez chaque séquence de NOT "a-zA-Z0-9_-" par un tiret; ajoutez vous-même une extension.
la source
L'expression suivante crée une chaîne agréable, propre et utilisable:
Transformer les finances d'aujourd'hui: la facturation en facturation financière d' aujourd'hui
la source
preg_replace
l'indicateur global est implicite. Il n'y a donc pas besoin de g si preg_replace est utilisé. Lorsque nous voulons contrôler le nombre de remplacements, preg_replace a unlimit
paramètre pour cela. Lisez la documentation preg_replace pour en savoir plus.En ajustant légèrement la solution de Sean Vieira pour permettre des points uniques, vous pouvez utiliser:
la source
Celles-ci peuvent être un peu lourdes, mais elles sont suffisamment flexibles pour désinfecter n'importe quelle chaîne en un "coffre-fort"
en
nom de fichier ou de dossier de style (ou diable, même des slugs nettoyés et autres si vous le pliez).1) Construire un nom de fichier complet (avec un nom de secours si l'entrée est totalement tronquée):
2) Ou en utilisant simplement l'utilitaire de filtrage sans construire un nom de fichier complet (le mode strict
true
n'autorisera pas [] ou () dans le nom de fichier):3) Et voici ces fonctions:
Alors disons que certaines entrées utilisateur sont:
.....<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) საბეჭდი-და-ტიპოგრაფიული
Et nous voulons le convertir en quelque chose de plus convivial pour créer un tar.gz avec une longueur de nom de fichier de 255 caractères. Voici un exemple d'utilisation. Remarque: cet exemple inclut une extension tar.gz malformée comme preuve de concept, vous devez toujours filtrer l'ext après que la chaîne soit construite par rapport à votre (vos) liste (s) blanche (s).
Le résultat serait:
_wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz
Vous pouvez jouer avec ici: https://3v4l.org/iSgi8
Ou un Gist: https://gist.github.com/dhaupin/b109d3a8464239b7754a
EDIT: filtre de script mis à jour pour la
place de l'espace, lien 3v4l mis à jourla source
Le meilleur que je connaisse aujourd'hui est la méthode statique Strings :: webalize du framework Nette.
BTW, cela traduit tous les signes diacritiques à leur base .. š => s ü => u ß => ss etc.
Pour les noms de fichiers, vous devez ajouter le point "." au paramètre de caractères autorisés.
la source
urlencode()
avant d'utiliser le nom de fichier en tant quesrc
ouhref
. Le seul système de fichiers actuellement utilisé qui a des problèmes avec UTF-8 est FATx (utilisé par XBOX): en.wikipedia.org/wiki/Comparison_of_file_systems#Limits Et je ne pense pas que cela soit utilisé par les serveurs WebIl semble que tout dépend de la question, est-il possible de créer un nom de fichier qui peut être utilisé pour pirater un serveur (ou faire d'autres dommages). Sinon, il semble que la réponse la plus simple soit d'essayer de créer le fichier là où il sera finalement utilisé (puisque ce sera le système d'exploitation de choix, sans aucun doute). Laissez le système d'exploitation régler le problème. S'il se plaint, renvoyez cette plainte à l'utilisateur en tant qu'erreur de validation.
Cela a l'avantage supplémentaire d'être portable de manière fiable, car tous les systèmes d'exploitation (j'en suis presque sûr) se plaindront si le nom de fichier n'est pas correctement formé pour ce système d'exploitation.
S'il est possible de faire des choses néfastes avec un nom de fichier, peut-être y a-t-il des mesures qui peuvent être appliquées avant de tester le nom de fichier sur le système d'exploitation résident - des mesures moins compliquées qu'un "nettoyage" complet du nom de fichier.
la source
une manière
la source
/
et..
dans le nom de fichier fourni par l'utilisateur peut être nuisible. Vous devriez donc vous en débarrasser par quelque chose comme:la source
..name
laquelle ne se briserait de rien. La suppression de tous les caractères de séparation de chemin devrait être suffisante pour empêcher toute traversée de répertoire. (La suppression de..
est techniquement inutile.)./.
devient..
. Et finalement, cette réponse manque tous les autres caractères réservés au système de fichiers comme NULL. Plus dans ma réponse: stackoverflow.com/a/42058764/318765Étant donné que les utilisateurs peuvent utiliser la barre oblique pour séparer deux mots, il serait préférable de le remplacer par un tiret au lieu de NULL
la source