Codificador e descodificador de entidades HTML
Faça escape de texto para que seja seguro dentro de HTML, ou descodifique entidades nomeadas e numéricas de volta aos caracteres que representam.
A saída aparecerá aqui
O que esta ferramenta faz
O HTML não tem como distinguir um sinal de menor que você queria como texto de um que abre uma etiqueta. A linguagem resolve isso com entidades: sequências de escape curtas que representam um carácter sem serem lidas como marcação. Esta ferramenta converte nos dois sentidos — texto simples para a sua forma com escape, e HTML com escape de volta para os caracteres que representa.
Ambos os sentidos correm inteiramente no seu navegador. Aqui isso importa mais do que na maioria das ferramentas, porque o texto que se cola num descodificador de entidades costuma ser uma página recolhida por um scraper, o email de um cliente ou uma coluna de base de dados que alguém está a tentar perceber.
Os cinco caracteres que importam
Existem milhares de entidades, mas bastam poucas para tornar o texto seguro. A codificação aqui substitui exatamente cinco caracteres e deixa legível tudo o resto:
- O e comercial passa a & — este primeiro, ou cada substituição seguinte seria relida como uma entidade.
- O sinal de menor passa a < — o carácter capaz de abrir uma etiqueta.
- O sinal de maior passa a > — menos perigoso sozinho, com escape por simetria e para sobreviver a analisadores descuidados.
- As aspas duplas passam a " — necessárias dentro de valores de atributo escritos com aspas duplas.
- O apóstrofo passa a ' — necessário dentro de valores de atributo escritos com aspas simples.
Este último é escrito numericamente de propósito. Existe um nome, ', mas vem do XML e o HTML 4 nunca o definiu, por isso analisadores antigos deixam-no passar como texto literal e o escape falha em silêncio. A forma numérica sempre funcionou em todo o lado, e é por isso que as bibliotecas de escape sérias a emitem.
Nomeadas, decimais e hexadecimais
Qualquer carácter pode ser escrito de três maneiras, e a descodificação aceita todas. O travessão é um bom exemplo:
named — a forma legível, mas só para caracteres que têm nome decimal — o ponto de código na base 10 hex — o mesmo ponto de código na base 16, a notação das tabelas Unicode
Ao descodificar, esta ferramenta reconhece os 255 nomes do conjunto do HTML 4 — as letras latinas, o alfabeto grego, as setas, os símbolos matemáticos e a pontuação tipográfica, que entre todos cobrem praticamente tudo o que aparece em texto real. O HTML 5 define cerca de mais 2200, quase todos símbolos matemáticos pouco frequentes; carregar essa tabela acrescentaria dezenas de kilobytes a cada carregamento de página em troca de nomes que a maioria dos documentos nunca usa. Um nome fora do conjunto é comunicado em vez de descartado, portanto o custo é um aviso, nunca uma resposta errada.
A codificação segue o caminho inverso e mantém-se deliberadamente simples: nomes para os cinco caracteres acima, números decimais para todo o resto. Nada se transforma em … nem em ’ quando o próprio carácter é perfeitamente válido num documento UTF-8.
Fazer escape não é uma regra mas quatro
É tentador tratar o escape de entidades como a resposta à injeção, e dentro do conteúdo de um elemento é mesmo. Mas o HTML são na verdade quatro linguagens encaixadas umas nas outras, cada uma com as suas regras. O escape de entidades está certo nos dois primeiros destes lugares e é inútil nos restantes:
- Conteúdo de elemento — texto entre etiquetas. O escape de entidades é exatamente o indicado.
- Valores de atributo entre aspas. O escape de entidades serve, desde que o atributo esteja mesmo entre aspas; sem elas, um espaço no valor termina o atributo e o escape não lhe traz nada.
- Dentro de um bloco script. Aplicam-se as regras de escape de cadeias de JavaScript, não as entidades — o navegador não descodifica entidades aí, por isso uma aspa com escape chega como os caracteres literais ".
- Atributos de URL como href e src. O escape de entidades não trava um URL javascript:, porque o perigo está no esquema e não em qualquer carácter que uma entidade fosse substituir.
A regra prática: faça escape no ponto onde o texto é inserido num documento, com as regras do contexto exato em que aterra — e não uma só vez, cedo, na esperança de que sirva em todo o lado mais à frente.
Porque às vezes se vê &amp;
Esta é de longe a razão mais comum para recorrer a um descodificador de entidades. O texto sofreu escape e depois sofreu escape outra vez — normalmente uma pelo código da aplicação e outra por um motor de modelos ou framework que já faz escape da sua saída:
original Fish & Chips escaped Fish & Chips escaped x2 Fish &amp; Chips
A segunda linha aparece na página como o original. A terceira aparece como a segunda, ou seja, o visitante vê a entidade em vez do carácter. A descodificação remove exatamente uma camada, por isso uma única passagem diz-lhe em que caso está. Se a saída ainda contiver entidades, havia mais do que uma camada. A correção quase nunca é remover entidades na altura de mostrar: é encontrar e eliminar o passo de escape duplicado, porque a mesma falha está a corromper em silêncio os dados guardados.
O não-ASCII e a opção para isso
Uma página servida em UTF-8 não precisa de entidades para letras acentuadas, hebraico, árabe, chinês ou emoji. Esses caracteres são válidos tal como estão, e deixá-los legíveis mantém o código-fonte legível e o ficheiro mais pequeno. É o predefinido aqui.
A opção existe porque alguns destinos ainda insistem em ASCII puro: modelos de correio antigos, sistemas que estragam bytes acima de 127, ou uma coluna de base de dados cuja codificação ninguém quer mudar. Ativá-la escreve cada carácter desses como referência decimal — é passa a é, א passa a א.
Os emoji merecem uma nota. Um emoji é escrito como uma única referência para todo o seu ponto de código, por exemplo 🙂, nunca como duas metades. Se já usou a ferramenta de escape JSON, isto é o oposto do que acontece lá, onde o formato exige expressamente dividir um emoji em dois escapes \u. O mesmo carácter, duas respostas corretas, porque os dois formatos definem o escape sobre unidades diferentes.
Quando uma referência não pode ser descodificada
Aqui a descodificação nunca falha e nunca apaga nada. Uma referência que não se consegue resolver fica exatamente como foi encontrada e é listada acima da saída com a sua linha e a sua coluna. São comunicadas três coisas:
- Um nome desconhecido, como &nbps; — quase sempre uma gralha de . É o aviso sobre o qual vale a pena agir: significa que falta um espaço no seu conteúdo e ninguém reparou.
- Um número que não é um carácter, como � ou um valor acima do intervalo Unicode. Não há nada para o descodificar, por isso fica como texto.
- Um número entre 128 e 159. Ver abaixo.
Um e comercial isolado não é comunicado de todo. Em HTML, R&D e Q&A são texto vulgar, e tratar cada e comercial perdido como um erro enterraria os avisos importantes sob o ruído da prosa.
O intervalo de 128 a 159 é uma verdadeira esquisitice. Esses números designam caracteres de controlo invisíveis que ninguém alguma vez quer escrever; aparecem porque o documento foi redigido em Windows-1252, onde os mesmos números são aspas curvas, travessões e o símbolo do euro. Os navegadores leem-nos discretamente como Windows-1252 exatamente por isso, e esta ferramenta faz o mesmo para que o resultado corresponda ao que uma página mostraria de facto — mas di-lo nos avisos, porque uma substituição silenciosa que não pediu é pior do que uma barulhenta.
Perguntas frequentes
- Fazer escape destes cinco caracteres basta para travar o XSS?
- No conteúdo de um elemento e em valores de atributo entre aspas, sim: é precisamente para isso que serve. Não basta dentro de um bloco script ou style, num atributo sem aspas, nem num atributo de URL como href, cada um dos quais precisa das suas próprias regras. O escape é uma propriedade do sítio onde o texto aterra, não do texto.
- Porque é que o apóstrofo é codificado como ' e não como '?
- Porque ' é uma entidade XML que o HTML 4 nunca definiu. Os analisadores anteriores ao HTML 5 deixam-na como texto literal, por isso um apóstrofo que julgava protegido não está. A forma numérica funciona em qualquer analisador, e por isso é a opção segura.
- A minha página mostra &amp; em vez de um e comercial. O que aconteceu?
- O texto sofreu escape duas vezes. Descodifique-o aqui: uma passagem transforma &amp; em &, confirmando a camada a mais. Corrija o processo em vez do texto — normalmente o seu código faz escape de uma saída que o motor de modelos já estava a proteger.
- Preciso de codificar hebraico, árabe ou emoji?
- Não numa página moderna servida em UTF-8; são válidos tal como estão. Ative a opção não-ASCII apenas quando algo mais à frente exigir ASCII puro, como um modelo de correio antigo. Cada emoji é então escrito como uma única referência numérica.
- Porque é que a ferramenta avisa sobre “ se o descodificou bem?
- Porque 147 designa um carácter de controlo invisível, não a aspa que vê. Os documentos que o usam foram escritos em Windows-1252, onde 147 é uma aspa curva: os navegadores leem-no assim, e esta ferramenta também. O aviso diz-lhe que houve uma substituição, para que possa corrigir a codificação de origem se estiver ao seu alcance.
- O meu texto é enviado para algum lado?
- Não. A codificação e a descodificação correm inteiramente no seu navegador; nada do que colar sai do seu dispositivo.