In questo modo è possibile disinfettare un file system come richiesto
function filter_filename($name) {
// remove illegal file system characters https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
$name = str_replace(array_merge(
array_map('chr', range(0, 31)),
array('<', '>', ':', '"', '/', '\\', '|', '?', '*')
), '', $name);
// maximise filename length to 255 bytes http://serverfault.com/a/9548/44086
$ext = pathinfo($name, PATHINFO_EXTENSION);
$name= mb_strcut(pathinfo($name, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($name)) . ($ext ? '.' . $ext : '');
return $name;
}
Tutto il resto è consentito in un filesystem, quindi la domanda ha una risposta perfetta ...
... ma potrebbe essere pericoloso consentire ad esempio virgolette singole 'in un nome di file se lo si utilizza in seguito in un contesto HTML non sicuro perché questo nome di file assolutamente legale:
' onerror= 'alert(document.cookie).jpg
diventa un foro XSS :
<img src='<? echo $image ?>' />
// output:
<img src=' ' onerror= 'alert(document.cookie)' />
Per questo motivo, il popolare software CMS Wordpress li rimuove, ma hanno coperto tutti i caratteri rilevanti solo dopo alcuni aggiornamenti :
$special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));
// ... a few rows later are whitespaces removed as well ...
preg_replace( '/[\r\n\t -]+/', '-', $filename )
Infine il loro elenco include ora la maggior parte dei caratteri che fanno parte dell'URI rerserved-characters e dell'URL non sicuri .
Ovviamente potresti semplicemente codificare tutti questi caratteri sull'output HTML, ma la maggior parte degli sviluppatori e anche io, segui l'idioma "Meglio prevenire che curare" ed eliminarli in anticipo.
Quindi alla fine suggerirei di usare questo:
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);
// maximize filename length to 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;
}
Tutto il resto che non causa problemi con il file system dovrebbe far parte di una funzione aggiuntiva:
function beautify_filename($filename) {
// reduce consecutive characters
$filename = preg_replace(array(
// "file name.zip" becomes "file-name.zip"
'/ +/',
// "file___name.zip" becomes "file-name.zip"
'/_+/',
// "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;
}
A questo punto è necessario generare un nome file se il risultato è vuoto e si può decidere se si desidera codificare i caratteri UTF-8. Ma non è necessario poiché UTF-8 è consentito in tutti i file system utilizzati nei contesti di hosting web.
L'unica cosa che devi fare è usare urlencode()(come si spera tu faccia con tutti i tuoi URL) in modo che il nome del file საბეჭდი_მანქანა.jpgdiventi questo URL come tuo <img src>o <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.jpg
Stackoverflow lo fa, quindi posso pubblicare questo link come farebbe un utente:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Quindi questo è un nome di file legale completo e non un problema come @ SequenceDigitale.com ha menzionato nella sua risposta .