Estou procurando uma função php que irá higienizar uma string e torná-la pronta para ser usada para um nome de arquivo. Alguém conhece um útil?
(Eu poderia escrever um, mas estou preocupado em esquecer um personagem!)
Editar: para salvar arquivos em um sistema de arquivos Windows NTFS.
php
string
sanitization
user151841
fonte
fonte
Respostas:
Em vez de se preocupar em ignorar os personagens - que tal usar uma lista branca de personagens que você gostaria de usar? Por exemplo, você poderia permitir que apenas o bom e velho
a-z
,0-9
,_
, e uma única instância de um ponto (.
). Obviamente, isso é mais limitante do que a maioria dos sistemas de arquivos, mas deve mantê-lo seguro.fonte
Fazendo um pequeno ajuste na solução de Tor Valamo para corrigir o problema notado por Dominic Rodger, você poderia usar:
fonte
..
depois. Por exemplo,.?.
acabaria sendo..
. Embora, como você filtra,/
eu não consiga ver como você exploraria isso ainda mais agora, mas isso mostra por que a verificação de..
é ineficaz aqui. Melhor ainda, provavelmente, não substitua, apenas rejeite se não se qualificar.[^a-z0-9_-]
se quiser ser realmente restritivo - ou apenas usar um nome gerado e descartar o nome fornecido e evitar todos esses problemas. :-)É assim que você pode limpar um sistema de arquivos conforme solicitado
Todo o resto é permitido em um sistema de arquivos, então a pergunta está perfeitamente respondida ...
... mas pode ser perigoso permitir, por exemplo, aspas simples
'
em um nome de arquivo se você usá-lo posteriormente em um contexto HTML não seguro porque este nome de arquivo absolutamente legal:torna-se um buraco XSS :
Por causa disso, o popular software CMS Wordpress os remove, mas eles cobrem todos os caracteres relevantes somente após algumas atualizações :
Finalmente sua lista inclui agora a maioria dos personagens que fazem parte da URI rerserved-personagens e URL caracteres inseguros lista.
É claro que você poderia simplesmente codificar todos esses caracteres na saída HTML, mas a maioria dos desenvolvedores e eu também, seguimos a expressão "Melhor prevenir do que remediar" e excluí-los antecipadamente.
Então, finalmente, sugiro usar isso:
Tudo o mais que não cause problemas com o sistema de arquivos deve fazer parte de uma função adicional:
E, neste ponto, você precisa gerar um nome de arquivo se o resultado estiver vazio e você pode decidir se deseja codificar caracteres UTF-8. Mas você não precisa disso, pois o UTF-8 é permitido em todos os sistemas de arquivos usados em contextos de hospedagem na web.
A única coisa que você precisa fazer é usar
urlencode()
(como você espera fazer com todos os seus URLs) para que o nome do arquivoსაბეჭდი_მანქანა.jpg
se torne este URL como seu<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 faz isso, então posso postar este link como um usuário faria:
http://www.maxrev.de/html/img/ საბეჭდი_მანქანა. Jpg
Portanto, este é um nome de arquivo legal completo e não é um problema, como @ SequenceDigitale.com mencionou em sua resposta .
fonte
r-u-l-e-s
e não tenho ideia do porquê isso aconteceu. Claro é que não é culpa da função, mas apenas perguntar - qual seria o motivo de tal comportamento? Codificação errada?preg_replace
infilter_filename()
.Que tal usar rawurlencode ()? http://www.php.net/manual/en/function.rawurlencode.php
Esta é uma função que higieniza até mesmo os caracteres chineses:
Aqui está a explicação
OK, algum nome de arquivo não será vantajoso, mas na maioria dos casos funcionará.
ex. Nome original: "საბეჭდი-და-ტიპოგრაფიული. Jpg"
Nome de saída: "-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 "
É melhor assim do que um erro 404.
Espero que tenha sido útil.
Carl.
fonte
http://www.maxrev.de/html/img/საბეჭდი_მანქანა.jpg
parahttp://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
no código fonte HTML como você faz espero que com todos os seus URLs.strip_tags()
e depois disso[<>]
. Por issostrip_tags()
não é realmente necessário. O mesmo ponto são as aspas. Não há aspas quando você decodifica comENT_QUOTES
. E ostr_replace()
não remove os espaços em branco consecutivos e, em seguida, você usastrtolower()
para string multibyte. E por que você converte para minúsculas? E finalmente você não pegou nenhum personagem reservado como @BasilMusa mencionou. Mais detalhes em minha resposta: stackoverflow.com/a/42058764/318765SOLUÇÃO 1 - simples e eficaz
$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );
[^a-z0-9]+
irá garantir, o nome do arquivo mantém apenas letras e números'-'
mantém o nome do arquivo legívelExemplo:
SOLUÇÃO 2 - para URLs muito longos
Você deseja armazenar em cache o conteúdo da URL e só precisa ter nomes de arquivo exclusivos. Eu usaria esta função:
$file_name = md5( strtolower( $url ) )
isso criará um nome de arquivo com comprimento fixo. O hash MD5 é, na maioria dos casos, exclusivo o suficiente para esse tipo de uso.
Exemplo:
fonte
Bem, tempnam () fará isso por você.
http://us2.php.net/manual/en/function.tempnam.php
mas isso cria um nome totalmente novo.
Para limpar uma string existente, basta restringir o que seus usuários podem inserir e transformá-la em letras, números, ponto, hífen e sublinhado e então limpar com um regex simples. Verifique quais caracteres precisam ser escapados ou você pode obter falsos positivos.
fonte
Adicione / remova mais caracteres válidos dependendo do que é permitido para seu sistema.
Como alternativa, você pode tentar criar o arquivo e retornar um erro se ele estiver ruim.
fonte
..
usar nomes de arquivo como , o que pode ou não ser um problema.PHP fornece uma função para limpar um texto para um formato diferente
filter.filters.sanitize
Como :
fonte
A expressão a seguir cria uma string agradável, limpa e utilizável:
Transformando o financeiro de hoje: faturamento em faturamento financeiro de hoje
fonte
preg_replace
o sinalizador global está implícito. Portanto, não há necessidade de g se preg_replace estiver sendo usado. Quando queremos controlar o número de substituições preg_replace tem umlimit
parâmetro para isso. Leia a documentação preg_replace para mais.Fazendo um pequeno ajuste na solução de Sean Vieira para permitir pontos únicos, você pode usar:
fonte
seguro: substitua toda sequência de NÃO "a-zA-Z0-9_-" por um travessão; adicione uma extensão você mesmo.
fonte
Eles podem ser um pouco pesados, mas são flexíveis o suficiente para limpar qualquer string em um
en
nome de arquivo ou pasta de estilo "seguro" (ou diabos, até mesmo slugs limpos e outras coisas se você dobrar).1) Construindo um nome de arquivo completo (com nome substituto caso a entrada esteja totalmente truncada):
2) Ou usando apenas o utilitário de filtro sem construir um nome de arquivo completo (o modo estrito
true
não permitirá [] ou () no nome do arquivo):3) E aqui estão essas funções:
Então, digamos que alguma entrada do usuário seja:
.....<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) საბეჭდი-და-ტიპოგრაფიული
E queremos convertê-lo para algo mais amigável para fazer um tar.gz com um tamanho de nome de arquivo de 255 caracteres. Aqui está um exemplo de uso. Observação: este exemplo inclui uma extensão tar.gz malformada como uma prova de conceito, você ainda deve filtrar a extensão depois que a string for criada em sua (s) lista (s) branca (s).
A saída seria:
_wei_gbel_file_name_dcor_._._._z_._y_._x_._this_name_is_462_not_that_grrrreat_][09]()1234747)_.tar.gz
Você pode brincar com ele aqui: https://3v4l.org/iSgi8
Ou um Síntese: https://gist.github.com/dhaupin/b109d3a8464239b7754a
EDITAR: filtro de script atualizado para em
vez de espaço, link 3v4l atualizadofonte
O melhor que sei hoje é o método estático Strings :: webalize do framework Nette.
BTW, isso traduz todos os sinais diacríticos para seus básicos .. š => s ü => u ß => ss etc.
Para nomes de arquivos, você deve adicionar o ponto "." para o parâmetro de caracteres permitidos.
fonte
urlencode()
antes de usar o nome do arquivo comosrc
ouhref
. O único sistema de arquivos usado atualmente que tem problemas com UTF-8 é o FATx (usado pelo XBOX): en.wikipedia.org/wiki/Comparison_of_file_systems#Limits E eu não acho que isso seja usado por servidores webParece que tudo depende da questão, é possível criar um nome de arquivo que pode ser usado para invadir um servidor (ou causar algum outro dano). Do contrário, parece que a resposta simples é tentar criar o arquivo onde quer que ele seja, em última instância, usado (já que esse será o sistema operacional de escolha, sem dúvida). Deixe o sistema operacional resolver isso. Se houver reclamação, devolva a reclamação ao usuário como um erro de validação.
Isso tem o benefício adicional de ser portável de maneira confiável, já que todos (tenho certeza) os sistemas operacionais reclamarão se o nome do arquivo não for formado corretamente para aquele SO.
Se isso for possível fazer coisas nefastas com um nome de arquivo, talvez haja medidas que possam ser aplicadas antes de testar o nome do arquivo no sistema operacional residente - medidas menos complicadas do que uma "limpeza" completa do nome do arquivo.
fonte
mão única
fonte
/
e..
no nome de arquivo fornecido pelo usuário pode ser prejudicial. Portanto, você deve se livrar deles por meio de algo como:fonte
..name
que não sairá de nada. A remoção de todos os caracteres separadores de caminho deve ser suficiente para evitar qualquer passagem de diretório. (A remoção de..
é tecnicamente desnecessária.)./.
se torna..
. E, finalmente, esta resposta perde todos os outros caracteres reservados do sistema de arquivos, como NULL. Mais em minha resposta: stackoverflow.com/a/42058764/318765Uma vez que os usuários podem usar a barra para separar duas palavras, seria melhor substituí-la por um hífen em vez de NULL
fonte