Я ищу функцию php, которая очистит строку и подготовит ее к использованию для имени файла. Кто-нибудь знает удобный?
(Я мог бы написать один, но боюсь, что пропущу персонажа!)
Изменить: для сохранения файлов в файловой системе Windows NTFS.
php
string
sanitization
user151841
источник
источник
Ответы:
Вместо того, чтобы беспокоиться о пропущенных персонажах - как насчет использования белого списка символов, которые вы готовы использовать? Например, вы могли бы позволить только старый добрый
a-z
,0-9
,_
и единственный экземпляр периода (.
). Очевидно, что это больше ограничений, чем у большинства файловых систем, но должно вас обезопасить.источник
Внеся небольшую корректировку в решение Tor Valamo, чтобы исправить проблему, замеченную Домиником Роджером, вы можете использовать:
источник
..
потом запустить проверку . Например.?.
, в конечном итоге будет..
. Хотя, поскольку вы фильтруете,/
я не вижу, как вы могли бы использовать это дальше прямо сейчас, но это показывает, почему проверка..
здесь неэффективна. Еще лучше, наверное, не заменять, просто отклонить, если он не соответствует требованиям.[^a-z0-9_-]
если хотите, чтобы оно было действительно ограничительным - или просто используйте сгенерированное имя и выбросьте данное имя, чтобы избежать всех этих проблем. :-)Вот как вы можете очистить файловую систему по запросу
Все остальное разрешено в файловой системе, так что на вопрос есть прекрасный ответ ...
... но может быть опасно разрешать, например, одинарные кавычки
'
в имени файла, если вы используете его позже в небезопасном контексте HTML, потому что это абсолютно допустимое имя файла:становится дырой XSS :
Из-за этого популярное программное обеспечение CMS Wordpress удаляет их, но они покрывают все соответствующие символы только после некоторых обновлений :
Наконец, их список теперь включает большинство символов, которые являются частью списка зарезервированных символов URI и небезопасных символов URL .
Конечно, вы можете просто закодировать все эти символы в выводе HTML, но большинство разработчиков и я тоже следуем идиоме «Лучше перестраховаться, чем сожалеть» и заранее удалить их.
Итак, наконец, я предлагаю использовать это:
Все остальное, что не вызывает проблем с файловой системой, должно быть частью дополнительной функции:
И на этом этапе вам нужно сгенерировать имя файла, если результат пуст, и вы можете решить, хотите ли вы кодировать символы UTF-8. Но вам это не нужно, поскольку UTF-8 разрешен во всех файловых системах, которые используются в контекстах веб-хостинга.
Единственное, что вам нужно сделать, это использовать
urlencode()
(как вы надеетесь сделать это со всеми своими URL-адресами), чтобы имя файлаსაბეჭდი_მანქანა.jpg
стало этим URL-адресом как ваш<img src>
или<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 делает это, поэтому я могу опубликовать эту ссылку, как это сделал бы пользователь:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Так что это полное законное имя файла и не проблема, как @ SequenceDigitale.com упомянул в своем ответе .
источник
r-u-l-e-s
и я понятия не имею, почему это происходит. Конечно, это не ошибка функции, а просто вопрос - в чем может быть причина такого поведения? Неправильная кодировка?preg_replace
дюймаfilter_filename()
.А как насчет использования rawurlencode ()? http://www.php.net/manual/en/function.rawurlencode.php
Вот функция, которая дезинфицирует даже китайские символы:
Вот объяснение
Хорошо, какое-то имя файла не будет актуальным, но в большинстве случаев оно будет работать.
напр. Оригинальное название: "საბეჭდი-და-ტიპოგრაფიული. Jpg"
Название выхода: «-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 "
Так лучше, чем ошибка 404.
Надеюсь, это было полезно.
Карл.
источник
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
в исходном HTML кода , как вы , надеюсь , делать со всей своей URL.strip_tags()
и после этого удаляете[<>]
. К тому жеstrip_tags()
это вообще не нужно. То же самое и с цитатами. При декодировании с помощью кавычек не остаетсяENT_QUOTES
. Иstr_replace()
не удаляет последовательные пробелы, а затем вы используетеstrtolower()
для многобайтовой строки. А зачем вообще переводить в нижний регистр? И, наконец, вы не поймали ни одного зарезервированного символа, как упомянул @BasilMusa. Подробнее в моем ответе: stackoverflow.com/a/42058764/318765РЕШЕНИЕ 1 - просто и эффективно
$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );
[^a-z0-9]+
гарантирует, что имя файла содержит только буквы и цифры'-'
на, чтобы имя файла оставалось читаемымПример:
РЕШЕНИЕ 2 - для очень длинных URL
Вы хотите кэшировать содержимое URL-адреса и просто должны иметь уникальные имена файлов. Я бы использовал эту функцию:
$file_name = md5( strtolower( $url ) )
это создаст имя файла с фиксированной длиной. Хеш MD5 в большинстве случаев достаточно уникален для такого использования.
Пример:
источник
Что ж, tempnam () сделает это за вас.
http://us2.php.net/manual/en/function.tempnam.php
но это создает совершенно новое имя.
Чтобы очистить существующую строку, просто ограничьте то, что ваши пользователи могут вводить, и сделайте это буквами, цифрами, точкой, дефисом и подчеркиванием, а затем очистите с помощью простого регулярного выражения. Проверьте, какие символы нужно экранировать, иначе вы можете получить ложные срабатывания.
источник
Добавьте / удалите больше допустимых символов в зависимости от того, что разрешено в вашей системе.
В качестве альтернативы вы можете попробовать создать файл, а затем вернуть ошибку, если он плохой.
источник
..
, что может быть или не быть проблемой.PHP предоставляет функцию для преобразования текста в другой формат
filter.filters.sanitize
Как :
источник
безопасно: заменить каждую последовательность НЕ «a-zA-Z0-9_-» на тире; добавьте расширение самостоятельно.
источник
Следующее выражение создает красивую, чистую и удобную строку:
Преобразование сегодняшних финансов: биллинг в сегодняшние финансовые счета
источник
preg_replace
глобального флага неявно. Таким образом, если используется preg_replace, в g нет необходимости. Когда мы хотим контролировать количество замен, у preg_replace естьlimit
параметр для этого. Прочтите документацию preg_replace, чтобы узнать больше.Внеся небольшую поправку в решение Шона Виейры, чтобы учесть отдельные точки, вы можете использовать:
источник
Они могут быть немного тяжелыми, но они достаточно гибкие, чтобы преобразовать любую строку в «безопасный»
en
стиль имени файла или имени папки (или, черт возьми, даже очистить ярлыки и тому подобное, если вы его согнете).1) Создание полного имени файла (с резервным именем в случае, если ввод полностью усечен):
2) Или используя только утилиту фильтра без создания полного имени файла (строгий режим
true
не позволяет использовать [] или () в имени файла):3) А вот эти функции:
Итак, допустим, пользовательский ввод:
.....<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) საბეჭდი-და-ტიპოგრაფიული
И мы хотим преобразовать его во что-то более дружелюбное, чтобы создать tar.gz с длиной имени файла 255 символов. Вот пример использования. Примечание: этот пример включает в себя искаженное расширение tar.gz в качестве доказательства концепции, вы все равно должны фильтровать расширение после того, как строка будет построена по вашему белому списку (ам).
Результатом будет:
_wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz
Вы можете поиграть с ним здесь: https://3v4l.org/iSgi8
Или Gist: https://gist.github.com/dhaupin/b109d3a8464239b7754a
РЕДАКТИРОВАТЬ: обновленный фильтр сценария
вместо пробела, обновленная ссылка 3v4lисточник
Лучшее, что я знаю сегодня, - это статический метод Strings :: webalize из Nette framework.
Кстати, это переводит все диакритические знаки в их основные .. š => s ü => u ß => ss и т. Д.
Для имен файлов необходимо добавить точку "." параметру разрешенных символов.
источник
urlencode()
прежде чем использовать имя файла какsrc
илиhref
. Единственная используемая в настоящее время файловая система, которая имеет проблемы с UTF-8, - это FATx (используется XBOX): en.wikipedia.org/wiki/Comparison_of_file_systems#Limits И я не думаю, что это используется веб-серверамиКажется, все это зависит от вопроса, можно ли создать имя файла, которое можно использовать для взлома сервера (или для нанесения какого-либо другого ущерба). Если нет, то кажется, что простой ответ - попытаться создать файл там, где он, в конечном счете, будет использоваться (поскольку, без сомнения, это будет предпочтительная операционная система). Позвольте операционной системе разобраться с этим. Если он жалуется, перенесите эту жалобу обратно пользователю как ошибку валидации.
Это имеет дополнительное преимущество - надежность переносимости, поскольку все (я почти уверен) операционные системы будут жаловаться, если имя файла неправильно сформировано для этой ОС.
Если это это возможно сделать гнусные вещи с именем файла, возможно , существуют меры , которые могут быть применены перед тестированием файла на резидентной операционной системы - меры , менее сложные , чем полный «санитария» в имени файла.
источник
в одну сторону
источник
/
и..
в указанном пользователем имени файла может быть вредным. Так что избавиться от них нужно примерно так:источник
..name
которую ни из чего не вырвется. Удаление всех символов разделителей пути должно быть достаточным для предотвращения любого обхода каталога. (Удаление..
технически не./.
становится..
. И, наконец, в этом ответе отсутствуют все другие зарезервированные символы файловой системы, такие как NULL. Подробнее в моем ответе: stackoverflow.com/a/42058764/318765Поскольку пользователи могут использовать косую черту для разделения двух слов, было бы лучше заменить дефисом вместо NULL.
источник